ImapFlow

imapflow~ ImapFlow

IMAP client class for accessing IMAP mailboxes

Constructor

new ImapFlow()

IMAP connection options

Properties:
Name Type Attributes Default Description
host String

Hostname of the IMAP server.

port Number

Port number for the IMAP server.

secure Boolean <optional>
false

If true, establishes the connection directly over TLS (commonly on port 993). If false, a plain (unencrypted) connection is used first and, if possible, the connection is upgraded to STARTTLS.

doSTARTTLS Boolean <optional>

Determines whether to upgrade the connection to TLS via STARTTLS: - true: Start unencrypted and upgrade to TLS using STARTTLS before authentication. The connection fails if the server does not support STARTTLS or the upgrade fails. Note that secure=true combined with doSTARTTLS=true is invalid. - false: Never use STARTTLS, even if the server advertises support. This is useful if the server has a broken TLS setup. Combined with secure=false, this results in a fully unencrypted connection. Make sure you warn users about the security risks. - undefined (default): If secure=false (default), attempt to upgrade to TLS via STARTTLS before authentication if the server supports it. If not supported, continue unencrypted. This may expose the connection to a downgrade attack.

servername String <optional>

Server name for SNI or when using an IP address as host.

disableCompression Boolean <optional>
false

If true, the client does not attempt to use the COMPRESS=DEFLATE extension.

auth Object

Authentication options. Authentication occurs automatically during connect.

Properties
Name Type Attributes Description
user String

Username for authentication.

pass String <optional>

Password for regular authentication.

accessToken String <optional>

OAuth2 access token, if using OAuth2 authentication.

loginMethod String <optional>

Optional login method for password-based authentication (e.g., "LOGIN", "AUTH=LOGIN", or "AUTH=PLAIN"). If not set, ImapFlow chooses based on available mechanisms.

clientInfo IdInfoObject <optional>

Client identification info sent to the server (via the ID command).

disableAutoIdle Boolean <optional>
false

If true, do not start IDLE automatically. Useful when only specific operations are needed.

tls Object <optional>

Additional TLS options. For details, see Node.js TLS connect.

Properties
Name Type Attributes Default Description
rejectUnauthorized Boolean <optional>
true

If false, allows self-signed or expired certificates.

minVersion String <optional>
'TLSv1.2'

Minimum accepted TLS version (e.g., 'TLSv1.2').

minDHSize Number <optional>
1024

Minimum size (in bits) of the DH parameter for TLS connections.

logger Object | Boolean <optional>

Custom logger instance with debug(obj), info(obj), warn(obj), and error(obj) methods. If false, logging is disabled. If not provided, ImapFlow logs to console in pino format.

logRaw Boolean <optional>
false

If true, logs all raw data (read and written) in base64 encoding. You can pipe such logs to eerawlog command for readable output.

emitLogs Boolean <optional>
false

If true, emits 'log' events with the same data passed to the logger.

verifyOnly Boolean <optional>
false

If true, disconnects after successful authentication without performing other actions.

proxy String <optional>

Proxy URL. Supports HTTP CONNECT (http://, https://) and SOCKS (socks://, socks4://, socks5://).

qresync Boolean <optional>
false

If true, enables QRESYNC support so that EXPUNGE notifications include uid instead of seq.

maxIdleTime Number <optional>

If set, breaks and restarts IDLE every maxIdleTime milliseconds.

missingIdleCommand String <optional>
"NOOP"

Command to use if the server does not support IDLE.

disableBinary Boolean <optional>
false

If true, ignores the BINARY extension for FETCH and APPEND operations.

disableAutoEnable Boolean <optional>
false

If true, do not automatically enable supported IMAP extensions.

connectionTimeout Number <optional>
90000

Maximum time (in milliseconds) to wait for the connection to establish. Defaults to 90 seconds.

greetingTimeout Number <optional>
16000

Maximum time (in milliseconds) to wait for the server greeting after a connection is established. Defaults to 16 seconds.

socketTimeout Number <optional>
300000

Maximum period of inactivity (in milliseconds) before terminating the connection. Defaults to 5 minutes.

Extends

  • EventEmitter

Members

authenticated :String|Boolean

Currently authenticated user or false if mailbox is not open or true if connection was authenticated by PREAUTH

capabilities :Map.<string, (boolean|number)>

Active IMAP capabilities. Value is either true for togglabe capabilities (eg. UIDPLUS) or a number for capabilities with a value (eg. APPENDLIMIT)

enabled :Set.<string>

Enabled capabilities. Usually CONDSTORE and UTF8=ACCEPT if server supports these.

id :String

Instance ID for logs

idling :Boolean

Is current mailbox idling (true) or not (false)

mailbox :MailboxObject|Boolean

Currently selected mailbox or false if mailbox is not open

secureConnection :Boolean

Is the connection currently encrypted or not

serverInfo :IdInfoObject|null

Server identification info. Available after successful connect(). If server does not provide identification info then this value is null.

Example
await client.connect();
console.log(client.serverInfo.vendor);

usable :Boolean

Is the connection currently usable or not

version

Current module version as a static class property

Properties:
Name Type Description
version String

Module version

Methods

(async) append(path, content, flagsopt, idateopt) → {Promise.<AppendResponseObject>}

Appends a new message to a mailbox

Parameters:
Name Type Attributes Default Description
path String

Mailbox path to upload the message to (unicode string)

content string | Buffer

RFC822 formatted email message

flags Array.<string> <optional>

an array of flags to be set for the uploaded message

idate Date | string <optional>
now

internal date to be set for the message

Example
await client.append('INBOX', rawMessageBuffer, ['\\Seen'], new Date(2000, 1, 1));

close()

Closes TCP connection without notifying the server.

Example
let client = new ImapFlow({...});
await client.connect();
...
client.close();

(async) connect() → {Promise.<void>}

Initiates a connection against IMAP server. Throws if anything goes wrong. This is something you have to call before you can run any IMAP commands

Throws:

Will throw an error if connection or authentication fails

Example
let client = new ImapFlow({...});
await client.connect();

(async) download(range, partopt, optionsopt) → {Promise.<DownloadObject>}

Download either full rfc822 formatted message or a specific bodystructure part as a Stream. Bodystructure parts are decoded so the resulting stream is a binary file. Text content is automatically converted to UTF-8 charset.

Parameters:
Name Type Attributes Description
range SequenceString

UID or sequence number for the message to fetch

part String <optional>

If not set then downloads entire rfc822 formatted message, otherwise downloads specific bodystructure part

options Object <optional>
Properties
Name Type Attributes Default Description
uid Boolean <optional>

If true then uses UID number instead of sequence number for range

maxBytes number <optional>

If set then limits download size to specified bytes

chunkSize number <optional>
65536

How large content parts to ask from the server

Example
let mailbox = await client.mailboxOpen('INBOX');
// download body part nr '1.2' from latest message
let {meta, content} = await client.download('*', '1.2');
content.pipe(fs.createWriteStream(meta.filename));

(async) downloadMany(range, parts, optionsopt) → {Promise.<Object>}

Fetch multiple attachments as Buffer values

Parameters:
Name Type Attributes Description
range SequenceString

UID or sequence number for the message to fetch

parts String

A list of bodystructure parts

options Object <optional>
Properties
Name Type Attributes Description
uid Boolean <optional>

If true then uses UID number instead of sequence number for range

Example
let mailbox = await client.mailboxOpen('INBOX');
// download body parts '2', and '3' from all messages in the selected mailbox
let response = await client.downloadMany('*', ['2', '3']);
process.stdout.write(response[2].content)
process.stdout.write(response[3].content)

(async, generator) fetch(range, query, optionsopt)

Fetch messages from the currently opened mailbox

Parameters:
Name Type Attributes Description
range SequenceString | Array.<Number> | SearchObject

Range of messages to fetch

query FetchQueryObject

Fetch query

options Object <optional>
Properties
Name Type Attributes Default Description
uid Boolean <optional>

If true then uses UID numbers instead of sequence numbers for range

changedSince BigInt <optional>

If set then only messages with a higher modseq value are returned. Ignored if server does not support CONDSTORE extension.

binary Boolean <optional>
false

If true then requests a binary response if the server supports this

Example
let mailbox = await client.mailboxOpen('INBOX');
// fetch UID for all messages in a mailbox
for await (let msg of client.fetch('1:*', {uid: true})){
    console.log(msg.uid);
    // NB! You can not run any IMAP commands in this loop
    // otherwise you will end up in a deadloop
}

(async) fetchAll(range, query, optionsopt) → {Promise.<Array.<FetchMessageObject>>}

Fetch messages from the currently opened mailbox.

This method will fetch all messages before resolving the promise, unlike .fetch(), which is an async generator. Do not use large ranges like 1:*, as this might exhaust all available memory if the mailbox contains a large number of emails.

Parameters:
Name Type Attributes Description
range SequenceString | Array.<Number> | SearchObject

Range of messages to fetch

query FetchQueryObject

Fetch query

options Object <optional>
Properties
Name Type Attributes Default Description
uid Boolean <optional>

If true then uses UID numbers instead of sequence numbers for range

changedSince BigInt <optional>

If set then only messages with a higher modseq value are returned. Ignored if server does not support CONDSTORE extension.

binary Boolean <optional>
false

If true then requests a binary response if the server supports this

Example
let mailbox = await client.mailboxOpen('INBOX');
// fetch UID for all messages in a mailbox
const messages = await client.fetchAll('1:*', {uid: true});
for (let msg of messages){
    console.log(msg.uid);
}

(async) fetchOne(seq, query, optionsopt) → {Promise.<FetchMessageObject>}

Fetch a single message from the currently opened mailbox

Parameters:
Name Type Attributes Description
seq SequenceString

Single UID or sequence number of the message to fetch for

query FetchQueryObject

Fetch query

options Object <optional>
Properties
Name Type Attributes Default Description
uid Boolean <optional>

If true then uses UID number instead of sequence number for seq

binary Boolean <optional>
false

If true then requests a binary response if the server supports this

Example
let mailbox = await client.mailboxOpen('INBOX');
// fetch UID for the last email in the selected mailbox
let lastMsg = await client.fetchOne('*', {uid: true})
console.log(lastMsg.uid);

(async) getMailboxLock(path, optionsopt) → {Promise.<MailboxLockObject>}

Opens a mailbox if not already open and returns a lock. Next call to getMailboxLock() is queued until previous lock is released. This is suggested over mailboxOpen() as getMailboxLock() gives you a weak transaction while mailboxOpen() has no guarantees whatsoever that another mailbox is opened while you try to call multiple fetch or store commands.

Parameters:
Name Type Attributes Description
path string | array

Path for the mailbox to open

options Object <optional>

optional options

Properties
Name Type Attributes Default Description
readOnly Boolean <optional>
false

If true then opens mailbox in read-only mode. You can still try to perform write operations but these would probably fail.

Throws:

Will throw an error if mailbox does not exist or can not be opened

Example
let lock = await client.getMailboxLock('INBOX');
try {
  // do something in the mailbox
} finally {
  // use finally{} to make sure lock is released even if exception occurs
  lock.release();
}

(async) getQuota(pathopt) → {Promise.<(QuotaResponse|Boolean)>}

Returns current quota

Parameters:
Name Type Attributes Description
path String <optional>

Optional mailbox path if you want to check quota for specific folder

Example
let quota = await client.getQuota();
console.log(quota.storage.used, quota.storage.available)

(async) idle() → {Promise.<Boolean>}

Starts listening for new or deleted messages from the currently opened mailbox. Only required if ImapFlow#disableAutoIdle is set to true otherwise IDLE is started by default on connection inactivity. NB! If idle() is called manually then it does not return until IDLE is finished which means you would have to call some other command out of scope.

Example
let mailbox = await client.mailboxOpen('INBOX');

await client.idle();

(async) list(optionsopt) → {Promise.<Array.<ListResponse>>}

Lists available mailboxes as an Array

Parameters:
Name Type Attributes Description
options ListOptions <optional>

defines additional listing options

Example
let list = await client.list();
list.forEach(mailbox=>console.log(mailbox.path));

(async) listTree(optionsopt) → {Promise.<ListTreeResponse>}

Lists available mailboxes as a tree structured object

Parameters:
Name Type Attributes Description
options ListOptions <optional>

defines additional listing options

Example
let tree = await client.listTree();
tree.folders.forEach(mailbox=>console.log(mailbox.path));

(async) logout() → {Promise.<void>}

Graceful connection close by sending logout command to server. TCP connection is closed once command is finished.

Example
let client = new ImapFlow({...});
await client.connect();
...
await client.logout();

(async) mailboxClose() → {Promise.<Boolean>}

Closes a previously opened mailbox

Example
let mailbox = await client.mailboxOpen('INBOX');
await client.mailboxClose();

(async) mailboxCreate(path) → {Promise.<MailboxCreateResponse>}

Creates a new mailbox folder and sets up subscription for the created mailbox. Throws on error.

Parameters:
Name Type Description
path string | array

Full mailbox path. Unicode is allowed. If value is an array then it is joined using current delimiter symbols. Namespace prefix is added automatically if required.

Throws:

Will throw an error if mailbox can not be created

Example
let info = await client.mailboxCreate(['parent', 'child']);
console.log(info.path);
// "INBOX.parent.child" // assumes "INBOX." as namespace prefix and "." as delimiter

(async) mailboxDelete(path) → {Promise.<MailboxDeleteResponse>}

Deletes a mailbox. Throws on error.

Parameters:
Name Type Description
path string | array

Path for the mailbox to delete. Unicode is allowed. If value is an array then it is joined using current delimiter symbols. Namespace prefix is added automatically if required.

Throws:

Will throw an error if mailbox does not exist or can not be deleted

Example
let info = await client.mailboxDelete('Important stuff ❗️');
console.log(info.path);
// "INBOX.Important stuff ❗️" // assumes "INBOX." as namespace prefix

(async) mailboxOpen(path, optionsopt) → {Promise.<MailboxObject>}

Opens a mailbox to access messages. You can perform message operations only against an opened mailbox. Using getMailboxLock() instead of mailboxOpen() is preferred. Both do the same thing but next getMailboxLock() call is not executed until previous one is released.

Parameters:
Name Type Attributes Description
path string | array

Path for the mailbox to open

options Object <optional>

optional options

Properties
Name Type Attributes Default Description
readOnly Boolean <optional>
false

If true then opens mailbox in read-only mode. You can still try to perform write operations but these would probably fail.

Throws:

Will throw an error if mailbox does not exist or can not be opened

Example
let mailbox = await client.mailboxOpen('Important stuff ❗️');
console.log(mailbox.exists);
// 125

(async) mailboxRename(path, newPath) → {Promise.<MailboxRenameResponse>}

Renames a mailbox. Throws on error.

Parameters:
Name Type Description
path string | array

Path for the mailbox to rename. Unicode is allowed. If value is an array then it is joined using current delimiter symbols. Namespace prefix is added automatically if required.

newPath string | array

New path for the mailbox

Throws:

Will throw an error if mailbox does not exist or can not be renamed

Example
let info = await client.mailboxRename('parent.child', 'Important stuff ❗️');
console.log(info.newPath);
// "INBOX.Important stuff ❗️" // assumes "INBOX." as namespace prefix

(async) mailboxSubscribe(path) → {Promise.<Boolean>}

Subscribes to a mailbox

Parameters:
Name Type Description
path string | array

Path for the mailbox to subscribe to. Unicode is allowed. If value is an array then it is joined using current delimiter symbols. Namespace prefix is added automatically if required.

Example
await client.mailboxSubscribe('Important stuff ❗️');

(async) mailboxUnsubscribe(path) → {Promise.<Boolean>}

Unsubscribes from a mailbox

Parameters:
Name Type Description
path string | array

Path for the mailbox to unsubscribe from. Unicode is allowed. If value is an array then it is joined using current delimiter symbols. Namespace prefix is added automatically if required.

Example
await client.mailboxUnsubscribe('Important stuff ❗️');

(async) messageCopy(range, destination, optionsopt) → {Promise.<CopyResponseObject>}

Copies messages from current mailbox to destination mailbox

Parameters:
Name Type Attributes Description
range SequenceString | Array.<Number> | SearchObject

Range of messages to copy

destination String

Mailbox path to copy the messages to

options Object <optional>
Properties
Name Type Attributes Description
uid Boolean <optional>

If true then uses UID SequenceString instead of sequence numbers

Example
await client.mailboxOpen('INBOX');
// copy all messages to a mailbox called "Backup" (must exist)
let result = await client.messageCopy('1:*', 'Backup');
console.log('Copied %s messages', result.uidMap.size);

(async) messageDelete(range, optionsopt) → {Promise.<Boolean>}

Delete messages from the currently opened mailbox. Method does not indicate info about deleted messages, instead you should be using ImapFlow#expunge event for this

Parameters:
Name Type Attributes Description
range SequenceString | Array.<Number> | SearchObject

Range to filter the messages

options Object <optional>
Properties
Name Type Attributes Description
uid Boolean <optional>

If true then uses UID SequenceString instead of sequence numbers

Example
let mailbox = await client.mailboxOpen('INBOX');
// delete all seen messages
await client.messageDelete({seen: true});

(async) messageFlagsAdd(range, Array, optionsopt) → {Promise.<Boolean>}

Adds flags for a message or message range

Parameters:
Name Type Attributes Description
range SequenceString | Array.<Number> | SearchObject

Range to filter the messages

Array Array.<string>

of flags to set. Only flags that are permitted to set are used, other flags are ignored

options Object <optional>
Properties
Name Type Attributes Default Description
uid Boolean <optional>

If true then uses UID SequenceString instead of sequence numbers

unchangedSince BigInt <optional>

If set then only messages with a lower or equal modseq value are updated. Ignored if server does not support CONDSTORE extension.

useLabels Boolean <optional>
false

If true then update Gmail labels instead of message flags

Example
let mailbox = await client.mailboxOpen('INBOX');
// mark all unseen messages as seen (and keep other flags as is)
await client.messageFlagsAdd({seen: false}, ['\Seen]);

(async) messageFlagsRemove(range, Array, optionsopt) → {Promise.<Boolean>}

Remove specific flags from a message or message range

Parameters:
Name Type Attributes Description
range SequenceString | Array.<Number> | SearchObject

Range to filter the messages

Array Array.<string>

of flags to remove. Only flags that are permitted to set are used, other flags are ignored

options Object <optional>
Properties
Name Type Attributes Default Description
uid Boolean <optional>

If true then uses UID SequenceString instead of sequence numbers

unchangedSince BigInt <optional>

If set then only messages with a lower or equal modseq value are updated. Ignored if server does not support CONDSTORE extension.

useLabels Boolean <optional>
false

If true then update Gmail labels instead of message flags

Example
let mailbox = await client.mailboxOpen('INBOX');
// mark all seen messages as unseen by removing \\Seen flag
await client.messageFlagsRemove({seen: true}, ['\Seen]);

(async) messageFlagsSet(range, Array, optionsopt) → {Promise.<Boolean>}

Sets flags for a message or message range

Parameters:
Name Type Attributes Description
range SequenceString | Array.<Number> | SearchObject

Range to filter the messages

Array Array.<string>

of flags to set. Only flags that are permitted to set are used, other flags are ignored

options Object <optional>
Properties
Name Type Attributes Default Description
uid Boolean <optional>

If true then uses UID SequenceString instead of sequence numbers

unchangedSince BigInt <optional>

If set then only messages with a lower or equal modseq value are updated. Ignored if server does not support CONDSTORE extension.

useLabels Boolean <optional>
false

If true then update Gmail labels instead of message flags

Example
let mailbox = await client.mailboxOpen('INBOX');
// mark all unseen messages as seen (and remove other flags)
await client.messageFlagsSet({seen: false}, ['\Seen]);

(async) messageMove(range, destination, optionsopt) → {Promise.<CopyResponseObject>}

Moves messages from current mailbox to destination mailbox

Parameters:
Name Type Attributes Description
range SequenceString | Array.<Number> | SearchObject

Range of messages to move

destination String

Mailbox path to move the messages to

options Object <optional>
Properties
Name Type Attributes Description
uid Boolean <optional>

If true then uses UID SequenceString instead of sequence numbers

Example
await client.mailboxOpen('INBOX');
// move all messages to a mailbox called "Trash" (must exist)
let result = await client.messageMove('1:*', 'Trash');
console.log('Moved %s messages', result.uidMap.size);

(async) noop() → {Promise.<void>}

Performs a no-op call against server

Search messages from the currently opened mailbox

Parameters:
Name Type Attributes Description
query SearchObject

Query to filter the messages

options Object <optional>
Properties
Name Type Attributes Description
uid Boolean <optional>

If true then returns UID numbers instead of sequence numbers

Example
let mailbox = await client.mailboxOpen('INBOX');
// find all unseen messages
let list = await client.search({seen: false});
// use OR modifier (array of 2 or more search queries)
let list = await client.search({
  seen: false,
  or: [
    {flagged: true},
    {from: 'andris'},
    {subject: 'test'}
  ]});

(async) setFlagColor(range, The, optionsopt) → {Promise.<Boolean>}

Sets a colored flag for an email. Only supported by mail clients like Apple Mail

Parameters:
Name Type Attributes Description
range SequenceString | Array.<Number> | SearchObject

Range to filter the messages

The string

color to set. One of 'red', 'orange', 'yellow', 'green', 'blue', 'purple', and 'grey'

options Object <optional>
Properties
Name Type Attributes Description
uid Boolean <optional>

If true then uses UID SequenceString instead of sequence numbers

unchangedSince BigInt <optional>

If set then only messages with a lower or equal modseq value are updated. Ignored if server does not support CONDSTORE extension.

Example
let mailbox = await client.mailboxOpen('INBOX');
// add a purple flag for all emails
await client.setFlagColor('1:*', 'Purple');

(async) status(path, query) → {Promise.<StatusObject>}

Requests the status of the indicated mailbox. Only requested status values will be returned.

Parameters:
Name Type Description
path String

mailbox path to check for (unicode string)

query Object

defines requested status items

Properties
Name Type Description
messages Boolean

if true request count of messages

recent Boolean

if true request count of messages with \Recent tag

uidNext Boolean

if true request predicted next UID

uidValidity Boolean

if true request mailbox UIDVALIDITY value

unseen Boolean

if true request count of unseen messages

highestModseq Boolean

if true request last known modseq value

Example
let status = await client.status('INBOX', {unseen: true});
console.log(status.unseen);
// 123

(async) upgradeToSTARTTLS() → {boolean}

Tries to upgrade the connection to TLS using STARTTLS.

Throws:

if STARTTLS is required, but not possible.

Events

close

Connection close event. NB! ImapFlow does not handle reconnects automatically. So whenever a 'close' event occurs you must create a new connection yourself.

error :Error

Error event. In most cases getting an error event also means that connection is closed and pending operations should return with a failure.

Example
client.on('error', err=>{
    console.log(`Error occurred: ${err.message}`);
});

exists :Object

Message count in currently opened mailbox changed

Properties:
Name Type Description
path String

mailbox path this event applies to

count Number

updated count of messages

prevCount Number

message count before this update

Example
client.on('exists', data=>{
    console.log(`Message count in "${data.path}" is ${data.count}`);
});

expunge :Object

Deleted message sequence number in currently opened mailbox. One event is fired for every deleted email.

Properties:
Name Type Description
path String

mailbox path this event applies to

seq Number

sequence number of deleted message

Example
client.on('expunge', data=>{
    console.log(`Message #${data.seq} was deleted from "${data.path}"`);
});

flags :Object

Flags were updated for a message. Not all servers fire this event.

Properties:
Name Type Attributes Description
path String

mailbox path this event applies to

seq Number

sequence number of updated message

uid Number <optional>

UID number of updated message (if server provided this value)

modseq BigInt <optional>

Updated modseq number for the mailbox (if server provided this value)

flags Set.<string>

A set of all flags for the updated message

Example
client.on('flags', data=>{
    console.log(`Flag set for #${data.seq} is now "${Array.from(data.flags).join(', ')}"`);
});

log :Object

Log event if emitLogs=true

Example
client.on('log', entry => {
    console.log(`${log.cid} ${log.msg}`);
});

mailboxClose :MailboxObject

Mailbox was closed

Example
client.on('mailboxClose', mailbox => {
    console.log(`Mailbox ${mailbox.path} was closed`);
});

mailboxOpen :MailboxObject

Mailbox was opened

Example
client.on('mailboxOpen', mailbox => {
    console.log(`Mailbox ${mailbox.path} was opened`);
});