Portal Community

Example 1: Basic Unread Email Trigger

Scenario: Fire a workflow for every new unread email arriving in the support mailbox. Create a CRM ticket from the email subject and body. This is the minimal configuration for an email-to-ticket workflow.

Node: IMAP Trigger
{
  "Host": "imap.gmail.com",
  "Port": 993,
  "User": "support@mycompany.com",
  "Password": "{{ secrets.SUPPORT_IMAP_PASSWORD }}",
  "Tls": true,
  "Mailbox": "INBOX",
  "CustomEmailConfig": ["UNSEEN"],
  "Format": "simple",
  "DownloadAttachments": false,
  "PostProcessAction": "read",
  "BatchSize": 20
}
Expected outcome: Each unread email in the support inbox triggers one workflow execution. The email is marked as read after processing (preventing re-triggering). Downstream nodes can access {{ nodes.imapTrigger.output.subject }}, {{ nodes.imapTrigger.output.from }}, and {{ nodes.imapTrigger.output.text }} to populate CRM fields.

Example 2: Filter by Sender and Date Range

Scenario: An accounts payable workflow should only trigger on invoices from a specific supplier email domain, received within the current month. All other emails in the INBOX should be ignored by this trigger.

Node: IMAP Trigger
{
  "Host": "outlook.office365.com",
  "Port": 993,
  "User": "accounts@mycompany.com",
  "Password": "{{ secrets.ACCOUNTS_IMAP_PASSWORD }}",
  "Tls": true,
  "Mailbox": "INBOX",
  "CustomEmailConfig": [
    "UNSEEN",
    "FROM", "billing@vendorcorp.com",
    "SINCE", "01-May-2026"
  ],
  "Format": "resolved",
  "DownloadAttachments": false,
  "PostProcessAction": "read",
  "BatchSize": 10
}
The resolved format is used here because the downstream CRM integration needs to distinguish the sender's display name from their email address. Access the sender address via {{ nodes.imapTrigger.output.from[0].Address }} and the display name via {{ nodes.imapTrigger.output.from[0].Name }}. The SINCE date filter uses the RFC 3501 date format: DD-Mon-YYYY.

Example 3: Download and Process Email Attachments

Scenario: An invoice processing workflow triggers on emails with attachments from any supplier, downloads the PDF attachments, and routes them to a FlowRag node for AI data extraction.

Node: IMAP Trigger
{
  "Host": "imap.gmail.com",
  "Port": 993,
  "User": "invoices@mycompany.com",
  "Password": "{{ secrets.INVOICES_IMAP_PASSWORD }}",
  "Tls": true,
  "Mailbox": "INBOX",
  "CustomEmailConfig": ["UNSEEN"],
  "Format": "simple",
  "DownloadAttachments": true,
  "AttachmentsBinaryPropertyPrefix": "invoice_attachment_",
  "PostProcessAction": "read",
  "BatchSize": 5
}
With DownloadAttachments: true, each email attachment is downloaded and exposed as a binary field. If an email has two attachments, they are accessible as invoice_attachment_0 and invoice_attachment_1. The attachment metadata (filename, MIME type, binary key) is in the attachments array: {{ nodes.imapTrigger.output.attachments[0].FileName }}. Pass the BinaryKey value (invoice_attachment_0) to downstream nodes that accept binary input. BatchSize is set to 5 to prevent large attachment downloads from overwhelming the workflow execution queue.

Example 4: Delete Emails After Processing

Scenario: A compliance mailbox receives notification emails from a third-party system. After each email is processed and its data extracted to a compliance database, the email is no longer needed and should be removed from the mailbox to prevent accumulation.

Node: IMAP Trigger
{
  "Host": "mail.mycompany.com",
  "Port": 993,
  "User": "compliance-notify@mycompany.com",
  "Password": "{{ secrets.COMPLIANCE_IMAP_PASSWORD }}",
  "Tls": true,
  "AllowUnauthorizedCerts": false,
  "Mailbox": "INBOX",
  "CustomEmailConfig": ["UNSEEN", "FROM", "notify@thirdpartysystem.com"],
  "Format": "simple",
  "DownloadAttachments": false,
  "PostProcessAction": "delete",
  "BatchSize": 50,
  "CommandTimeoutSeconds": 60
}
PostProcessAction: "delete" permanently removes the email from the IMAP server after the trigger fires. Ensure the workflow successfully extracts and stores the required data before this action runs. There is no undo. Consider using "read" instead during initial testing and only switching to "delete" once the downstream processing is verified stable. CommandTimeoutSeconds is increased to 60 here because this server handles high volumes and may be slower to respond.

Example 5: Parse CSV Attachment with CodeExecute

Scenario: A sales operations workflow receives a daily email from a partner system with a CSV file containing new lead data. The IMAP Trigger downloads the CSV, and a CodeExecute node parses it into structured records for CRM import.

Step 1 — IMAP Trigger: download the CSV attachment
{
  "Host": "imap.gmail.com",
  "Port": 993,
  "User": "leads@mycompany.com",
  "Password": "{{ secrets.LEADS_IMAP_PASSWORD }}",
  "Tls": true,
  "Mailbox": "INBOX",
  "CustomEmailConfig": [
    "UNSEEN",
    "FROM", "exports@partnersystem.com",
    "SUBJECT", "Daily Lead Export"
  ],
  "Format": "simple",
  "DownloadAttachments": true,
  "AttachmentsBinaryPropertyPrefix": "csv_",
  "PostProcessAction": "read",
  "BatchSize": 3
}
Step 2 — CodeExecute node: parse the CSV binary into JSON records
// Access the attachment info to get the binary key
const attachments = input.nodes.imapTrigger.output.attachments;
const csvAttachment = attachments.find(a => a.MimeType === "text/csv" || a.FileName.endsWith(".csv"));

if (!csvAttachment) {
  throw new Error("No CSV attachment found in email: " + input.nodes.imapTrigger.output.subject);
}

// The binary field key is stored in csvAttachment.BinaryKey (e.g. "csv_0")
const binaryKey = csvAttachment.BinaryKey;
const csvBuffer = input.binary[binaryKey];

// Decode the binary buffer to a UTF-8 string
const csvText = Buffer.from(csvBuffer.data, "base64").toString("utf8");

// Parse CSV lines into records
const lines = csvText.trim().split("\n");
const headers = lines[0].split(",").map(h => h.trim().replace(/^"|"$/g, ""));

const records = lines.slice(1).map(line => {
  const values = line.split(",").map(v => v.trim().replace(/^"|"$/g, ""));
  const record = {};
  headers.forEach((h, i) => { record[h] = values[i] || ""; });
  return record;
});

return {
  leadCount: records.length,
  leads: records,
  sourceEmail: input.nodes.imapTrigger.output.from,
  receivedDate: input.nodes.imapTrigger.output.date
};
Expected outcome: The CodeExecute node outputs a leads array of structured objects matching the CSV columns, along with a leadCount. A downstream Loop node iterates over leads and creates a CRM record for each entry. The sourceEmail and receivedDate fields are stored on each CRM record for audit purposes. The IMAP Trigger marks the email as read after firing, so the same CSV email will not re-trigger the workflow on the next poll.
Attachment binary key pattern: The binary key is always {AttachmentsBinaryPropertyPrefix}{index}. In this example, the prefix is "csv_", so the first attachment is at key "csv_0". The BinaryKey field in the attachment metadata object tells you exactly which key to use — always prefer reading it dynamically (as shown above) rather than hardcoding "csv_0", as email senders may occasionally include additional attachments before the CSV.