212 Recruiter Replies Sorted by 8:55am: 6-Node n8n Agent

Monday, 8:47am. A recruiter I work with opens Gmail to 47 unread candidate replies from Friday's outreach batch. By Wednesday, 212 across the week. At four minutes each to read, classify, tag in the ATS, and decide next move — that's 14+ hours a week processing inbound. Not sourcing. Not interviewing. Not closing. Just reading and sorting.
Her ATS could send 500 sequenced outreach emails, but the moment a candidate hit reply, everything went manual. Every recruiting tool on the market sells you the front of the funnel. Nobody automates the reply inbox because replies are messy — a candidate might say yes, ask about salary, and mention vacation, all in one email. Classifiers hate that. So vendors avoid it. Which is exactly why it's the highest-leverage thing to automate right now.
Here's the 6-node n8n agent I built her, the failure modes I hit in week one, and the real numbers after four weeks in production.
The 6-node architecture in n8n
The whole system is a single linear workflow: Gmail trigger → preprocessor → classifier → Airtable log → Gmail label → Telegram digest. No branching, no sub-workflows, no vector store. That's deliberate. Every extra node is a place where the flow can silently fail at 3am and the recruiter walks into Monday blind.
Here's the node map:
| # | Node | Purpose | Runs |
|---|---|---|---|
| 1 | Gmail Trigger | Poll Outreach-Replies label every 5 min |
On schedule |
| 2 | Function (JS) | Strip quoted thread, extract sender + new reply text | Per message |
| 3 | OpenAI (GPT-4o-mini) | Classify intent → JSON | Per message |
| 4 | Airtable | Append row: sender, intent, confidence, snippet | Per message |
| 5 | Gmail | Apply label based on primary intent | Per message |
| 6 | Telegram (cron trigger + Airtable read) | Digest at 8:55am and 2:00pm | 2x/day |
The Gmail label Outreach-Replies is set up with a native Gmail filter — anything replying to her outreach alias (sara+outreach@agencydomain.com) auto-labels on arrival. n8n only sees pre-filtered mail. That single filter kills 80% of noise before a single API call fires.
Why you must strip quoted history before classifying
If you feed the entire email thread to GPT-4o-mini, it will read the recruiter's original outreach pitch and confuse it with the candidate's reply. In my first test batch of 40 emails, doing this misclassified 19 of them — the model kept latching onto the pitch language ("excited to share this opportunity") and marking candidate replies as interested when the actual reply said "please remove me."
Node two is a 15-line Function node that fixes this:
const raw = $input.item.json.textPlain || '';
// Cut at the first quoted-line marker Gmail inserts
const markers = [
/\nOn .+ wrote:/, // "On Mon, Jul 21 ... wrote:"
/\n-{2,}\s*Original Message/i,
/\nFrom: .+\nSent: /,
/\n>{1,}\s/ // fallback: quoted lines
];
let cutIdx = raw.length;
for (const m of markers) {
const match = raw.match(m);
if (match && match.index < cutIdx) cutIdx = match.index;
}
const clean = raw.slice(0, cutIdx).trim();
return {
json: {
sender: $input.item.json.from,
subject: $input.item.json.subject,
reply_text: clean.slice(0, 2000) // cap tokens
}
};
The 2000-char cap keeps input tokens bounded. Real candidate replies are 30-400 characters. Anything longer is almost always a forwarded thread we already trimmed poorly, and truncating protects the API bill.
The classifier prompt (and why the secondary flag matters)
Node three is a single call to GPT-4o-mini with a strict JSON schema. Five intent classes: interested, decline, question, scheduling, spam. The model returns primary intent, confidence 0–1, and a secondary flag field.
That secondary flag is the whole trick. In week one, 8% of replies were multi-intent — "I'm interested, what's the salary band?" If you force single-class, you either lose the interest signal or lose the salary question. Both cost you the candidate.
You are classifying a candidate's reply to a recruiter's outreach.
Return ONLY valid JSON:
{
"primary": "interested|decline|question|scheduling|spam",
"secondary": "interested|decline|question|scheduling|spam|null",
"confidence": 0.0-1.0,
"one_line_summary": "max 90 chars"
}
Rubric:
- interested: wants to move forward, no blockers stated
- decline: clear no, remove me, not a fit, not interested
- question: needs info before deciding (salary, remote, scope, visa)
- scheduling: agreed to talk, proposing or confirming times
- spam: auto-replies, out-of-office, vacation autoresponders,
unrelated marketing, bounce notifications
Rules:
1. If the reply contains two distinct intents, put the stronger
ACTION signal in primary and the other in secondary.
Example: "Yes I'm interested, what's the salary?"
-> primary: interested, secondary: question
2. Out-of-office / vacation autoresponders ALWAYS = spam,
even if the text says "I won't be available" or "I'm away".
3. If confidence < 0.75, still return your best guess.
The downstream system will flag for human review.
Reply text:
"""{{ $json.reply_text }}"""
Two rules in that prompt exist because of specific failures I watched happen. Rule 2 was added after out-of-office autoresponders ("I won't be available until Aug 4") kept getting labeled decline. Rule 1 pushed multi-intent accuracy from 62% (week one) to 89% (week two).
Anything below 0.75 confidence gets flagged for human review regardless of class. question and scheduling always route to the recruiter within the day even at high confidence — those two need a human response fast or the candidate goes cold.
The Telegram digest that replaces 40 Gmail refreshes
Node six is where the recruiter actually gets her time back. It runs on cron at 8:55am and 2:00pm, queries Airtable for everything logged since the last digest, groups by intent, and sends a formatted message to her phone.
Sample digest from a real Monday:
📬 Reply digest — Mon 8:55am
Window: Fri 2pm → Mon 8:50am
🟢 Interested (4)
• Marcus T. — "yes, happy to chat this week"
• Priya S. — "sounds relevant, send details"
• Jordan K. — "interested, currently on notice"
• Elena R. — "yes let's talk"
📅 Scheduling (2)
• David L. — "Tue 3pm ET works"
• Aisha M. — "Wed or Thu after 2pm PT"
❓ Question (7)
• salary band: 3
• remote policy: 2
• role scope: 2
🔴 Decline (31) 🚫 Spam (3)
⚠️ Low confidence (2) — check Airtable
She reads this on her phone over coffee. She knows before opening her laptop that her day is 4 interested + 2 scheduling + 7 questions = 13 replies that need her. The 31 declines and 3 spam are already labeled in Gmail; she'll batch-archive them at end of day. That's the entire point: Gmail sidebar becomes a triage board, not an infinite scroll.
The Airtable schema is boring on purpose:
sender_email,sender_name,subjectsnippet(90 chars from classifier)primary_intent,secondary_intent,confidencegmail_message_id,timestampsent_to_digest(bool, flipped true after digest ships)
That last column is what makes the twice-daily digest idempotent. If the workflow crashes mid-send, the next run picks up exactly where it left off.
The two failure modes that broke week one
Two things went wrong in the first week that would have killed the whole system if I hadn't caught them:
- Multi-intent replies destroyed accuracy. Classifier hit 92% on single-intent, 62% on multi-intent. Fix: added the
secondaryfield to the JSON schema, rewrote the prompt with the "stronger action signal in primary" rule, and shipped rule-1 above. Multi-intent accuracy jumped to 89% in week two. - Autoresponders classified as declines. "I won't be available" and "I am out of the office until…" kept getting tagged
decline. Fix: three lines in the prompt with explicit autoresponder patterns, forced tospam. Zero misclassifications on autoresponders in weeks 2–4.
The confidence gate (< 0.75 → human review) catches whatever the prompt still misses. Over four weeks, roughly 6% of replies landed in the low-confidence bucket. The recruiter reviews those in one 5-minute pass at end of day.
One thing I'd flag if you're building this yourself: don't skip the Airtable log. It's tempting to go Gmail → Classifier → Label → Telegram and cut Airtable. Don't. Without the log, you have no way to audit misclassifications, tune the prompt, or answer the question "did the agent process that reply from Marcus on Tuesday?" It's the difference between a black box and a system you can actually improve.
Real numbers after 4 weeks in production
Measured, not estimated. She kept before-and-after time tracking in Toggl.
| Metric | Before | After 4 weeks |
|---|---|---|
| Replies processed / week | 212 avg | 212 avg |
| Recruiter time on inbound | 14.1 hrs/wk | 1.3 hrs/wk |
| Gmail opens / day | ~40 | 2 (post-digest) |
Avg reply time to interested |
6.2 hrs | 47 min |
Avg reply time to scheduling |
4.1 hrs | 22 min |
| Classification accuracy | — | 94% overall, 89% multi-intent |
| OpenAI API cost | — | $0.87/week at GPT-4o-mini pricing |
| n8n hosting | — | $20/mo self-hosted on a $6 VPS + Cloudflare tunnel |
$0.87/week to reclaim 12.8 hours of a $95/hr recruiter's time. That math doesn't need explaining.
Two months in, she still opens Gmail twice a day. Not forty.
Where bizflowai.io fits in
Most of what I build for recruiting and sales clients at bizflowai.io is exactly this shape — inbound-side automation that the vendor stack refuses to touch. ATS platforms, sales engagement tools and CRMs all optimize outbound because it's clean and structured. The reply inbox is where the actual leverage sits, and it's where I spend most client engagements: reply classification, digest routing, follow-up scheduling, and clean handoffs from AI to human at the exact confidence threshold that keeps you from losing candidates. If you already have outreach running and the reply volume is drowning you, that's the highest-ROI thing to fix first.
Want more like this?
I publish practical AI automation, GenAI engineering, and faceless content workflows on YouTube every week.
Subscribe to bizflowai.io on YouTube — never miss a new tutorial.
Planning an AI automation project or need a second opinion on your architecture?
Connect with me on LinkedIn — Lazar Milicevic, GenAI Engineer & bizflowai.io Founder.
Visit bizflowai.io for our services, case studies, and AI consulting.
Frequently asked questions
What is recruiter reply inbox automation with n8n?
It's a six-node n8n workflow that automatically processes candidate email replies to recruiting outreach. A Gmail trigger pulls new replies, a preprocessor cleans thread history, GPT-4o-mini classifies intent into five categories (interested, decline, question, scheduling, spam), Airtable logs results, Gmail labels are applied for triage, and Telegram sends twice-daily digests summarizing what needs attention.
Why automate the reply inbox instead of outreach?
Most recruiting tools automate outbound (sourcing, screening, scheduling) but leave replies fully manual. A recruiter processing 212 weekly replies at four minutes each spends over 14 hours just reading and sorting. Vendors avoid it because replies are unstructured and multi-intent, but that's exactly what makes reply automation the highest-leverage workflow to build right now.
How do I classify multi-intent candidate replies accurately?
Use a classifier prompt that returns both a primary intent and a secondary flag field. Around 8% of replies are multi-intent, like 'interested, what's the salary band.' Forcing single-class loses critical information. Also include a confidence score; anything below 0.75 gets flagged for human review, and question or scheduling intents always route to a human regardless of confidence.
Why strip quoted thread history before classifying replies?
If you feed the entire email thread to the classifier, it confuses the recruiter's original outreach pitch with the candidate's actual reply and misclassifies roughly half of them. A preprocessing node should strip quoted history, keep only the new reply text, and extract the sender email and subject line before sending anything to the LLM.
When should replies route to a human versus stay automated?
Route to a human whenever confidence is below 0.75, regardless of intent class. Also always route 'question' and 'scheduling' intents to the recruiter even at high confidence, because both require a human response within the day. 'Decline' and 'spam' can be labeled and archived automatically, while 'interested' entries appear in the Telegram digest for review.