### ImapFlow Configuration Examples Source: https://github.com/postalsys/imapflow/blob/master/_autodocs/MANIFEST.md This section provides practical examples for configuring ImapFlow, covering various scenarios such as Gmail with OAuth2, Outlook with OAuth2, self-hosted servers with self-signed certificates, corporate proxy setups, high-volume synchronization, and admin impersonation. ```javascript // Example: Gmail with OAuth2 configuration const client = new ImapFlow({ host: 'imap.gmail.com', port: 993, secure: true, auth: { user: 'user@gmail.com', accessToken: 'YOUR_ACCESS_TOKEN' }, logger: console }); await client.connect(); ``` ```javascript // Example: Outlook with OAuth2 configuration const client = new ImapFlow({ host: 'outlook.office365.com', port: 993, secure: true, auth: { user: 'user@outlook.com', accessToken: 'YOUR_ACCESS_TOKEN' } }); await client.connect(); ``` ```javascript // Example: Self-hosted with self-signed certificate const client = new ImapFlow({ host: 'mail.example.com', port: 993, secure: true, ignoreTLS: true, // Use with caution auth: { user: 'user@example.com', pass: 'password' } }); await client.connect(); ``` ```javascript // Example: Corporate proxy setup (SOCKS) const client = new ImapFlow({ host: 'imap.example.com', port: 993, secure: true, proxy: { type: 'socks', host: 'proxy.example.com', port: 1080, username: 'proxy_user', password: 'proxy_password' }, auth: { user: 'user@example.com', pass: 'password' } }); await client.connect(); ``` ```javascript // Example: High-volume sync configuration const client = new ImapFlow({ host: 'imap.example.com', port: 993, secure: true, auth: { user: 'user@example.com', pass: 'password' }, // Enable compression for potentially faster transfers extensions: { enabled: ['COMPRESS'] }, // Adjust timeouts for long-running operations timeout: { connection: 60000, greeting: 30000, socket: 120000 } }); await client.connect(); ``` ```javascript // Example: Admin impersonation (Zimbra) const client = new ImapFlow({ host: 'mail.example.com', port: 993, secure: true, auth: { user: 'admin@example.com', pass: 'admin_password', authzid: 'user@example.com' // Impersonate this user } }); await client.connect(); ``` -------------------------------- ### IMAP Sequence String Examples Source: https://github.com/postalsys/imapflow/blob/master/_autodocs/README.md Illustrates various formats for specifying message ranges using IMAP sequence strings. ```javascript '1' // Message 1 '1:10' // Messages 1 through 10 '1:*' // Message 1 through last message '*' // Last message (with uid: true, last UID) '1,5,10' // Messages 1, 5, and 10 '1:10,20:*' // Messages 1-10 and 20 to last ``` -------------------------------- ### Basic Authentication with Password Source: https://github.com/postalsys/imapflow/blob/master/_autodocs/configuration.md Example of setting up basic authentication using only the password. This is typically used when the username is implicitly handled or not required by the server. ```javascript const client = new ImapFlow({ auth: { user: 'user@example.com', pass: 'mypassword' } }); ``` -------------------------------- ### Configure Corporate Proxy Setup Source: https://github.com/postalsys/imapflow/blob/master/_autodocs/configuration.md Connect through a corporate proxy by specifying the proxy URL. This is useful in environments with network restrictions. ```javascript const client = new ImapFlow({ host: 'imap.gmail.com', port: 993, secure: true, proxy: 'http://corporate-proxy.company.com:3128', auth: { user: 'user@gmail.com', pass: 'password' } }); ``` -------------------------------- ### Install ImapFlow via npm Source: https://github.com/postalsys/imapflow/blob/master/README.md Use this command to install the ImapFlow package in your Node.js project. ```bash npm install imapflow ``` -------------------------------- ### ImapFlow Fetch and Download Examples Source: https://github.com/postalsys/imapflow/blob/master/_autodocs/MANIFEST.md This section details how to fetch message data and download content using ImapFlow. It covers various fetch methods, options like `changedSince` and `binary`, streaming downloads, and common patterns for efficient processing and batch downloading. ```javascript // Example: Basic fetch using async iterator const messages = client.fetch('1:*', ['UID', 'FLAGS', 'INTERNALDATE', 'RFC822.SIZE', 'BODY.PEEK[HEADER]']); for await (const message of messages) { console.log(`UID: ${message.uid}, Subject: ${message.header.get('subject')}`); } ``` ```javascript // Example: Fetching with changedSince and binary option const since = new Date('2023-01-01T00:00:00Z'); const messages = client.fetch('1:*', ['UID', 'BODY'], { changedSince: since, binary: true // Enable binary transfer for parts }); for await (const message of messages) { // Process message content, potentially binary parts } ``` ```javascript // Example: Fetching all messages into an array (use with caution for large mailboxes) const allMessages = await client.fetchAll(['UID', 'BODY.PEEK[HEADER.FIELDS (SUBJECT FROM)]']); console.log(`Fetched ${allMessages.length} messages`); ``` ```javascript // Example: Fetching a single message by UID const message = await client.fetchOne(123, ['UID', 'BODY.PEEK[TEXT]']); if (message) { console.log('Message body:', message.text); } ``` ```javascript // Example: Full message download using streaming const downloadStream = client.download(123, '1:*'); // Download entire message let messageContent = ''; for await (const chunk of downloadStream) { messageContent += chunk; } console.log('Downloaded message size:', messageContent.length); ``` ```javascript // Example: Downloading a specific part of a message const partStream = client.download(123, '1.2'); // Download part 1.2 let partContent = ''; for await (const chunk of partStream) { partContent += chunk; } console.log('Downloaded part content:', partContent); ``` ```javascript // Example: Downloading multiple parts into a buffer const parts = await client.downloadMany(123, ['1.1', '1.2'], { maxBytes: 1024 * 1024 }); // Download parts 1.1 and 1.2, max 1MB console.log(`Downloaded ${parts.length} parts`); // parts[0] would contain content for '1.1', parts[1] for '1.2' ``` ```javascript // Example: Extract all attachments from a message const message = await client.fetchOne(123, ['BODYSTRUCTURE']); const attachments = []; function findAttachments(structure) { if (structure.type === 'multipart') { for (const part of structure.childNodes) { findAttachments(part); } } else if (structure.type === 'application' || structure.type === 'text' || structure.type === 'message') { if (structure.disposition === 'attachment') { attachments.push({ filename: structure.dispositionParams.filename, partId: structure.partId, size: structure.size }); } } } findAttachments(message.bodyStructure); for (const attachment of attachments) { console.log(`Downloading attachment: ${attachment.filename} (Part ID: ${attachment.partId})`); const attachmentStream = client.download(123, attachment.partId); // Process the stream, e.g., save to file } ``` -------------------------------- ### ImapFlow Client API Overview Source: https://github.com/postalsys/imapflow/blob/master/_autodocs/MANIFEST.md This file details the ImapFlow constructor, connection lifecycle, mailbox and message operations, IDLE mode control, and events. It includes complete method signatures and code examples for each method. ```javascript // Example: Connecting to an IMAP server import ImapFlow from 'imapflow'; const client = new ImapFlow({ host: 'imap.example.com', port: 993, secure: true, auth: { user: 'user@example.com', pass: 'password' } }); await client.connect(); console.log('Connected to IMAP server'); ``` -------------------------------- ### Fetch Partial Message Source (start and maxLength) Source: https://github.com/postalsys/imapflow/blob/master/_autodocs/fetch-and-download.md Fetches a portion of a message's source, starting from byte 500 and up to 1000 bytes. The source is returned as a Buffer. ```javascript // Partial (from byte 500, up to 1000 bytes) const msg = await client.fetchOne('1', { source: { start: 500, maxLength: 1000 } }); ``` -------------------------------- ### Fetch All Messages (Filtered Results) Source: https://github.com/postalsys/imapflow/blob/master/_autodocs/fetch-and-download.md Fetches messages and filters them based on size, then sorts the filtered results. This example demonstrates how to find large messages. ```javascript const messages = await client.fetchAll('1:*', { uid: true, size: true, envelope: true }); // Filter large messages const largeMessages = messages .filter(msg => msg.size > 5 * 1024 * 1024) .sort((a, b) => b.size - a.size); console.log(`Found ${largeMessages.length} large messages`); ``` -------------------------------- ### Count, Min, Max Search Results Source: https://github.com/postalsys/imapflow/blob/master/_autodocs/search-queries.md Use returnOptions to get the total count, first UID, and last UID of messages matching a search query. This is useful for understanding the scope of results without fetching all UIDs. ```javascript const result = await client.search( { since: new Date('2024-01-01') }, { uid: true, returnOptions: ['COUNT', 'MIN', 'MAX'] } ); console.log(`Total: ${result.count}`); console.log(`First UID: ${result.min}`); console.log(`Last UID: ${result.max}`); ``` -------------------------------- ### Handle Standard Connection Errors Source: https://github.com/postalsys/imapflow/blob/master/_autodocs/errors.md Catch generic connection errors by inspecting the error code. This example shows how to differentiate between common network issues like connection refused, host not found, and timeouts. ```javascript try { await client.connect(); } catch (err) { if (err.code === 'ECONNREFUSED') { console.error('Server refused connection'); } else if (err.code === 'ENOTFOUND') { console.error('Server host not found'); } else if (err.code === 'ETIMEDOUT') { console.error('Connection timeout'); } else { console.error('Connection error:', err.message); } } ``` -------------------------------- ### Disable Automatic IDLE Start Source: https://github.com/postalsys/imapflow/blob/master/_autodocs/configuration.md Do not automatically start the IDLE command after successful authentication. Manual IDLE control is required. Defaults to false. ```javascript const client = new ImapFlow({ host: 'imap.example.com', port: 993, secure: true, disableAutoIdle: true // Manual IDLE control only }); ``` -------------------------------- ### All Search Results as Sequence Set Source: https://github.com/postalsys/imapflow/blob/master/_autodocs/search-queries.md Retrieve all matching UIDs as a compact sequence set string using the 'ALL' return option. This is useful for getting a list of all relevant message identifiers. ```javascript const result = await client.search( { unseen: true }, { uid: true, returnOptions: ['ALL'] } ); // Compact sequence set like "1,5:10,20" console.log('Unseen UIDs:', result.all); ``` -------------------------------- ### idle() Source: https://github.com/postalsys/imapflow/blob/master/_autodocs/imapflow-client-api.md Starts listening for new or deleted messages in the currently opened mailbox using the IDLE extension. This allows for real-time notifications of changes. ```APIDOC ## idle() ### Description Starts listening for new or deleted messages from the currently opened mailbox via the IDLE extension. ### Method `idle(): Promise` ### Returns `Promise` – `true` if IDLE started successfully, `false` if not supported ### Throws - `Error` if no mailbox is currently open ### Example ```javascript await client.mailboxOpen('INBOX'); client.on('exists', event => { console.log(`New messages: ${event.count - event.prevCount}`); }); // Start idle listening const idle = await client.idle(); if (!idle) { console.log('Server does not support IDLE'); // Falls back to periodic NOOP/SELECT } ``` ``` -------------------------------- ### ImapFlow Search Query Examples Source: https://github.com/postalsys/imapflow/blob/master/_autodocs/MANIFEST.md This section covers various search query patterns, including boolean searches, text-based searches, date and size ranges, flag-specific searches, and advanced logical operators. It also details support for Modseq, Object ID, Gmail extensions, and extended search results. ```javascript // Example: Sync since last modseq const searchCriteria = { modseq: 12345 }; const messages = await client.search(searchCriteria); console.log(`Found ${messages.length} new messages`); ``` ```javascript // Example: Archive old messages (older than 30 days) const thirtyDaysAgo = new Date(); thirtyDaysAgo.setDate(thirtyDaysAgo.getDate() - 30); const searchCriteria = { before: thirtyDaysAgo, // Optionally add flags to ensure they are not already archived // notFlags: ['\Archived'] }; const messagesToArchive = await client.search(searchCriteria); console.log(`Found ${messagesToArchive.length} messages to archive`); // await client.store(messagesToArchive, '+FLAGS', '\Archived'); ``` ```javascript // Example: Find large attachments (e.g., > 1MB) const searchCriteria = { larger: 1024 * 1024 // 1MB in bytes }; const largeMessages = await client.search(searchCriteria); console.log(`Found ${largeMessages.length} messages larger than 1MB`); ``` ```javascript // Example: Unread priority inbox messages const searchCriteria = { flags: ['\Unread'], // Assuming a custom flag like \Priority or a specific header // customFlags: ['\Priority'] // Or search within a specific mailbox like 'INBOX' // mailbox: 'INBOX' }; const priorityInboxMessages = await client.search(searchCriteria); console.log(`Found ${priorityInboxMessages.length} unread priority messages`); ``` ```javascript // Example: Newsletter cleanup (find messages from specific senders) const searchCriteria = { from: ['newsletter@example.com', 'updates@example.org'] }; const newsletters = await client.search(searchCriteria); console.log(`Found ${newsletters.length} newsletters`); // await client.delete(newsletters); ``` ```javascript // Example: Extended search results with COUNT const searchCriteria = { count: true, // Request message count // Add other search criteria as needed // subject: 'Important Update' }; const searchResult = await client.search(searchCriteria, { count: true }); console.log(`Found ${searchResult.count} matching messages`); ``` ```javascript // Example: Paged results using PARTIAL (RFC 9394) // Note: ImapFlow's search method directly returns messages. // For true pagination, you'd typically fetch UIDs and then fetch messages in batches. // This example demonstrates fetching a subset of UIDs. const uidSet = await client.search({ seq: '1:*' }); // Get all UIDs const pageSize = 100; for (let i = 0; i < uidSet.length; i += pageSize) { const pageUids = uidSet.slice(i, i + pageSize); console.log(`Processing page ${Math.floor(i / pageSize) + 1} with UIDs: ${pageUids.join(',')}`); // Fetch messages for this page // const messages = await client.fetch(pageUids, ['UID', 'BODY.PEEK[HEADER.FIELDS (SUBJECT FROM DATE)]']); } ``` -------------------------------- ### Handle IMAP Command Failures Source: https://github.com/postalsys/imapflow/blob/master/_autodocs/errors.md Handle errors that occur during IMAP command execution by checking the `serverResponseCode`. This example demonstrates how to identify specific command failures like a mailbox already existing or not existing. ```javascript try { const result = await client.mailboxCreate('MyFolder'); } catch (err) { if (err.serverResponseCode === 'ALREADYEXISTS') { console.error('Mailbox already exists'); } else if (err.serverResponseCode === 'NONEXISTENT') { console.error('Parent mailbox does not exist'); } else { console.error('Create failed:', err.message); } } ``` -------------------------------- ### Start Idle Mode for New Messages Source: https://github.com/postalsys/imapflow/blob/master/_autodocs/imapflow-client-api.md Initiate IDLE mode to receive real-time notifications for new or deleted messages. This method requires a mailbox to be open and falls back to periodic checks if IDLE is not supported by the server. ```javascript await client.mailboxOpen('INBOX'); client.on('exists', event => { console.log(`New messages: ${event.count - event.prevCount}`); }); // Start idle listening const idle = await client.idle(); if (!idle) { console.log('Server does not support IDLE'); // Falls back to periodic NOOP/SELECT } ``` -------------------------------- ### Run Development Commands Source: https://github.com/postalsys/imapflow/blob/master/CLAUDE.md Execute various development tasks such as testing, linting, formatting, and dependency updates using npm scripts. ```bash npm test # Run full suite via Grunt (ESLint + nodeunit tests) ``` ```bash npm run coverage # Run tests under c8 coverage (text + html reports) ``` ```bash npm run lint # Lint with ESLint ``` ```bash npm run format # Format with Prettier (js, json, md, yml, yaml) ``` ```bash npm run update # Refresh deps: remove node_modules + lockfile, ncu -u, npm install ``` -------------------------------- ### Get ImapFlow Version Source: https://github.com/postalsys/imapflow/blob/master/_autodocs/imapflow-client-api.md Access the current module version of ImapFlow. ```javascript console.log('ImapFlow version:', ImapFlow.version); ``` -------------------------------- ### Async/Await vs .then() for Operations Source: https://github.com/postalsys/imapflow/blob/master/_autodocs/README.md Demonstrates how to perform IMAP operations using both async/await syntax and traditional Promise .then() chaining. ```javascript // async/await await client.connect(); const messages = await client.fetchAll('1:100', { envelope: true }); // .then() client.connect().then(() => { return client.fetchAll('1:100', { envelope: true }); }).then(messages => { console.log(messages); }); ``` -------------------------------- ### connect() Source: https://github.com/postalsys/imapflow/blob/master/_autodocs/imapflow-client-api.md Initiates a connection to the IMAP server, handling TLS negotiation, authentication, and capability detection. ```APIDOC ## connect() ### `connect(): Promise` Initiates a connection against IMAP server. Performs TLS negotiation, authentication, capability detection, and optional auto-IDLE. **Throws:** - `AuthenticationFailure` if authentication fails - `Error` if connection cannot be established **Example:** ```javascript try { await client.connect(); console.log('Connected and authenticated'); } catch (err) { if (err.authenticationFailed) { console.error('Login failed:', err.message); } else { console.error('Connection error:', err.message); } } ``` ``` -------------------------------- ### Create ImapFlow Client Instance Source: https://github.com/postalsys/imapflow/blob/master/_autodocs/imapflow-client-api.md Instantiate the ImapFlow client with connection and authentication options. Ensure correct host, port, secure flag, and user credentials are provided. ```javascript const { ImapFlow } = require('imapflow'); const client = new ImapFlow({ host: 'imap.example.com', port: 993, secure: true, auth: { user: 'user@example.com', pass: 'password' } }); ``` -------------------------------- ### Configure High-Volume Sync Source: https://github.com/postalsys/imapflow/blob/master/_autodocs/configuration.md Optimize for high-volume synchronization by enabling `qresync`, setting `maxIdleTime`, `socketTimeout`, and configuring compression and line/literal sizes. ```javascript const client = new ImapFlow({ host: 'imap.example.com', port: 993, secure: true, auth: { user: 'user@example.com', pass: 'password' }, qresync: true, // More efficient sync maxIdleTime: 30 * 60 * 1000, // Restart IDLE every 30 min socketTimeout: 10 * 60 * 1000, // 10 min socket timeout disableCompression: false, // Use compression maxLineLength: 100 * 1024 * 1024, maxLiteralSize: 500 * 1024 * 1024 }); ``` -------------------------------- ### Get and Reset Connection Stats Source: https://github.com/postalsys/imapflow/blob/master/_autodocs/imapflow-client-api.md Retrieve byte counters for the current connection. Call with `true` to reset counters after retrieval. Useful for monitoring data transfer. ```javascript const stats = client.stats(); console.log(`Sent: ${stats.sent} bytes, Received: ${stats.received} bytes`); // Reset counters const prevStats = client.stats(true); ``` -------------------------------- ### Connect and Fetch Messages with ImapFlow Source: https://github.com/postalsys/imapflow/blob/master/README.md Demonstrates establishing a secure IMAP connection, locking a mailbox, fetching messages, and logging subjects. ```js const { ImapFlow } = require('imapflow'); const client = new ImapFlow({ host: 'imap.example.com', port: 993, secure: true, auth: { user: 'user@example.com', pass: 'password' } }); const main = async () => { await client.connect(); let lock = await client.getMailboxLock('INBOX'); try { // fetch latest message let message = await client.fetchOne(client.mailbox.exists, { source: true }); console.log(message.source.toString()); // list subjects for all messages for await (let message of client.fetch('1:*', { envelope: true })) { console.log(`${message.uid}: ${message.envelope.subject}`); } } finally { // always release the lock lock.release(); } await client.logout(); }; main().catch(console.error); ``` -------------------------------- ### Get Mailbox Quota with ImapFlow Source: https://github.com/postalsys/imapflow/blob/master/_autodocs/imapflow-client-api.md Retrieves current quota information for a mailbox, including storage and message limits. Returns false if quota information is not supported. ```javascript const quota = await client.getQuota('INBOX'); if (quota) { const percent = (quota.storage.used / quota.storage.limit * 100).toFixed(1); console.log(`Storage: ${percent}% full`); } ``` -------------------------------- ### Configure ImapFlow with STARTTLS Source: https://github.com/postalsys/imapflow/blob/master/_autodocs/configuration.md Configure ImapFlow to use STARTTLS for upgrading an unencrypted connection to TLS. Set `secure` to `false` and `port` to a non-993 value like 143. ```javascript // Plaintext with STARTTLS upgrade const client = new ImapFlow({ host: 'imap.example.com', port: 143, secure: false }); ``` -------------------------------- ### Get Mailbox Status in JavaScript Source: https://github.com/postalsys/imapflow/blob/master/_autodocs/README.md Retrieves and logs the total number of messages and unseen messages for a specified mailbox. Requires mailbox name and status options. ```javascript const status = await client.status('INBOX', { messages: true, unseen: true, uidNext: true }); console.log(`Total: ${status.messages}, Unseen: ${status.unseen}`); ``` -------------------------------- ### Fetch Last Message Source: https://github.com/postalsys/imapflow/blob/master/_autodocs/fetch-and-download.md Demonstrates fetching the last message in the mailbox, both by sequence number and by UID. `client.mailbox.exists` can be used to get the total number of messages for sequence-based fetching. ```javascript // Fetch last message by sequence const lastMsg = await client.fetchOne(client.mailbox.exists, { envelope: true, source: true }); // Fetch last message by UID const lastMsg = await client.fetchOne('*', { envelope: true }, { uid: true }); ``` -------------------------------- ### Use QRESYNC for Synchronization Source: https://github.com/postalsys/imapflow/blob/master/_autodocs/configuration.md Utilize the QRESYNC extension instead of CONDSTORE for synchronization. EXPUNGE notifications will include UID instead of sequence number. Defaults to false. ```javascript const client = new ImapFlow({ host: 'imap.example.com', port: 993, secure: true, qresync: true }); ``` -------------------------------- ### Get Mailbox Status with ImapFlow Source: https://github.com/postalsys/imapflow/blob/master/_autodocs/imapflow-client-api.md Requests specific status information for a mailbox without opening it. Supports requesting message counts, recent messages, next UID, UIDValidity, and highest modseq. ```javascript const status = await client.status('INBOX', { messages: true, unseen: true }); console.log(`${status.messages} total, ${status.unseen} unseen`); ``` -------------------------------- ### List All Mailboxes in JavaScript Source: https://github.com/postalsys/imapflow/blob/master/_autodocs/README.md Fetches and logs the paths of all available mailboxes. Ensure the client is connected before calling. ```javascript const mailboxes = await client.list(); mailboxes.forEach(mbox => { console.log(mbox.path); }); ``` -------------------------------- ### ImapFlow Constructor Source: https://github.com/postalsys/imapflow/blob/master/_autodocs/imapflow-client-api.md Creates a new ImapFlow client instance with specified connection options. ```APIDOC ## ImapFlow Constructor ### `ImapFlow(options: ImapFlowOptions)` Creates a new IMAP client instance. **Parameters:** | Parameter | Type | Required | Default | Description | |-----------|------|----------|---------|-------------| | options | ImapFlowOptions | yes | — | Configuration object for the IMAP connection | **Returns:** `ImapFlow` instance **Example:** ```javascript const { ImapFlow } = require('imapflow'); const client = new ImapFlow({ host: 'imap.example.com', port: 993, secure: true, auth: { user: 'user@example.com', pass: 'password' } }); ``` ``` -------------------------------- ### Configure HTTP CONNECT Proxy Source: https://github.com/postalsys/imapflow/blob/master/_autodocs/configuration.md Set up an HTTP CONNECT proxy for the IMAP connection. Specify the proxy URL including scheme, host, and port. ```javascript // HTTP CONNECT proxy const client = new ImapFlow({ host: 'imap.example.com', port: 993, secure: true, proxy: 'http://proxy.company.com:3128' }); ``` -------------------------------- ### Connect to IMAP Server Source: https://github.com/postalsys/imapflow/blob/master/_autodocs/imapflow-client-api.md Initiate a connection to the IMAP server, handling TLS negotiation, authentication, and capability detection. Includes error handling for authentication failures and general connection errors. ```javascript try { await client.connect(); console.log('Connected and authenticated'); } catch (err) { if (err.authenticationFailed) { console.error('Login failed:', err.message); } else { console.error('Connection error:', err.message); } } ``` -------------------------------- ### fetchAll() Source: https://github.com/postalsys/imapflow/blob/master/_autodocs/fetch-and-download.md Fetches all messages within a specified range and buffers them into an array. Best for small result sets where full buffering is acceptable. Avoid for large mailboxes to prevent memory exhaustion. ```APIDOC ## fetchAll() ### Description Fetches all messages and buffers into array. ### Signature ```javascript fetchAll(range: SequenceString | number[] | SearchObject, query: FetchQueryObject, options?: FetchOptions): Promise ``` ### Best for Small result sets where full buffering is acceptable. ### Caveat Do NOT use for large mailboxes (memory exhaustion). ### Basic Usage ```javascript const messages = await client.fetchAll('1:100', { uid: true, envelope: true, size: true }); console.log(`Fetched ${messages.length} messages`); messages.forEach(msg => { console.log(`${msg.uid}: ${msg.envelope.subject} (${msg.size} bytes)`); }); ``` ### Sorted Results ```javascript const messages = await client.fetchAll('1:*', { uid: true, internalDate: true, envelope: true }); // Sort by date descending messages.sort((a, b) => { return new Date(b.internalDate) - new Date(a.internalDate); }); messages.slice(0, 10).forEach(msg => { console.log(`${msg.internalDate}: ${msg.envelope.subject}`); }); ``` ### Filtered Results ```javascript const messages = await client.fetchAll('1:*', { uid: true, size: true, envelope: true }); // Filter large messages const largeMessages = messages .filter(msg => msg.size > 5 * 1024 * 1024) .sort((a, b) => b.size - a.size); console.log(`Found ${largeMessages.length} large messages`); ``` ``` -------------------------------- ### Force STARTTLS in ImapFlow Source: https://github.com/postalsys/imapflow/blob/master/_autodocs/configuration.md Force ImapFlow to use STARTTLS by setting `doSTARTTLS` to `true`. The connection will fail if STARTTLS is not supported by the server. ```javascript // Force STARTTLS (fail if not available) const client = new ImapFlow({ host: 'imap.example.com', port: 143, secure: false, doSTARTTLS: true }); ``` -------------------------------- ### download() Method Source: https://github.com/postalsys/imapflow/blob/master/_autodocs/fetch-and-download.md Downloads the full message or a specific body part as a stream. This method is best for memory-efficient streaming of large content. ```APIDOC ## download(range: SequenceString, part?: string, options?: { uid?: boolean; maxBytes?: number; chunkSize?: number; }): Promise Downloads full message or specific body part as stream. ### Parameters - **range** (SequenceString) - Required - The sequence number or UID of the message. - **part** (string) - Optional - The MIME part identifier (e.g., '1', 'TEXT', '2'). If not provided, the full message is downloaded. - **options** (object) - Optional - Configuration options for the download. - **uid** (boolean) - If true, `range` is treated as a UID. Defaults to false. - **maxBytes** (number) - Maximum number of bytes to download. - **chunkSize** (number) - The size of chunks to read from the stream. ### Returns - Promise - A promise that resolves to a DownloadObject containing `meta` (message metadata) and `content` (a Readable stream). ### Example: Download Full Message ```javascript const download = await client.download('1'); console.log('Content-Type:', download.meta.contentType); console.log('Size:', download.meta.expectedSize, 'bytes'); // Stream to file const fs = require('fs'); download.content.pipe(fs.createWriteStream('message.eml')); // Or consume as Buffer const chunks = []; for await (const chunk of download.content) { chunks.push(chunk); } const buffer = Buffer.concat(chunks); ``` ### Example: Download Specific Part ```javascript // Download text body const textPart = await client.download('1', 'TEXT'); console.log('Text body:', textPart.content.toString()); // Download attachment const attachment = await client.download('1', '2'); console.log('Attachment:', attachment.meta.filename); console.log('Type:', attachment.meta.contentType); // Check metadata before streaming if (attachment.meta.expectedSize > 100 * 1024 * 1024) { console.log('Attachment too large'); } else { attachment.content.pipe(process.stdout); } ``` ### Example: With Options ```javascript // Limit download size const download = await client.download('1', undefined, { uid: true, maxBytes: 10 * 1024 * 1024 // 10 MB limit }); // Custom chunk size const download = await client.download('1', undefined, { chunkSize: 64 * 1024 // 64 KB chunks }); ``` ### Example: Error Handling ```javascript try { const download = await client.download('999'); download.content.on('error', (err) => { console.error('Stream error:', err.message); }); } catch (err) { if (err.message.includes('not found')) { console.error('Message does not exist'); } else { console.error('Download failed:', err.message); } } ``` ``` -------------------------------- ### Download Multiple Body Parts Using UID Source: https://github.com/postalsys/imapflow/blob/master/_autodocs/fetch-and-download.md Demonstrates how to use the downloadMany() method with the `uid` option set to true, allowing message selection by UID instead of sequence number. This is useful for targeting specific messages when UIDs are known. ```javascript const result = await client.downloadMany('12345', ['1', '2', '3'], { uid: true }); ``` -------------------------------- ### Connect and Log Server Info Source: https://github.com/postalsys/imapflow/blob/master/_autodocs/imapflow-client-api.md Connects to the IMAP server and logs various details about the connection, including server information, capabilities, authenticated user, and selected mailbox details. Ensure the client is connected before accessing these properties. ```javascript await client.connect(); console.log('Connected to:', client.serverInfo.vendor); console.log('Capabilities:', Array.from(client.capabilities.keys())); console.log('User:', client.authenticated); await client.mailboxOpen('INBOX'); console.log('Mailbox:', client.mailbox.path); console.log('Messages:', client.mailbox.exists); ``` -------------------------------- ### Download Multiple Body Parts Source: https://github.com/postalsys/imapflow/blob/master/_autodocs/fetch-and-download.md Demonstrates basic usage of downloadMany() to fetch specified parts of a message and log their content type and size. Ensure the client is authenticated and connected. ```javascript const result = await client.downloadMany('1', ['1', '1.1', '2']); Object.entries(result).forEach(([part, data]) => { if (data.content) { console.log(`Part ${part}: ${data.meta.contentType} (${data.content.length} bytes)`); } else { console.log(`Part ${part}: Not available`); } }); ``` -------------------------------- ### Fetch Messages with ALL Macro Source: https://github.com/postalsys/imapflow/blob/master/_autodocs/fetch-and-download.md Uses the 'all' macro to fetch comprehensive message data, including flags, internal date, size, and envelope information. This is a shortcut for common fetch requirements. ```javascript for await (let msg of client.fetch('1:*', { all: true })) { console.log(msg.envelope.subject, msg.size); } ``` -------------------------------- ### Basic Authentication with Username and Password Source: https://github.com/postalsys/imapflow/blob/master/_autodocs/configuration.md Configure the client with username and password for basic IMAP authentication. Ensure the 'user' field is set to your email address. ```javascript const client = new ImapFlow({ host: 'imap.example.com', port: 993, secure: true, auth: { user: 'user@example.com', pass: 'password' } }); ``` -------------------------------- ### Fetch All Headers Source: https://github.com/postalsys/imapflow/blob/master/_autodocs/fetch-and-download.md Iterates through a range of messages and logs all their headers as a Buffer. The headers are decoded to a string for display. ```javascript // All headers for await (let msg of client.fetch('1:10', { headers: true })) { console.log(msg.headers.toString()); } ``` -------------------------------- ### Download with Options in imapflow Source: https://github.com/postalsys/imapflow/blob/master/_autodocs/fetch-and-download.md Allows setting options for the download, such as limiting the download size with `maxBytes` or specifying a custom `chunkSize` for streaming. The `uid` option can be used to specify the message by UID instead of sequence number. ```javascript // Limit download size const download = await client.download('1', undefined, { uid: true, maxBytes: 10 * 1024 * 1024 // 10 MB limit }); // Custom chunk size const download = await client.download('1', undefined, { chunkSize: 64 * 1024 // 64 KB chunks }); ``` -------------------------------- ### Fetch All Messages (Basic Usage) Source: https://github.com/postalsys/imapflow/blob/master/_autodocs/fetch-and-download.md Fetches a specified range of messages and buffers them into an array. Best for small result sets where full buffering is acceptable. Do not use for large mailboxes due to potential memory exhaustion. ```javascript const messages = await client.fetchAll('1:100', { uid: true, envelope: true, size: true }); console.log(`Fetched ${messages.length} messages`); messages.forEach(msg => { console.log(`${msg.uid}: ${msg.envelope.subject} (${msg.size} bytes)`); }); ``` -------------------------------- ### Connect to Gmail IMAP with OAuth2 Source: https://github.com/postalsys/imapflow/blob/master/_autodocs/README.md Initializes ImapFlow for Gmail using host, port, secure connection, and OAuth2 authentication. Requires user credentials and an access token. ```javascript new ImapFlow({ host: 'imap.gmail.com', port: 993, secure: true, auth: { user: 'user@gmail.com', accessToken: 'ya29.a0AfH6SMBx...' // OAuth2 token } }); ``` -------------------------------- ### Configure Self-Hosted with Self-Signed Certificate Source: https://github.com/postalsys/imapflow/blob/master/_autodocs/configuration.md Use this for self-hosted mail servers with self-signed certificates. Set `rejectUnauthorized` to false to allow the connection. Specify `servername` if it differs from the host. ```javascript const client = new ImapFlow({ host: 'mail.mycompany.local', port: 993, secure: true, servername: 'mail.mycompany.local', tls: { rejectUnauthorized: false, // Allow self-signed cert minVersion: 'TLSv1.2' }, auth: { user: 'user@mycompany.local', pass: 'password' } }); ``` -------------------------------- ### connect() Errors Source: https://github.com/postalsys/imapflow/blob/master/_autodocs/errors.md Errors that can occur during the `connect()` operation, including authentication and connection issues. ```APIDOC ## connect() | Error | Trigger | |-------|---------| | `AuthenticationFailure` | Credentials invalid, account locked | | `Error` (ECONNREFUSED) | Server refused connection | | `Error` (ENOTFOUND) | Server hostname not found | | `Error` (ETIMEDOUT) | Connection timeout exceeded | | `Error` (TLS error) | Certificate validation failed | ``` -------------------------------- ### Check Server Extension Support Source: https://github.com/postalsys/imapflow/blob/master/_autodocs/errors.md Verify if the IMAP server supports specific search criteria or extensions before attempting to use them. Throws an error if a required extension is missing. ```javascript function supportsSearch(client, criterion) { const unsupported = { 'emailId': !client.enabled.has('OBJECTID') && !client.capabilities.has('X-GM-EXT-1'), 'threadId': !client.enabled.has('OBJECTID') && !client.capabilities.has('X-GM-EXT-1'), 'gmraw': !client.capabilities.has('X-GM-EXT-1'), 'modseq': !client.enabled.has('CONDSTORE') }; if (unsupported[criterion]) { throw new Error(`Server does not support ${criterion} searches`); } } ``` -------------------------------- ### Check Server Capabilities in ImapFlow Source: https://github.com/postalsys/imapflow/blob/master/_autodocs/errors.md After connecting, you can inspect the server's capabilities, enabled extensions, and general server information. ```javascript await client.connect(); console.log('Server capabilities:', Array.from(client.capabilities.keys())); console.log('Enabled extensions:', Array.from(client.enabled)); console.log('Server info:', client.serverInfo); ``` -------------------------------- ### Fetch Messages with FAST Macro Source: https://github.com/postalsys/imapflow/blob/master/_autodocs/fetch-and-download.md Uses the 'fast' macro to fetch basic message information including flags, internal date, and size. This is a shortcut for specifying multiple fetch options. ```javascript for await (let msg of client.fetch('1:*', { fast: true })) { console.log(msg.seq, msg.flags, msg.size); } ``` -------------------------------- ### Fetch All Messages into an Array Source: https://github.com/postalsys/imapflow/blob/master/_autodocs/imapflow-client-api.md Use `fetchAll` when you need all messages from a specific range buffered into an array. This method is suitable only for small result sets to avoid memory issues. ```javascript const messages = await client.fetchAll('1:100', { uid: true, envelope: true, size: true }); console.log(`Fetched ${messages.length} messages`); ``` -------------------------------- ### Create Mailbox - Imapflow Client Source: https://github.com/postalsys/imapflow/blob/master/_autodocs/imapflow-client-api.md Creates a new mailbox folder. Returns information about the creation, including whether it was newly created or already existed. ```javascript const result = await client.mailboxCreate('Archive/2024'); if (result.created) { console.log('Created:', result.path); } else { console.log('Already exists:', result.path); } ``` -------------------------------- ### ImapFlowOptions Source: https://github.com/postalsys/imapflow/blob/master/_autodocs/types.md Configuration object for creating a new ImapFlow instance. It includes settings for server connection, authentication, TLS, logging, and various operational parameters. ```APIDOC ## ImapFlowOptions ### Description Configuration object for creating a new ImapFlow instance. ### Fields #### host (string) - Required - Hostname of the IMAP server #### port (number) - Required - Port number #### secure (boolean) - Optional - Use TLS directly (default: false) #### servername (string) - Optional - Server name for SNI #### disableCompression (boolean) - Optional - Disable COMPRESS=DEFLATE (default: false) #### auth (object) - Optional - Authentication details ##### auth.user (string) - Required - Username for authentication ##### auth.pass (string) - Optional - Password for regular auth ##### auth.accessToken (string) - Optional - OAuth2 access token ##### auth.loginMethod (string) - Optional - Specific login method override ##### auth.authzid (string) - Optional - Authorization identity for SASL PLAIN #### clientInfo (IdInfoObject) - Optional - Client ID info sent to server #### disableAutoIdle (boolean) - Optional - Disable automatic IDLE start (default: false) #### tls (ConnectionOptions) - Optional - Additional TLS options #### logger (Logger | false) - Optional - Custom logger instance #### logRaw (boolean) - Optional - Log raw base64-encoded data (default: false) #### emitLogs (boolean) - Optional - Emit 'log' events (default: false) #### verifyOnly (boolean) - Optional - Disconnect after auth (default: false) #### includeMailboxes (boolean) - Optional - List mailboxes if verifyOnly (default: false) #### proxy (string) - Optional - Proxy URL (http, https, socks) #### qresync (boolean) - Optional - Use QRESYNC instead of CONDSTORE (default: false) #### maxIdleTime (number) - Optional - Break and restart IDLE every N ms #### missingIdleCommand (string) - Optional - Fallback if IDLE not supported (default: 'NOOP') #### disableBinary (boolean) - Optional - Ignore BINARY extension (default: false) #### disableAutoEnable (boolean) - Optional - Don't enable extensions automatically (default: false) #### connectionTimeout (number) - Optional - Connection timeout in ms (default: 90000) #### greetingTimeout (number) - Optional - Greeting timeout in ms (default: 16000) #### socketTimeout (number) - Optional - Socket inactivity timeout in ms (default: 300000) #### maxLineLength (number) - Optional - Max line length in bytes (default: 1073741824) #### maxLiteralSize (number) - Optional - Max literal block size in bytes (default: 1073741824) #### maxLockHoldTime (number | false) - Optional - Lock hold time warning threshold in ms (default: 1800000) #### doSTARTTLS (boolean) - Optional - Force STARTTLS usage #### id (string) - Optional - Custom instance ID for logs #### expungeHandler (function) - Optional - Custom expunge event handler ``` -------------------------------- ### Robust Search with Fallback Source: https://github.com/postalsys/imapflow/blob/master/_autodocs/errors.md Perform searches using advanced options first and fall back to a simpler search if the server does not support the advanced features. Logs a warning when falling back. ```javascript async function robustSearch(client, query) { try { // Try with advanced features first return await client.search(query, { uid: true, returnOptions: ['COUNT', 'MIN', 'MAX'] }); } catch (err) { if (err.message.includes('BAD') || err.message.includes('NO')) { // Server doesn't support advanced options, try simple search console.warn('Falling back to simple search'); return await client.search(query, { uid: true }); } throw err; } } ``` -------------------------------- ### Fetch Partial Message Source (maxLength) Source: https://github.com/postalsys/imapflow/blob/master/_autodocs/fetch-and-download.md Fetches the first 1000 bytes of a message's source. The source is returned as a Buffer. ```javascript // Partial (first 1000 bytes) const msg = await client.fetchOne('1', { source: { maxLength: 1000 } }); ``` -------------------------------- ### downloadMany() Method Source: https://github.com/postalsys/imapflow/blob/master/_autodocs/fetch-and-download.md Downloads multiple body parts from a single message as buffers. This method is best for fetching multiple parts when buffering is acceptable. ```APIDOC ## downloadMany() ### Description Downloads multiple body parts from a single message as buffers. ### Method Signature ```javascript downloadMany(range: SequenceString, parts: string[], options?: { uid?: boolean }): Promise<{ [part: string]: { meta: {...}; content: Buffer | null } }> ``` ### Parameters - **range** (SequenceString) - Required - The sequence number or UID of the message. - **parts** (string[]) - Required - An array of part identifiers to download. - **options** (object) - Optional - Configuration options. - **uid** (boolean) - Optional - If true, the `range` parameter is treated as a UID. ### Returns An object keyed by part identifier. Each value contains `meta` (metadata about the part) and `content` (the downloaded content as a Buffer or null if not available). ### Basic Usage ```javascript const result = await client.downloadMany('1', ['1', '1.1', '2']); Object.entries(result).forEach(([part, data]) => { if (data.content) { console.log(`Part ${part}: ${data.meta.contentType} (${data.content.length} bytes)`); } else { console.log(`Part ${part}: Not available`); } }); ``` ### Extract All Attachments This example demonstrates how to first fetch the message structure to identify attachment parts and then download them using `downloadMany`. ```javascript // First, fetch structure to identify attachment parts const msg = await client.fetchOne('1', { bodyStructure: true }); const attachmentParts = []; function findAttachments(node, prefix = '') { if (node.disposition === 'attachment') { attachmentParts.push(node.part || prefix); } if (node.childNodes) { node.childNodes.forEach((child, idx) => { const childPrefix = prefix ? `${prefix}.${idx + 1}` : (idx + 1).toString(); findAttachments(child, childPrefix); }); } } findAttachments(msg.bodyStructure); // Download all attachments if (attachmentParts.length > 0) { const attachments = await client.downloadMany('1', attachmentParts); attachmentParts.forEach(part => { const data = attachments[part]; if (data.content) { console.log(`${data.meta.filename}: ${data.content.length} bytes`); } }); } ``` ### With UID Example of using the `uid` option to specify that the `range` parameter is a UID. ```javascript const result = await client.downloadMany('12345', ['1', '2', '3'], { uid: true }); ``` ```