Bounces, opt-outs, and replies — classified every hour. No inbox babysitting.
An 11-node n8n workflow that watches two Gmail accounts. A code node labels each inbound message, updates the lead row, and writes bounced or opted-out addresses to the suppression list so the scraper cannot re-add them.
Missed bounces and ignored opt-outs are not “admin”
A bounce notification sits in the inbox until someone reads it. An “unsubscribe” reply sits next to it. If nobody updates the sheet, the follow-up workflow sends again — to a dead mailbox or to someone who already asked you to stop. That is a reputation problem and a compliance problem.
This page is the classifier only. It does not send mail. It writes bounced, replied, and suppression rows so the other outbound workflows can stay stateless.
One classifier. Instant sheet action.
Bounce
From mailer-daemon or postmaster, or subject contains delivery-failure language (undelivered, failure notice, returned mail, address not found, message blocked). Row: Status = Bounced, bounced = yes. Suppression reason = bounced.
Opt-out
Human reply whose subject or body matches 15+ removal phrases. Must not be a bounce. Row: replied = yes. Suppression reason = opt_out. No further contact.
Genuine reply
Not a bounce, not an opt-out, and not from Nick or David’s own addresses. Row: replied = yes. Follow-ups stop. A person picks up the conversation.
Anyone running dual-inbox outbound on a shared sheet
Teams that cannot staff inbox triage
Hourly polling on both accounts. You do not need someone to live in Gmail to keep the sheet honest.
Scrapers that must not re-hit the dead
Suppression is a second sheet the Maps workflows read before they write a new lead. That is the loop closing.
Subject and body. Both checked.
The published regex is matched against subject + body together. It covers direct removals and frustrated phrasing from the live write-up:
11 nodes. The hard part is the bounce body.
Two Gmail triggers, hourly
Nick’s inbox and David’s inbox. Any new message on either account fires the same classifier. Own-account receipts are excluded from the reply path.
Code node — type, lead_email, opt_out, from_email
Reads from, subject, and body (snippet + text + textPlain). Downstream nodes only route on those four fields.
Extract the lead address from a bounce
A bounce comes from mailer-daemon, not the prospect. The code pulls candidate emails from the body, drops own addresses and Google/mailer domains, and keeps the first remaining address. That is what gets suppressed — not postmaster@.
Has Lead Email, then route
If no lead email can be extracted, the item is dropped. Nothing is written for unmatchable system mail. Matched items update the leads sheet and, for bounce or opt-out, append the suppression sheet with reason and added_at.
A suppression list the scraper actually reads
Tracker stack
Gmail triggers ×2, one classification code node, Google Sheets (leads + suppression). The follow-up filters read replied and bounced. The Maps scrapers read the suppression list before they spend Claude on a row.
This build
Need inbox classification?
We walk bounce extract and suppression writeback on a call.
Get a proposalWrites to
The other seven in this portfolio
Bounce Tracker — short answers
Does this send or scrape anything?
How do you find the address inside a bounce?
What if the classifier cannot match a lead?
Does a genuine reply get suppressed?
Can this watch more than two inboxes?
Want both inboxes classified without a human sweep?
We will walk the 11-node canvas — hourly triggers, bounce extract, 15+ opt-out phrases, suppression writeback — on your Gmail accounts.