npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2026 – Pkg Stats / Ryan Hefner

n8n-nodes-send-mail-thread

v0.3.2

Published

n8n community node bundle for sending SMTP replies in correct mail threads (In-Reply-To/References) and saving the same message to the IMAP Sent folder. Includes a push-based Mailbox Trigger using IMAP IDLE.

Readme

n8n-nodes-send-mail-thread

This is an n8n community node bundle for sending threaded SMTP replies and keeping your IMAP mailbox in sync.

It solves a common gap in n8n: when you reply to an email through SMTP, your sent message does not appear in the original thread on your side (because it never gets into your IMAP Sent folder), and your reply may not appear in-thread for the recipient (because the right In-Reply-To and References headers are not set).

This package fixes that with two nodes:

  • Mailbox Trigger (IMAP) — a push-based IMAP trigger using IMAP IDLE. Emits a normalized JSON shape (messageId, inReplyTo, references, uid, mailbox, etc.) that plugs straight into the action node.
  • Send Mail Thread — sends emails via SMTP with proper threading headers, and writes the same RFC822 bytes to the IMAP Sent folder so your mail client (eM Client, Gmail web, Outlook, …) sees the conversation correctly on both sides. Also marks the original as \Answered, moves it to a folder, etc.

Why this works

Mail clients identify thread membership by:

  1. The Message-ID header of each email (must be globally unique).
  2. The In-Reply-To header pointing to the previous message's Message-ID.
  3. The References header listing the full chain.

The trick is: the message you send via SMTP must have the same Message-ID as the copy you append to your Sent folder via IMAP. Otherwise your mail client cannot link them.

This package builds the MIME message once (with Nodemailer's MailComposer), then sends those exact bytes through SMTP and appends those exact bytes through IMAP. Same Message-ID, perfect threading on both sides.

Installation

In n8n: Settings → Community Nodes → Install → enter n8n-nodes-send-mail-threadInstall.

After install, both nodes appear in the panel:

  • Mailbox Trigger (IMAP) (under Triggers)
  • Send Mail Thread (under Actions)

Credentials

Create a single credential of type Mailbox (SMTP + IMAP). It holds both SMTP and IMAP connection details (host, port, TLS, user, password) plus optional defaults:

  • Default From Address / Name — used when the node's From field is empty
  • Sent Folder Detectionauto tries IMAP SPECIAL-USE \Sent, falls back to common names (Sent, Wysłane, [Gmail]/Sent Mail, …); manual lets you pin a folder name
  • Allow Self-Signed Certificates — only for self-hosted mail servers

The credential test verifies SMTP login and IMAP NOOP.

Provider-specific notes

  • Gmail / Google Workspace: enable 2-Step Verification, then create an App Password. Use that password (not your account password). SMTP smtp.gmail.com:465 (secure), IMAP imap.gmail.com:993 (secure). Sent folder: [Gmail]/Sent Mail.
  • Microsoft 365 / Outlook: SMTP smtp.office365.com:587 (secure off, STARTTLS), IMAP outlook.office365.com:993 (secure on). Basic auth must be enabled by your tenant admin (modern auth/OAuth2 is on the v2 roadmap).
  • Custom domain (cPanel / Plesk / Postfix): use the SMTP/IMAP details from your hosting panel.

Example workflow

Mailbox Trigger (IMAP) → AI Agent / OpenAI → Send Mail Thread (Send Reply in Thread)

The default field expressions in Send Reply in Thread already point at the trigger's output:

| Field | Default expression | | ----- | ------------------ | | Original Message-ID | ={{ $json.messageId }} | | Original References | ={{ ($json.references \|\| []).join(" ") }} | | Original Mailbox | ={{ $json.mailbox \|\| "INBOX" }} | | Original UID or Message-ID | ={{ $json.uid }} |

So you only need to fill in:

  • To — usually ={{ $json.from.address }}
  • Subject — usually ={{ $json.subject }} (auto-prepends Re: unless already there)
  • HTML Body — your AI-generated reply
  • (optional) Move Original to Folder — e.g. AI/Odpowiedziane

After execution, the original email gets the \Answered flag (eM Client shows the curved-arrow icon), your reply lives in the thread on both sides, and the original is moved to the AI folder if you set that.

Thread filtering and history (v0.2+)

The Mailbox Trigger has two powerful features for AI-powered email workflows:

Thread Filter Mode

Control which messages trigger the workflow:

| Mode | Description | | ---- | ----------- | | All Messages | Default. Emit every new message. | | New Threads Only | Skip replies. Only trigger when a brand-new conversation starts (no In-Reply-To, no References headers). Useful for intake workflows that only handle first-contact emails. | | Replies Only | Skip new threads. Only trigger when someone replies to an existing conversation. Useful for follow-up or escalation workflows. |

Include Thread History

When enabled, the trigger fetches all messages from the same conversation and attaches them as a thread array. This gives your AI agent full context of the conversation.

Output structure with thread history:

{
  "uid": 123,
  "messageId": "<latest@host>",
  "subject": "Re: Question about pricing",
  "text": "Thanks for the info...",
  "threadHistory": "[28/04/2026, 10:00] [email protected]:\nHi, I have a question...\n\n[28/04/2026, 11:00] [email protected] (You):\nHello! Happy to help...\n\n[28/04/2026, 12:00] [email protected]:\nThanks for the info...",
  "thread": [
    { "messageId": "<first@host>", "from": {...}, "date": "2026-04-28T10:00:00Z", "text": "Hi, I have a question...", "isOutgoing": false },
    { "messageId": "<reply1@me>", "from": {...}, "date": "2026-04-28T11:00:00Z", "text": "Hello! Happy to help...", "isOutgoing": true },
    { "messageId": "<latest@host>", "from": {...}, "date": "2026-04-28T12:00:00Z", "text": "Thanks for the info...", "isOutgoing": false }
  ],
  "threadCount": 3
}
  • threadHistory - pre-formatted string ready for LLM prompts. Messages marked with (You) are outgoing.
  • thread - array of message objects for advanced processing
  • isOutgoing - true for messages found in the Sent folder

Example AI prompt (simple):

You are a customer support assistant.

Conversation history:
{{ $json.threadHistory }}

Write a helpful reply to the customer's latest message.

Example AI prompt (using thread array for custom formatting):

{{ $json.thread.map(m => `[${m.date}] ${m.isOutgoing ? 'Support' : 'Customer'}: ${m.text}`).join("\n\n") }}

Options:

  • Thread Search Folders: Which folders to search for thread messages. Empty = current mailbox + auto-detected Sent folder.
  • Thread History Limit: Max messages to include (default 20). Protects against very long threads.
  • Include Thread Bodies: Whether to download full HTML/text of historical messages. Disable for faster fetches if you only need metadata.

Operations on the Send Mail Thread node

| Operation | What it does | | --------- | ------------ | | Send New Message | Plain SMTP send. Optional save to Sent. | | Send Reply in Thread | The flagship operation. Builds a single MIME, sends via SMTP with In-Reply-To + References, appends the same bytes to Sent, sets \Answered, optionally moves the original. | | Save Message to Sent | Append a raw RFC822 message (from a binary property or text) to Sent. | | Mark Message as Answered | Set \Answered flag by UID or Message-ID. | | Move Message to Folder | Move a message between IMAP folders. | | List Folders | Returns all folders with specialUse flags (useful for building dropdowns). |

Compatibility

  • n8n: tested on 1.x. Uses n8nNodesApiVersion: 1.
  • Node.js: >= 20.15.
  • Mail libraries: nodemailer ^8.0.7, imapflow ^1.3.2, mailparser ^3.9.8.

Local development

npm install
npm run build
npm link
# in your n8n custom dir:
mkdir -p ~/.n8n/custom
cd ~/.n8n/custom && npm link n8n-nodes-send-mail-thread
n8n start

Out of scope (v1)

  • OAuth2 / XOAUTH2 — only password auth for now
  • HTML signature templating — compose the body in another node (HTML Edit, AI, etc.)
  • Automated tests — manual testing on a real mailbox

License

MIT