chh-imap

Minimal IMAP node for n8n: UIDVALIDITY-checked UID operations, native UID MOVE with COPYUID, partial body sections, a total deadline per operation.

Package Information

Released: this month
Downloads: 0 weekly / 0 monthly
Latest Version: 0.1.0

Documentation

n8n-nodes-chh-imap

A minimal IMAP community node for n8n, built for a mail router that must never lose or silently duplicate a message.
It is small on purpose: six operations over imapflow (pinned), each with an explicit result
contract and a total deadline.

Operations

operation what it returns
Folder State per folder: uidValidity (decimal string), uidNext, exists; session capabilities move, uidplus
List UIDs every UID of a folder >= fromUid, ascending — never "first N"; a failed or malformed UID SEARCH is an error, never an empty list
Lookup one item per requested UID: found: true with size, envelope, flags (optionally BODYSTRUCTURE and raw header fields) or found: false
Fetch Part the first maxBytes encoded bytes of one body section (BODY.PEEK[section]<0.n+1>); truncated: true is proven by one extra byte; decoding is left to the caller
Fetch Source the whole raw message (base64) only when its size is known and within maxBytes (≤ 10 MB); otherwise tooLarge without downloading
Move native UID MOVE of one message; outcome: 'moved' only with a valid COPYUID mapping of exactly that UID, otherwise 'unconfirmed'

Guarantees

  • Generation check in the same session. Every operation on a UID requires the expected UIDVALIDITY and compares it with the folder's
    right after SELECT, before the UID is used. A mismatch is UIDVALIDITY_MISMATCH and nothing else happens.
  • Plain JSON out. BigInt becomes a decimal string, Map an array of pairs; nothing is serialised after a command has run.
  • No COPY+DELETE fallback. Without the MOVE capability the node refuses (MOVE_UNSUPPORTED).
  • Total deadline per operation (default 45 s, 1–300 s). On expiry the connection is closed and the operation fails with TIMEOUT;
    the remaining items of that node run are not attempted (CONNECTION_CLOSED). Closing stops the waiting — a command the server already
    accepted may still complete there.
  • commandSent on every Move error. false means the MOVE was certainly never handed to the IMAP client (validation, SELECT,
    generation, capability, deadline before sending); true means it may have reached the server.

What it does not guarantee

UID MOVE is not exclusive between sessions: on Dovecot 2.4.5 two sessions moving the same UID at the same moment both received
COPYUID and OK, and the message existed twice (most rounds of a 40-round test, maildir and sdbox). moved proves that this session
created a copy — never that it was the only one. Mutual exclusion has to come from the caller (a lock), not from IMAP.

Dovecot answers an empty string for a body section the message does not have, so take section numbers from BODYSTRUCTURE.

Errors

With On Error → Continue an error becomes an item { op, error: { code, message, details } } with the input's pairedItem;
otherwise the node throws CODE: message. Codes: BAD_UID, BAD_PATH, BAD_UIDVALIDITY, BAD_SECTION, BAD_LIMIT, BAD_HEADERS,
BAD_DEADLINE, BAD_OPERATION, BAD_CREDENTIAL, CONNECT_FAILED, CONNECTION_CLOSED, OPEN_FAILED, NOT_SELECTED,
UIDVALIDITY_MISMATCH, SEARCH_FAILED, FETCH_FAILED, PART_MISSING, MOVE_UNSUPPORTED, MOVE_FAILED, TIMEOUT.

⚠ When the result of a Move matters, make it the only item of its node run and turn Continue on — an error on a later item would
otherwise throw away the earlier result.

Credential

Uses n8n's built-in IMAP credential (user, password, host, port, SSL/TLS, allow self-signed certificates). Anyone who can edit a
workflow can attach any IMAP credential of the instance to this node — and this node moves mail.

Install

Settings → Community Nodes → Install → n8n-nodes-chh-imap. No install scripts; the only dependency is imapflow (exact version).

Tests

npm test runs the unit tests (fake client), the wrapper tests (fake IMAP servers that hang) and — when a local Dovecot is reachable
on 127.0.0.1:31143 — the integration tests:

docker run -d --name chh-dovecot-test -e USER_PASSWORD=testpass -p 127.0.0.1:31143:31143 dovecot/dovecot:latest

License

MIT

Discussion