← 返回 Skills 市场
openlark

imapflow

作者 OpenLark · GitHub ↗ · v1.0.0 · MIT-0
cross-platform ✓ 安全检测通过
8
总下载
0
收藏
0
当前安装
1
版本数
在 OpenClaw 中安装
/install imapflow
功能描述
Modern Node.js IMAP client library (imapflow) for email integration.Covers authentication, mailbox locking, streaming fetches, async iterators, reconnection...
使用说明 (SKILL.md)

\r \r

ImapFlow\r

\r

Overview\r

\r ImapFlow is a modern, promise-based IMAP client for Node.js. It auto-detects and handles IMAP extensions (CONDSTORE, QRESYNC, IDLE, COMPRESS, etc.) so the same code works across servers.\r \r Key features: async/await API, async iterators for message streaming, built-in mailbox locking, TypeScript support, SOCKS/HTTP proxy support, Gmail X-GM-EXT-1 support.\r \r

Trigger Scene\r

\r Use when building email features: connecting to IMAP servers, fetching/reading emails, searching mailboxes, managing folders, monitoring new messages via IDLE, working with Gmail labels and Gmail-specific extensions, or any IMAP-based email automation. \r \r

Quick Start\r

\r

const { ImapFlow } = require('imapflow');\r
\r
const client = new ImapFlow({\r
    host: 'imap.example.com',\r
    port: 993,\r
    secure: true,\r
    auth: { user: '[email protected]', pass: 'password' }\r
});\r
\r
await client.connect();\r
\r
let lock = await client.getMailboxLock('INBOX');\r
try {\r
    // Fetch latest message\r
    let msg = await client.fetchOne(client.mailbox.exists, { source: true });\r
    console.log(msg.source.toString());\r
\r
    // Stream all messages\r
    for await (let msg of client.fetch('1:*', { envelope: true })) {\r
        console.log(`${msg.uid}: ${msg.envelope.subject}`);\r
    }\r
} finally {\r
    lock.release();\r
}\r
\r
await client.logout();\r
```\r
\r
## Core Tasks\r
\r
### 1. Connecting\r
\r
```js\r
const client = new ImapFlow({\r
    host: 'imap.example.com',\r
    port: 993,\r
    secure: true,\r
    auth: { user: '[email protected]', pass: 'password' }\r
});\r
await client.connect();\r
```\r
\r
**Provider-specific configs** → See [references/connection.md](references/connection.md) for Gmail, Outlook, Yahoo, iCloud, and other common providers.\r
\r
**OAuth2 / XOAUTH2:**\r
```js\r
auth: {\r
    user: '[email protected]',\r
    accessToken: 'ya29.xxx...'\r
}\r
```\r
\r
**Common options:**\r
- `logger`: Pass a logger object (`console`, pino, etc.) for debug output. Set `logger: false` to disable.\r
- `emitLogs`: Set `true` to emit 'log' events instead of using a logger.\r
- `clientInfo`: Custom client identification `{ name: 'myapp', version: '1.0.0' }`.\r
- `disableAutoIdle`: Disable automatic IDLE when mailbox is selected.\r
\r
**Disconnect:** Call `client.logout()` for graceful disconnect. Handle `client.close()` for abrupt close.\r
\r
### 2. Fetching Messages\r
\r
**Always acquire a mailbox lock before fetching:**\r
```js\r
let lock = await client.getMailboxLock('INBOX');\r
try {\r
    // ... fetch operations ...\r
} finally {\r
    lock.release();\r
}\r
```\r
\r
**Fetch one message:**\r
```js\r
let msg = await client.fetchOne('*', { source: true });\r
// or by sequence number: client.fetchOne(42, { source: true })\r
// or by UID (append `uid` flag):\r
let msg = await client.fetchOne('12345', { uid: true, source: true });\r
```\r
\r
**Fetch query options** (what data to retrieve — choose only what you need):\r
- `source` — Full RFC822 message source (as Buffer)\r
- `envelope` — Parsed envelope (subject, from, to, date, message-id)\r
- `bodyStructure` — MIME structure tree\r
- `flags` — Array of flags (\\Seen, \\Answered, etc.)\r
- `internalDate` — Internal server date\r
- `size` — Message size in bytes\r
- `uid` — UID (always included)\r
- `threadId` — THREAD=ORDEREDSUBJECT reference (Gmail)\r
- `labels` — Gmail labels (X-GM-LABELS)\r
- `headers` — Raw headers as Buffer\r
- `bodyParts` — Array of MIME part paths to fetch, e.g. `['1.1', '1.2']`\r
\r
**Stream/iterate messages:**\r
```js\r
// Range: sequence numbers\r
for await (let msg of client.fetch('1:100', { envelope: true, flags: true })) {\r
    console.log(`${msg.seq}: ${msg.envelope.subject}`);\r
}\r
\r
// All messages: '1:*'\r
for await (let msg of client.fetch('1:*', { envelope: true })) { /* ... */ }\r
\r
// By UID range\r
for await (let msg of client.fetch('1000:2000', { uid: true, envelope: true })) { /* ... */ }\r
```\r
\r
**Fetch specific body parts:**\r
```js\r
let msg = await client.fetchOne('*', {\r
    bodyParts: ['1.1', '1.2'],  // MIME part paths\r
    source: true\r
});\r
// msg.bodyParts.get('1.1') → Buffer\r
// msg.text.toString() → decoded text content\r
```\r
\r
**Download attachments:**\r
```js\r
let msg = await client.fetchOne('*', { source: true, bodyStructure: true });\r
for (let attachment of msg.attachments) {\r
    let buf = await client.download(msg.uid, attachment.part, { uid: true });\r
    // buf contains the attachment data\r
}\r
```\r
\r
**Common envelope fields:** `msg.envelope.subject`, `msg.envelope.from[0].address`, `msg.envelope.to[0].address`, `msg.envelope.date`, `msg.envelope.messageId`, `msg.envelope.inReplyTo`.\r
\r
### 3. Searching\r
\r
```js\r
let lock = await client.getMailboxLock('INBOX');\r
try {\r
    // Simple search\r
    let list = await client.search({ unseen: true });\r
\r
    // Complex query\r
    let list = await client.search({\r
        from: '[email protected]',\r
        subject: 'invoice',\r
        seen: false,\r
        since: new Date('2024-01-01'),\r
        before: new Date('2024-12-31'),\r
        larger: 1024 * 1024  // > 1MB\r
    });\r
\r
    // Text search (body)\r
    let list = await client.search({ body: 'important keyword' });\r
\r
    // Combine with OR\r
    let list = await client.search({\r
        or: [\r
            { from: '[email protected]' },\r
            { from: '[email protected]' }\r
        ]\r
    });\r
\r
    // Combine AND + OR\r
    let list = await client.search({\r
        subject: 'report',\r
        or: [\r
            { from: '[email protected]' },\r
            { from: '[email protected]' }\r
        ]\r
    });\r
\r
    // List is an array of sequence numbers. Use fetch() with those:\r
    for await (let msg of client.fetch(list, { envelope: true })) {\r
        console.log(msg.envelope.subject);\r
    }\r
} finally {\r
    lock.release();\r
}\r
```\r
\r
**Search keys** → See [references/searching.md](references/searching.md) for the full IMAP search key reference.\r
\r
**Gmail raw search (X-GM-RAW):**\r
```js\r
let list = await client.search({ 'x-gm-raw': 'has:attachment larger:10M' });\r
```\r
\r
### 4. Mailbox Management\r
\r
```js\r
// List all mailboxes\r
let mailboxes = await client.list();\r
for (let mb of mailboxes) {\r
    console.log(`${mb.name} (${mb.path})`);\r
}\r
// Filter by pattern: client.list({ path: 'INBOX/*' })\r
\r
// Status (message count, unseen, etc.)\r
let status = await client.status('INBOX', { messages: true, unseen: true, uidNext: true });\r
console.log(`${status.messages} total, ${status.unseen} unseen`);\r
\r
// Mailbox info (when a mailbox is selected)\r
console.log(client.mailbox.exists);    // total messages\r
console.log(client.mailbox.uidNext);   // next predicted UID (CONDSTORE)\r
console.log(client.mailbox.uidValidity);\r
\r
// Create / Rename / Delete\r
await client.mailboxCreate('Projects/NewProject');\r
await client.mailboxRename('Projects/Old', 'Projects/New');\r
await client.mailboxDelete('Projects/Archive');\r
\r
// Subscribe / Unsubscribe\r
await client.mailboxSubscribe('INBOX/Newsletters');\r
await client.mailboxUnsubscribe('INBOX/Newsletters');\r
\r
// Move messages\r
await client.messageMove('1:5', 'Archive', { uid: false });\r
// Copy messages\r
await client.messageCopy('100:200', 'Important', { uid: true });\r
\r
// Delete messages (set \Deleted flag + expunge)\r
await client.messageDelete('1:10');\r
// Or manually: flag + expunge\r
await client.messageFlagsAdd('1:10', ['\\Deleted']);\r
await client.messageExpunge('1:10');  // or expunge all: client.mailboxExpunge()\r
```\r
\r
### 5. IDLE (Push Notifications)\r
\r
ImapFlow automatically enters IDLE when there's an active mailbox lock and no pending commands. Use events to react to new messages:\r
\r
```js\r
client.on('exists', async (data) => {\r
    console.log(`New messages! Count: ${data.count}`);\r
    // Fetch new messages\r
    let lock = await client.getMailboxLock('INBOX');\r
    try {\r
        for await (let msg of client.fetch(`${data.prevCount + 1}:${data.count}`, { envelope: true })) {\r
            console.log(`New: ${msg.envelope.subject}`);\r
        }\r
    } finally {\r
        lock.release();\r
    }\r
});\r
\r
client.on('expunge', (data) => {\r
    console.log(`Message seq#${data.seq} was deleted`);\r
});\r
\r
client.on('flags', (data) => {\r
    console.log(`Flags changed for seq#${data.seq}: ${data.flags}`);\r
});\r
\r
// Connect and select mailbox — IDLE starts automatically\r
await client.connect();\r
let lock = await client.getMailboxLock('INBOX');\r
// Keep lock active — IDLE runs in background\r
```\r
\r
**Manual IDLE control:**\r
```js\r
client.on('idle', () => console.log('Entered IDLE'));\r
// To disable auto-IDLE: new ImapFlow({ disableAutoIdle: true })\r
```\r
\r
### 6. Gmail-Specific Operations\r
\r
```js\r
// Gmail labels\r
let msg = await client.fetchOne('*', { labels: true });\r
console.log(msg.labels); // ['\\Inbox', 'Important', 'Starred']\r
\r
// Set labels\r
await client.messageFlagsAdd('1', ['\\Starred', 'Important'], { uid: true });\r
await client.messageFlagsRemove('100', ['Important'], { uid: true });\r
await client.messageFlagsSet('42', ['\\Inbox', 'CustomLabel'], { uid: true });\r
\r
// Gmail raw search\r
let results = await client.search({ 'x-gm-raw': 'from:alice has:attachment newer_than:7d' });\r
\r
// Gmail thread ID\r
let msg = await client.fetchOne('*', { threadId: true });\r
console.log(msg.threadId); // Gmail thread identifier\r
```\r
\r
Gmail connection config:\r
```js\r
new ImapFlow({\r
    host: 'imap.gmail.com',\r
    port: 993,\r
    secure: true,\r
    auth: {\r
        user: '[email protected]',\r
        accessToken: 'oauth2-token'  // Use OAuth2\r
    }\r
})\r
```\r
\r
> **Note:** Gmail requires OAuth2 or App Passwords. Regular passwords won't work unless "Less secure app access" is enabled (deprecated).\r
\r
### 7. Error Handling & Reconnection\r
\r
**Connection events:**\r
```js\r
client.on('error', (err) => {\r
    console.error('IMAP error:', err.message);\r
    // Connection is likely closed after a fatal error\r
});\r
\r
client.on('close', () => {\r
    console.log('Connection closed');\r
    // Reconnect logic here\r
});\r
\r
client.on('connectionError', (err) => {\r
    console.error('Connection failed:', err.message);\r
});\r
```\r
\r
**Reconnection pattern:**\r
```js\r
async function connectWithRetry(config, maxRetries = 5) {\r
    for (let i = 0; i \x3C maxRetries; i++) {\r
        try {\r
            const client = new ImapFlow(config);\r
            await client.connect();\r
            return client;\r
        } catch (err) {\r
            console.error(`Connection attempt ${i + 1} failed: ${err.message}`);\r
            if (i \x3C maxRetries - 1) {\r
                await new Promise(r => setTimeout(r, Math.min(1000 * Math.pow(2, i), 30000)));\r
            }\r
        }\r
    }\r
    throw new Error('All connection attempts failed');\r
}\r
```\r
\r
**Mailbox locking best practices:**\r
- Always use `try/finally` to release locks\r
- Keep lock durations short — release between operations when possible\r
- Never hold a lock across network calls or long async operations\r
- Use separate locks for read vs write operations when safe\r
\r
```js\r
// BAD: lock held too long\r
let lock = await client.getMailboxLock('INBOX');\r
let results = await client.search({ unseen: true });\r
// ... process results (slow, lock held) ...\r
lock.release();\r
\r
// GOOD: release lock between operations\r
let results;\r
{\r
    let lock = await client.getMailboxLock('INBOX');\r
    results = await client.search({ unseen: true });\r
    lock.release();\r
}\r
// Process results without holding lock\r
for (let seq of results) { /* ... */ }\r
```\r
\r
**Timeouts and connection health:**\r
```js\r
// No operation timeout (blocks forever) — set one\r
const timeout = setTimeout(() => client.close(), 30000);\r
// ... your operation ...\r
clearTimeout(timeout);\r
\r
// Check if connected: client.usable → true/false\r
```\r
\r
## Reference Files\r
\r
- **[connection.md](references/connection.md)** — Provider-specific connection configs: Gmail, Outlook/Hotmail, Yahoo, iCloud, Zoho, Fastmail, custom servers. Includes TLS, OAuth2, App Passwords, and proxy setup.\r
- **[searching.md](references/searching.md)** — Complete IMAP search key reference: flags, dates, sizes, headers, text searches, logical operators, sequence sets, Gmail raw search.\r
- **[api_reference.md](references/api_reference.md)** — Key API methods summary: client methods, events, MailboxLock, FetchQueryObject options, and ImapFlow constructor options.
安全使用建议
Use this skill only if you intend to let the agent help with IMAP email code. Keep mailbox credentials out of source code and logs, fetch the smallest needed set of messages, require confirmation before any delete/move/expunge/mailbox changes, and verify the external `imapflow` package before running generated code.
功能分析
Type: OpenClaw Skill Name: imapflow Version: 1.0.0 The imapflow skill bundle provides comprehensive documentation and code examples for integrating the standard Node.js ImapFlow library. It covers authentication, message fetching, searching, and mailbox management without any evidence of malicious intent, data exfiltration, or prompt injection.
能力标签
cryptocan-make-purchasesrequires-oauth-tokenrequires-sensitive-credentials
能力评估
Purpose & Capability
The documented capabilities fit the stated IMAP client purpose, including reading, searching, and managing mail, but references/api_reference.md also documents high-impact operations such as message and mailbox deletion.
Instruction Scope
The examples are user-directed API examples rather than automatic execution, but SKILL.md includes broad fetch examples such as full message source retrieval and all-message iteration.
Install Mechanism
There is no install spec or code in the skill, but SKILL.md examples rely on an external `imapflow` package while the registry source/homepage are unknown.
Credentials
Email passwords, app passwords, or OAuth access tokens are expected for IMAP access, but the registry metadata declares no primary credential or required environment variables.
Persistence & Privilege
No background service, autostart, persistence mechanism, or privileged installation is shown in the provided artifacts.
如何使用
  1. 确保已安装 OpenClaw(本地或 Docker 部署)
  2. 在对话框中输入安装命令:/install imapflow
  3. 安装完成后,直接呼叫该 Skill 的名称或使用 /imapflow 触发
  4. 根据 Skill 的参数说明提供必要输入,即可获得结构化输出
版本历史
v1.0.0
Initial release of the ImapFlow skill – a modern Node.js IMAP client for advanced email integration. - Provides comprehensive guides for connecting, authenticating (including provider-specific and OAuth2), and managing IMAP mailboxes. - Supports async/await and streaming/async iterator APIs for efficient email fetching. - Covers mailbox locking, searching, mailbox/label management, and downloading attachments. - Enables IDLE support for push notifications and outlines reconnection/proxy options. - Includes detailed usage recipes, common options, and references for major IMAP providers (e.g., Gmail, Outlook, Yahoo).
元数据
Slug imapflow
版本 1.0.0
许可证 MIT-0
累计安装 0
当前安装数 0
历史版本数 1
常见问题

imapflow 是什么?

Modern Node.js IMAP client library (imapflow) for email integration.Covers authentication, mailbox locking, streaming fetches, async iterators, reconnection... 它是一个面向 Claude Code / OpenClaw 的 AI Agent Skill 插件,目前累计下载 8 次。

如何安装 imapflow?

在 OpenClaw 或 Claude Code 对话框中运行命令「/install imapflow」即可一键安装,无需额外配置。

imapflow 是免费的吗?

是的,imapflow 完全免费,采用 MIT-0 许可证,可自由下载、安装和使用。

imapflow 支持哪些平台?

imapflow 跨平台运行,可在任意部署了 OpenClaw / Claude Code 的环境中使用(cross-platform)。

谁开发了 imapflow?

由 OpenLark(@openlark)开发并维护,当前版本 v1.0.0。

💬 留言讨论