
Why this, why now
I build products where automation buys back focus. The fastest “win” I’ve shipped for founders and PMs is an AI inbox triage: every time a feedback email lands, AI summarizes it, classifies it (Bug / Feature / Billing / General), extracts the contact, then alerts Slack and logs to Sheets. It’s the “hello world” of getting your time back.
This post shows the exact pattern I use again and again:
Trigger → AI → Parser → Actions
swap the trigger or actions and you’ve got lead scoring, ticket triage, invoice routing, onboarding… whatever your day throws at you.
What you’ll build
- Trigger: Gmail (Message Received) filtered to subjects like “Feature Request”
- AI: OpenAI turns messy text into a summary, category, and user_email
- Parser: forces clean, structured fields (no JSON.parse on camera)
- Actions:
- Post a formatted message to Slack (as a bot, not you)
- Append a row to Google Sheets
Result: new email → Slack ping + spreadsheet row — hands-free.
Prereqs (quick)
- n8n Cloud account (free trial works great)
- Gmail inbox you can connect
- Slack workspace where you can install an app
- Google account for Sheets
- OpenAI API key
Privacy note: we’ll use OAuth everywhere possible. Don’t paste secrets on screen.
Step 1 — Gmail Trigger (Message Received)
- In n8n, New workflow → add Gmail Trigger → Message Received.
- Authenticate with Google OAuth (name it “My Gmail”).
- Filter: Subject contains Feature Request (adjust to your flow).
- Click Test step. You should see fields like from, subject, bodyPlainText.
Why Gmail Trigger (not IMAP)? It’s simpler, more reliable on n8n Cloud, and faster to teach.
Step 2 — Make it smart with OpenAI (Chat)
Add OpenAI (Chat). Paste this prompt; it’s short, strict, and built for structured output.
You are an expert admin assistant.
Analyze the email and output ONLY valid JSON that matches the schema.
Email body: {{ $json.bodyPlainText }}
Sender: {{ $json.from }}
Fields:
- summary: 1–2 sentence summary of the user’s core request
- category: one of "Bug Report", "Feature Request", "Billing Question", "General Inquiry"
- user_email: if not in the body, use the sender
Return only the JSON object. No extra text.
- Model: a reliable GPT-4-class model
- Temperature: 0.2 (keeps structure consistent)
Pro tip: keep prompts boring and explicit for automation. Clever prompts are for demos; strict prompts are for production.
Step 3 — Enforce structure with Structured Output Parser
Add Structured Output Parser right after the OpenAI node and paste this schema:
{
"type": "object",
"properties": {
"summary": { "type": "string" },
"category": { "type": "string", "enum": ["Bug Report","Feature Request","Billing Question","General Inquiry"] },
"user_email": { "type": "string" }
},
"required": ["summary","category","user_email"],
"additionalProperties": false
}
Click Test step. You should see clean fields:
- summary
- category
- user_email
No string parsing, no regex spaghetti — just data.
Step 4 — Post to Slack (as a bot)
Add Slack → Post Message. Connect via OAuth (this makes the message come from your app, not your personal account).
Channel: #product-requests (or whatever you use)
Text:
🚀 *New AI-processed feedback*
*Summary:* {{$json.summary}}
*Category:* {{$json.category}}
*User:* {{$json.user_email}}
Hit Test step. Enjoy the ping.
If Slack errors with “missing scope,” add chat:write to your app, reinstall, reconnect in n8n, and test again. It’s the most common hiccup — fix is 30 seconds.
Step 5 — Log to Google Sheets (Append Row)
Add Google Sheets → Append. Connect your account, select spreadsheet + exact worksheet tab.
Map:
- Summary → {{$json.summary}}
- Category → {{$json.category}}
- User Email → {{$json.user_email}}
Test step → confirm the new row appears.
If nothing shows: double-check the tab name, sharing/permissions, and that you picked the right sheet. Then test again.
Step 6 — Full run & activate
Click Execute workflow (watch nodes glow green), then flip the Active toggle.
From now on, it runs 24/7 on n8n Cloud — you can close the tab and get back to shipping.
Upgrades you’ll want next
- Smart Routing: Add a Switch node after the Parser:
- category == "Bug Report" → post to #bugs
- category == "Feature Request" → post to #ideas
- category == "Billing Question" → post to #support
- PM Tool Auto-tickets: Replace Slack with Linear/Trello/Asana/Notion and map the same fields.
- Rate Limit: Add a Wait/Rate Limit node if you batch-import emails.
- Error Path: Create an Error Trigger that posts failure details to #ops.
- Cost Control: Use a smaller model for short messages, reserve bigger models for long/ambiguous ones.
- Versioning: Duplicate the workflow before big edits. Name versions with dates (future-you will thank past-you).
Troubleshooting (quick hits)
- Gmail Trigger isn’t firing: Activate the workflow and send a fresh test email; the trigger won’t backfill old messages.
- Slack message not posting: Wrong channel or missing scope; add chat:write, reinstall the app, then reconnect the credential.
- Sheets row missing: Wrong worksheet selected or sharing not granted; pick the exact tab and retry.
- AI returns extra text: That’s what the Structured Output Parser is for — it rejects non-JSON so you can tighten the prompt or reduce temperature.
Reuse the pattern everywhere
This tiny system is a template for dozens of jobs:
- Lead intake: Gmail/Forms → AI qualify → CRM + Slack
- Support triage: Helpdesk webhook → AI summarize → route by priority
- Invoice desk: Drive/Email → AI extract totals → Sheets + accounting tool
- Hiring intake: Careers inbox → AI tag role/seniority → ATS + Slack
Once you trust Trigger → AI → Parser → Actions, you’ll start seeing automation opportunities in every repetitive corner of your week.
Grab-and-go snippets
OpenAI Prompt
You are an expert admin assistant.
Analyze the email and output ONLY valid JSON that matches the schema.
Email body: {{ $json.bodyPlainText }}
Sender: {{ $json.from }}
Fields:
- summary: 1–2 sentence summary of the user’s core request
- category: one of "Bug Report", "Feature Request", "Billing Question", "General Inquiry"
- user_email: if not in the body, use the sender
Return only the JSON object. No extra text.
Structured Output Schema
{
"type": "object",
"properties": {
"summary": { "type": "string" },
"category": { "type": "string", "enum": ["Bug Report","Feature Request","Billing Question","General Inquiry"] },
"user_email": { "type": "string" }
},
"required": ["summary","category","user_email"],
"additionalProperties": false
}
Slack Message
🚀 *New AI-processed feedback*
*Summary:* {{$json.summary}}
*Category:* {{$json.category}}
*User:* {{$json.user_email}}
Final thought
You don’t need a team. You need a repeatable pattern and a couple of well-placed nodes.
Ship this once and you’ll never look at your inbox the same way again.
What’s the first repetitive task you’ll automate with n8n? Drop it in the comments or ping me — happy to help you turn it into a clean workflow.