ImapFlow

imapflow~ ImapFlow

IMAP client class for accessing IMAP mailboxes

Constructor

new ImapFlow(options)

Parameters:
Name Type Description
options Object

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

Should the connection be established over TLS. If false then connection is upgraded to TLS using STARTTLS extension before authentication

servername String <optional>

Servername for SNI (or when host is set to an IP address)

disableCompression Boolean <optional>
false

if true then client does not try to use COMPRESS=DEFLATE extension

auth Object

Authentication options. Authentication is requested automatically during connect()

Properties
Name Type Description
user String

Usename

pass String

Password

clientInfo IdInfoObject <optional>

Client identification info

disableAutoIdle Boolean <optional>
false

if true then IDLE is not started automatically. Useful if you only need to perform specific tasks over the connection

tls Object

Additional TLS options (see Node.js TLS connect for all available options)

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

if false then client accepts self-signed and expired certificates from the server

minVersion String <optional>
TLSv1.2

latest Node.js defaults to 'TLSv1.2', for older mail servers you might need to use something else, eg 'TLSv1'

minDHSize Number <optional>
1024

Minimum size of the DH parameter in bits to accept a TLS connection

logger Object <optional>

Custom logger instance with debug(obj), info(obj), warn(obj) and error(obj) methods. If not provided then ImapFlow logs to console using pino format

verifyOnly Boolean <optional>
false

If true then logs out automatically after successful authentication

Extends

  • EventEmitter

Members

authenticated :String|Boolean

Currently authenticated user or false if mailbox is not open

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

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

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 formated 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 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

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

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

Fetch messages from 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 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.

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);
}

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

Fetch a single message from 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 Description
uid Boolean <optional>

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

Example
let mailbox = await client.mailboxOpen('INBOX');
// fetch UID for all messages in a 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() → {Promise.<Array.<ListResponse>>}

Lists available mailboxes as an Array

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

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

Lists available mailboxes as a tree structured object

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 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 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');
// 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 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');
// 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 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');
// 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 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) 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

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

Events

close

Connection close event

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(', ')}"`);
});

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`);
});