{"slug": "the-inbox-autopilot-what-60-days-of-letting-an-n8n-workflow-triage-my-email-me", "title": "The Inbox Autopilot: What 60 Days of Letting an n8n Workflow Triage My Email Taught Me", "summary": "A developer built an n8n workflow that uses LLM classification and draft generation to triage 60–80 daily Gmail messages, saving roughly 35 minutes each morning over a 60-day production run. The workflow routes mail into five buckets (urgent, needs-reply, waiting-on-me, newsletter, noise) with a confidence gate that sends anything below 0.75 into a human-reviewed 'unsure' bucket, and never sends email automatically. Three failures shaped the design: synthetic few-shot examples misclassified a refund request as a newsletter, a single drafting prompt produced tonally wrong replies, and stripping quoted history caused a purchase confirmation to be filed as noise.", "body_md": "*This is part of my build-in-public series on running LLM workflows in n8n in production. Everything here is from a real template I sell and support â€” the mistakes are mine, the fixes are tested.*\n\nEvery morning I did the same thing: open Gmail, scan 60â€“80 new emails, decide what needed a reply, what could wait, and what was noise. It took 45 minutes on a good day. Not writing replies â€” just *deciding*. The triage, not the work.\n\nSo I built a workflow to do the deciding. A Gmail trigger, a classifier, a draft-reply generator, and a morning review. It's been running for 60 days. It now saves me about 35 minutes every morning. But the interesting part isn't the time saved â€” it's the three ways it failed, each of which taught me a rule I now apply to every classifier I build.\n\nGmail Trigger on new mail â†’ a Code node that strips signatures, disclaimers, and quoted history â†’ a classifier LLM call that assigns one of five buckets: `urgent`, `needs-reply`, `waiting-on-me`, `newsletter`, `noise` â†’ a confidence gate â†’ for `needs-reply`, a second LLM call drafts a reply in my voice â†’ drafts land in Gmail as *drafts*, never sent. Urgent gets a Slack/Telegram ping. Newsletters get auto-archived. The morning review is a Gmail search: `in:draft newer_than:1d`, five minutes, approve or edit.\n\nThe one hard rule: **the workflow never sends email.** Draft-only. That single constraint makes every other failure recoverable.\n\nWeek two, a customer wrote in with a refund request. Long email, polite tone, order number buried in paragraph three. The classifier filed it as `newsletter` with 0.91 confidence.\n\nWhy? My few-shot examples were synthetic â€” tidy little emails I wrote myself, each fitting its bucket perfectly. Real email is not tidy. The model learned \"polite + long = newsletter\" from my examples and confidently applied it.\n\nThe fix was to **throw away the synthetic examples and few-shot with my real email** â€” 40 actual messages, warts and all, including the ones where a refund request reads like a thank-you note. Accuracy on the tricky cases went from \"scary\" to \"boring.\" Synthetic examples teach the model a clean world that doesn't exist.\n\nClassification fixed, drafting began. The first week of drafts were grammatically fine and emotionally wrong. An annoyed customer got a cheerful \"Happy to help! ðŸŽ‰\" reply. A formal partner email got slang.\n\nThe problem: one system prompt for all drafts. The fix: **per-bucket tone templates**. The drafting prompt receives the bucket and a one-line voice card: `needs-reply-angry` â†’ \"acknowledge the frustration first, no exclamation marks, no emojis, state what happens next\"; `needs-reply-formal` â†’ \"use their name, sign with full signature.\" It's not fancy, but misfire rate on tone dropped to near zero. Voice is a parameter, not a personality.\n\nThis one cost me a customer interaction. Someone replied to an existing thread; the workflow classified the *single message* â€” \"Sounds good, let's do it\" â€” as `noise`. It was a purchase confirmation for a $79 custom service request. The purchase-confirmation context lived three messages up, which I'd stripped as \"quoted history\" to save tokens.\n\nLesson: **strip quoted history for classification, but fetch the thread for context when it matters.** Now the classifier gets the current message plus the last two messages of the thread (compressed), which costs ~300 extra tokens and catches every \"sounds good\" that actually means something. Token savings that break decisions aren't savings.\n\nEvery classification returns a confidence score. Below 0.75, the email goes into a sixth bucket: `unsure` â€” always shown to the human, never auto-filed. The `unsure` bucket gets 10â€“15% of mail, and that's *by design*: it's where the classifier admits ignorance instead of being confidently wrong. I'd rather review 12 emails than un-archive one misfiled refund.\n\nThis is the same pattern as the review-queue and retry-budget posts in this series: **the system's honesty about its own limits is the feature.** A classifier without an unsure bucket is a liar with good PR.\n\n~70 emails/day, classification at ~600 tokens each plus drafts for ~10 of them: about $0.40/day on GPT-4o-mini. The 35 minutes it saves me every morning would need to be worth $0.40. It is. The Gmail API is free, n8n is self-hosted, and the only real cost was the week I spent fixing the three failures above.\n\nTwo things deliberately stay human: the final send (I read every draft before it goes â€” the 5-minute morning review is the whole quality system), and the `unsure` bucket (which is a human inbox by another name). Everything else â€” reading, sorting, drafting, archiving â€” is the workflow's. That split has held for 60 days without an incident worth mentioning, which for an email automation is the highest praise I have.\n\n*I'm building [AI Automation Lab](https://payhip.com/haopengailab) â€” production-ready n8n workflow templates. The [AI Inbox Triage & Reply Drafter](https://payhip.com/b/W0mLE) is the full workflow from this article: the Gmail trigger, the classifier with real-email few-shots, the confidence gate, the per-bucket draft templates, and the morning-review setup. My open-source patterns live at [github.com/zhp910318/n8n-ai-automation-lab](https://github.com/zhp910318/n8n-ai-automation-lab).*", "url": "https://wpnews.pro/news/the-inbox-autopilot-what-60-days-of-letting-an-n8n-workflow-triage-my-email-me", "canonical_source": "https://dev.to/haopengai/the-inbox-autopilot-what-60-days-of-letting-an-n8n-workflow-triage-my-email-taught-me-8bn", "published_at": "2026-10-16 09:35:17+00:00", "updated_at": "2026-10-16 09:38:18.361475+00:00", "lang": "en", "topics": ["large-language-models", "ai-agents", "mlops", "ai-tools", "natural-language-processing"], "entities": ["n8n", "Gmail", "Slack", "Telegram"], "also_reported_by": [], "alternates": {"html": "https://wpnews.pro/news/the-inbox-autopilot-what-60-days-of-letting-an-n8n-workflow-triage-my-email-me", "markdown": "https://wpnews.pro/news/the-inbox-autopilot-what-60-days-of-letting-an-n8n-workflow-triage-my-email-me.md", "text": "https://wpnews.pro/news/the-inbox-autopilot-what-60-days-of-letting-an-n8n-workflow-triage-my-email-me.txt", "jsonld": "https://wpnews.pro/news/the-inbox-autopilot-what-60-days-of-letting-an-n8n-workflow-triage-my-email-me.jsonld"}}