BDS0.1

Email Capture

Reads the sellers' e-mail copied to non-reply@, resolves the CRM context and records each e-mail; inactive until set up.

Reviewed 2026-11-06Markdown
Platform
n8n · Open in n8n
Status
Active
Workflow ID
SAyagoahreVjMNmE
Nodes
11
n8n version
8bd6ad9b-9bcf-4481-8878-2ae51a9b4d40
Last saved in n8n
2026-11-06T19:42:09.676Z

Email Capture keeps the record of e-mail between sellers and customers. Google Workspace copies every external e-mail sent or received by a member of the group sales-crm@snackprompt.com to the capture mailbox non-reply@snackprompt.com. This workflow reads those copies, finds the seller and the customer in the systems, and hands each e-mail to Communication — Record Email, which writes one Message in Communication and one Interaction per thread in the CRM. It then marks the e-mail in Gmail with a status label. It never creates a person and never deletes mail.

The workflow is active since 2026-11-06. Before activating keeps the setup checklist and what is still pending. It replaces the older Email Logging workflow, which needed one Gmail credential per seller.

The Communication maintainer owns the capture mailbox and the Message records; the CRM maintainer owns the Interactions and the follow-up rules; the Tooling and Access maintainer owns the Tool Account of each seller.

Flow

Generated from the n8n version in the box above: every box is a node and every arrow is a connection in n8n. Pink pills are triggers, yellow hexagons are If and Switch nodes with their outputs on the arrows, blue cylinders read (Airtable, Data Table, HTTP GET), green cylinders write, purple boxes call another workflow, and dashed arrows are error outputs.

Status labels

Resolve and record

Read the capture mailbox

true

false

error

Gmail Trigger

Config

List Labels

Normalize

Resolve CRM Context
CRM — Resolve Context

Known Person?

Record Email
Communication — Record Email

Label Registered

Label No Match

Label Error

Mermaid source
flowchart TD
  subgraph g0["Read the capture mailbox"]
    n1(["Gmail Trigger"]):::trigger
    n0["Config"]:::logic
    n6["List Labels"]:::logic
    n7["Normalize"]:::logic
  end
  subgraph g1["Resolve and record"]
    n9["Resolve CRM Context<br/><small>CRM — Resolve Context</small>"]:::subflow
    n2{{"Known Person?"}}:::decision
    n8["Record Email<br/><small>Communication — Record Email</small>"]:::subflow
  end
  subgraph g2["Status labels"]
    n5["Label Registered"]:::logic
    n4["Label No Match"]:::logic
    n3["Label Error"]:::logic
  end
  n1 --> n0
  n0 --> n6
  n6 --> n7
  n7 --> n9
  n9 --> n2
  n2 -->|true| n8
  n2 -->|false| n4
  n8 --> n5
  n8 -.->|error| n3
  classDef trigger fill:#fde7f3,stroke:#d6409f,color:#111
  classDef decision fill:#fff7e0,stroke:#c99a00,color:#111
  classDef read fill:#e8f1ff,stroke:#3b82f6,color:#111
  classDef write fill:#e7f8ee,stroke:#16a34a,color:#111
  classDef subflow fill:#f3e8ff,stroke:#9333ea,color:#111
  classDef wait fill:#f1f1f1,stroke:#888,color:#111
  classDef logic fill:#ffffff,stroke:#999,color:#111

Systems it touches

This workflow reads and writes no Airtable table itself. It reads Gmail and calls two sub-workflows that do the Airtable work.

System Through Reads Writes
Gmail (capture mailbox) Gmail Trigger, List Labels, Label nodes Labelled copies, label list Status labels on each copy
Tooling and Access, CRM CRM — Resolve Context Tool Account, Membership, People, Deal Nothing
Communication, CRM Communication — Record Email Message, Interaction, Person Message, Interaction

How the copies reach the mailbox

Two routing rules in the Google Workspace Admin Console copy mail for the members of sales-crm@: one for outbound mail, delivered to non-reply+crm-out@, and one for inbound mail, delivered to non-reply+crm-in@. The copy carries three headers: X-capture-source: external-contacts, X-capture-direction (outbound or inbound) and, on inbound copies, X-Gm-Original-To with the seller’s address. The customer’s copy carries none of them. Gmail filters in the capture mailbox label the copies CRM/CRM - Outbound and CRM/CRM - Inbound and skip the inbox. Mail between internal domains is not copied.

Trigger and configuration

The Gmail Trigger polls the capture mailbox every minute with the search deliveredto:non-reply+crm-out@snackprompt.com OR deliveredto:non-reply+crm-in@snackprompt.com (the same addresses the Gmail filters use), read and unread, and returns full messages with headers. Each new copy is one item.

Config sets five values that the later nodes read: mailbox (the capture address), internalDomains (comma-separated company domains), and the names of the three status labels: labelRegistered, labelNoMatch and labelError.

List Labels reads the label list of the mailbox once per run, so Normalize can turn the label names into the ids the Label nodes need.

What Normalize keeps

Value How it is set
Kept or dropped Dropped when X-capture-source is present and is not external-contacts, when the copy was not delivered to a +crm- address, or when the copy already carries the label CRM/CRM - Registered
Direction X-capture-direction; fallback: the +crm-out or +crm-in delivery address, then the From domain
Seller Outbound: the From address. Inbound: X-Gm-Original-To, then the first internal address in To or Cc. Dropped when no internal seller is found
Counterparty Inbound: the sender. Outbound: the first external address in To, then Cc. Dropped when internal or automated (no-reply, mailer-daemon, notifications)
External Cc The other external addresses in To and Cc
Internal participants The other internal addresses in To and Cc, without the seller
Message-ID, In-Reply-To From the headers, without the angle brackets
Subject, sent at, body, snippet Subject cut at 250 characters; the message date or the processing time; plain text cut at 20,000 characters; one line cut at 300 characters
Thread link https://mail.google.com/mail/u/0/#all/ plus the Gmail thread id of the capture mailbox
Label ids Ids of the three status labels, empty when a label does not exist

When every copy of a poll is dropped, the run ends at Normalize.

Resolve and record

Resolve CRM Context calls CRM — Resolve Context once per e-mail with the seller address, the counterparty address and name. It returns the seller’s Membership and company, the person, the person’s company and the open Deal, plus notes.

Known Person? sends the e-mail on only when a person was found in the CRM People mirror. Record Email then calls Communication — Record Email with the normalized e-mail and the context. That sub-workflow writes the Message and the Interaction and carries the tag email-log-n8n.

Status labels

Outcome Label Effect
Message and Interaction written CRM/CRM - Registered Done
Person not in the CRM People mirror CRM/CRM - No match Nothing written; review the person, then remove the label to reprocess
Record Email failed CRM/CRM - Error Remove the label and let the trigger pick the copy up again

The Label nodes add the label to the copy in the capture mailbox. When a label name in Config does not exist in Gmail, the Label node has no id to add and continues without error. No node removes labels, marks mail as read or deletes mail: the Interaction’s Evidence URL points to the thread in this mailbox.

Nodes

The workflow has 11 nodes: 10 that run and one sticky note. For an If node, output 0 is true and output 1 is false. Record Email has a second output for errors.

Node Type What it does
Gmail Trigger gmailTrigger Polls the capture mailbox every minute for the two capture labels
Config set Mailbox, internal domains and the three status label names
List Labels gmail Reads the label list once per run
Normalize code One item per capture copy; reads the capture headers; drops what is not a customer contact
Resolve CRM Context executeWorkflow Calls CRM — Resolve Context per e-mail
Known Person? if Continue only when the counterparty is a CRM person
Record Email executeWorkflow Calls Communication — Record Email; error output on failure
Label Registered gmail Adds CRM/CRM - Registered to the copy
Label No Match gmail Adds CRM/CRM - No match to the copy
Label Error gmail Adds CRM/CRM - Error to the copy
Sticky Note stickyNote Setup note on the canvas; does not run

Connections

From Output To
Gmail Trigger 0 Config
Config 0 List Labels
List Labels 0 Normalize
Normalize 0 Resolve CRM Context
Resolve CRM Context 0 Known Person?
Known Person? 0 Record Email
Known Person? 1 Label No Match
Record Email 0 Label Registered
Record Email 1 Label Error

Settings and error handling

Setting Value
Status Active since 2026-11-06
Execution order v1
Error workflow None
On error Record Email: continue on the error output. Label nodes: continue on the regular output. Other nodes: stop the workflow (default)
Sub-workflow calls One call per item, waiting for the result
Caller policy Workflows from the same owner
Execution data retention Instance default; this workflow sets none

Before activating

Step Where State at the last review
The Gmail Trigger, List Labels and the three Label nodes use the OAuth credential of non-reply@snackprompt.com n8n Done: all five use the credential no-reply mail
The labels CRM/CRM - Registered, CRM/CRM - No match and CRM/CRM - Error exist in the capture mailbox Gmail Done
The routing rules and the Gmail filters are in place and tested Google Workspace Configured; the five tests in the setup document are pending
Every member of sales-crm@ has a Tool Account (Google Workspace, Login Alias = e-mail) with an Identity Binding Tooling and Access Pending
The two sub-workflows exist and are reachable n8n Created, inactive; a sub-workflow does not need to be active to be called
The Channel of non-reply@ is Active Communication Done

Known gaps

These come from the node configuration and the Google setup.

Gap Effect
A customer only in Bcc of an outbound e-mail is not in the copy’s headers That e-mail gets no counterparty and is dropped
Only the first external address is the counterparty A message to several customers is recorded on one of them; the others go to Receivers (Person) or stay as cc: in About Keys
Mail between internal domains is not copied by Google Internal threads are never recorded, by design
“Today” and “plus three days” use the UTC date E-mail processed late at night in Brazil gets the next day
The thread link opens in the capture mailbox Only the mailbox admin can open the Evidence URL
Bounces are suppressed on the capture address A broken routing rule fails silently; Email Capture — Health Check covers this

Recover a partial write

What was saved What to do
Copy labelled CRM/CRM - Error Fix the cause, remove the label; the next poll reprocesses the copy and the sub-workflow updates in place
Copy labelled CRM/CRM - No match Create or find the person in Core, wait for the CRM mirror, remove the label
Message written, Interaction missing Remove the status label; Record Email updates the Message and creates the Interaction by thread link

Keep this page in sync

The box at the top shows the n8n version this page describes. Open the workflow in n8n: when its last save is newer than the date in the box, this page is out of date until the next review. Every node and every connection of that version is in Nodes and Connections.