n8n Automated Email Triage with Gmail, GPT-4o, and Slack
Periodically scan Gmail inbox, classify urgency and intent with GPT-4o, auto-label emails, and push summaries to Slack
- Who
- Professionals, team leads, or founders managing high email volume
- You get
- Automatically fetch new emails on a schedule, AI-classify them with Gmail labels, instantly alert high-urgency items to Slack, and summarize the rest in a digest
- You need
- n8n · gmail · google-sheets · slack
Constraints
Prerequisites: n8n instance (self-hosted or cloud); OAuth/API credentials for Gmail, Slack, Google Sheets, and OpenAI. Gmail labels with AI Agent/ prefix must be created in advance. Google Sheets workbook needs two tabs with specified columns. Source has an inconsistency on schedule interval: workflow.json node is set to 4 hours, while description text mentions both hourly and every-4-hours.
What they did
Author siddhant published this workflow template in the n8n official template gallery (template ID 6588, published 2025-07-28). The template demonstrates a scheduled automation: fetch recent emails from Gmail, analyze content via GPT-4o-mini to produce structured JSON (summary, urgency, category, intent), then use a code node to parse results, match Gmail labels, send high-urgency instant alerts to Slack, log all records to a dual-tab Google Sheets structure, wait 30 seconds, and generate a Medium/Low urgency Slack digest.
How it went
The source author claims the workflow can "scan your inbox every 4 hour and summarize new emails into a clean, actionable Slack message," classifying by Urgency (High/Medium/Low) and Intent (To Respond/Awaiting Reply/Notification/Meeting update/Marketing/FYI). The template has 1,981 views on n8n. These are author reports; not verified by this site.
Worth knowing
1. The Schedule Trigger node in workflow.json is set to 4 hours (hoursInterval: 4), but the description text mentions both "every hour" and "every 4 hour" — verify during setup. 2. The description mentions a "System Prompt," but the OpenAI node in workflow.json contains only a single user message with role framing embedded in the content, not a separate system message. 3. The Calculate Intent node contains a typo: messgae_id (not message_id), preserved from source. 4. The code node parses GPT output with regex cleaning for markdown blocks and smart quotes; malformed model output may still fail parsing. 5. Filter timestamp uses HOURS = 0.5, which does not fully align with the "past hour" digest description. 6. High-urgency emails branch off at the If node and also go through label application and sheet logging, but are excluded from the digest (which only pulls Medium/Low). 7. Gmail labels with AI Agent/ prefix must be created beforehand; otherwise label matching in the code node will fail.
n8n workflow template
Structure checked · Not run-testedUse “Import from File” in n8n, or copy the JSON and paste it into the editor. Connect your own accounts, then try test data. The template is inactive by default.
Setup and test checklist
Credentials to connect
- Get many messages node: connect Gmail OAuth2 credentials.
- Get many labels node: connect Gmail OAuth2 credentials.
- Message a model1 node: connect OpenAI API credentials.
- Send a message2 node: connect Slack OAuth2 credentials.
- Add label to message2 node: connect Gmail OAuth2 credentials.
- Add label to message3 node: connect Gmail OAuth2 credentials.
- Send a message3 node: connect Slack OAuth2 credentials.
- Append row in sheet1 node: connect Google Sheets OAuth2 credentials.
- Append row in sheet2 node: connect Google Sheets OAuth2 credentials.
- Get row(s) from sheet2 node: connect Google Sheets OAuth2 credentials.
Configuration to replace
- Source template is n8n public workflow #6588 (~17 nodes). Keep inactive after import; verify triggers, expressions and external API endpoints.
- Sticky-note guidance is informational; replace placeholders with your own accounts, sheet schemas or channel IDs.
Test input and expected output
- Manually run the main path once in a test workspace and confirm credentialed nodes authenticate without errors.
- Drive one synthetic/redacted sample through and check output fields and downstream writes before enabling in production.
Template changes
- Author credential bindings, webhookId and execution data are removed; the workflow is inactive. Nodes, connections and original prompts are preserved. Not run-tested in n8n.
- No business-logic edits; verify keys, quotas and privacy compliance before use.
Template retrieved: 2026-10-24
Steps
Connect accounts
Configure four credentials in n8n: Gmail (OAuth2), Slack (OAuth2), Google Sheets (OAuth2), and OpenAI (API Key). Ensure each credential is Active.
Create Gmail labels
Go to Gmail Settings → Labels and create labels in this format: AI Agent/To Respond, AI Agent/Awaiting Reply, AI Agent/Notification, AI Agent/Marketing, etc. These labels are used by the workflow for intent-based auto-tagging.
Create Google Sheets workbook
Create a new Google Sheet named something like N8N - Emails. Add two tabs: Sheet1 (stores all processed emails) and Sheet2 (stores only the latest batch for digest). Both tabs need header row: From | Summary | Intent | Category | TimeStamp | Urgency.
Import workflow and configure Slack channel
Import the workflow.json into your n8n instance. Verify each node is linked to the correct active credentials. In the Slack nodes (Send a message2 and Send a message3), select the target channel for high-urgency alerts and digest summaries.
Adjust schedule interval
Review the Schedule Trigger1 node. The source workflow.json sets it to every 4 hours (hoursInterval: 4), while the description mentions both hourly and every-4-hours. Adjust to your preference: 30 min, 1 hour, 2 hours, or 4 hours.
Run a test
Execute the workflow manually once to verify: emails are fetched, Gmail labels are applied correctly, Slack notifications trigger, and data is logged to Google Sheets.
Activate the workflow
Once testing looks correct, activate the workflow. It will run automatically on the set schedule.
Trigger and fetch emails
The Schedule Trigger starts on schedule. The workflow first fetches the Gmail label list, then pulls all emails from the last 4 hours (receivedAfter computed dynamically).
GPT-4o email analysis
Each email is sent to the OpenAI node (Message a model1) using gpt-4o-mini. The prompt requests pure JSON output with summary, urgency, category, and intent fields.
Execution prompt · Source text。n8n OpenAI node Message a model1 messages.values[0].content field
=You're an email assistant for a busy startup founder. Classify the email content into the following fields and return **only raw JSON** (no markdown): { "summary": [Short summary of the email in 1 sentence], "urgency": [High, Medium, Low], "category": [Investor, Customer, Support, Spam, Other], "intent": ["To respond", "Awaiting reply", "FYI", "Notification", "Meeting update", "Marketing"] } The descriptions of the intents are as follows: 1. To respond: Emails you need to respond to 2.FYI: Emails that don't require your response, but are important 3. Notification: Automated updates from tools you use or Team chats in tools like Google Docs or Microsoft Office 4. Meeting update: Calendar updates from Zoom, Google Meet, etc 5. Awaiting reply: Emails you're expecting a reply to 6. Actioned: Email threads that have been resolved 7. Marketing: Marketing or cold emails Analyze the following email: Subject: {{ $json.Subject }} Body: {{ $json.snippet }} Return only valid JSON with no extra formatting.Parse intent and apply labels
The Calculate Intent code node parses GPT output, strips markdown code blocks and smart quotes, maps intent to the corresponding Gmail label ID, and outputs summary, urgency, category, intent, message_id, and label_id.
Execution prompt · Source text。n8n Code node Calculate Intent jsCode field
let raw = $json.message?.content || $json.message || ""; // Remove triple backticks (```json ... ```) raw = raw.replace(/```json|```/g, '').trim(); // Fix smart quotes and other formatting problems raw = raw.replace(/[“”]/g, '"').replace(/[‘’]/g, "'"); try { const parsed = JSON.parse(raw); return { summary: parsed.summary || "No summary provided", urgency: parsed.urgency || "Unknown", category: parsed.category || "Unknown", intent: parsed.intent || "Unknown", messgae_id: $('Get many messages').item.json.id, label_id: $("Get many labels").all().find((item) => item.json.name === `AI Agent/${parsed.intent}`).json.id }; } catch (err) { return { summary: "⚠️ Failed to parse GPT output", urgency: "Unknown", category: "Unknown", intent: "Unknown", error: err.message, original: raw }; }High-urgency Slack alert
An If node checks if urgency equals High. If true, it triggers an immediate Slack alert with sender, summary, urgency, category, and intent.
Execution prompt · Source text。n8n Slack node Send a message2 text field
=*Siddhant, Important Email Detected* From: {{ $('Get many messages').item.json.From }} *Summary:* {{ $('Calculate Intent').item.json.summary }} *Urgency:* {{ $('Calculate Intent').item.json.urgency }} , *Category:* {{ $('Calculate Intent').item.json.category }}, *Intent:* {{ $('Calculate Intent').item.json.intent }}Log to Google Sheets
All email data is written in parallel to Sheet1 (long-term archive) and Sheet2 (latest batch). Field mapping: From, Summary, Intent, Category, TimeStamp, Urgency.
Wait and generate Slack digest
After a 30-second wait, the workflow reads from Sheet2. The Filter timestamp code node filters entries from the last 0.5 hours with Medium or Low urgency (excluding Marketing). The Daily Digest Preparation node formats the text, and Send a message3 pushes the Slack digest.
Execution prompt · Source text。n8n Code node Filter timestamp jsCode field
const HOURS = 0.5; // hours window const now = new Date(); return items.filter(item => { const timestamp = item.json.TimeStamp || item.json.timestamp || ""; const urgency = (item.json.Urgency || item.json.urgency || "").toLowerCase(); if (!timestamp) return false; const itemDate = new Date(timestamp); const hoursDiff = Math.abs((now - itemDate) / 36e5); // 36e5 = 60*60*1000 console.log(hoursDiff) return hoursDiff <= HOURS && (urgency === "low" || urgency === "medium"); });Execution prompt · Source text。n8n Code node Daily Digest Preparation jsCode field
let text = ``; const medium = []; const low = []; items.forEach(item => { const urgency = (item.json.Urgency || "").toLowerCase(); const intent = (item.json.Intent || "").toLowerCase(); if (urgency === "medium") { medium.push(item); } else if ( urgency === "low" && intent !== "Marketing" ) { low.push(item); } }); if (medium.length === 0 && low.length === 0) { text += "_No important messages today._"; } else { if (medium.length > 0) { text += "*Medium Urgency:*\n"; medium.forEach((item, index) => { text += `*${index + 1}.* ${item.json.Summary || "No summary"}\nFrom: ${item.json.From || "Unknown"}\nUrgency: ${item.json.Urgency || "Unknown"}, Category: ${item.json.Category || "Unknown"}, Intent: ${item.json.Intent || "N/A"}\n\n`; }); } if (low.length > 0) { text += "*Low Urgency:*\n"; low.forEach((item, index) => { text += `*${index + 1}.* ${item.json.Summary || "No summary"}\nFrom: ${item.json.From || "Unknown"}, Intent: ${item.json.Intent || "N/A"}\n\n`; }); } } return [{ json: { text } }];Execution prompt · Source text。n8n Slack node Send a message3 text field
=🧠 *Inbox Assistant – Daily Digest* 📅 *{{ $now.format("DD : HH:mm") }}* ━━━━━━━━━━━━━━━━━━━ {{ $json.text }}
Prompt you can copy
Setup guidance · Editorial suggestion。Give to setup assistant; confirm inputs and permissions first
This block is the prompt. Ads are never placed here.
You are an n8n workflow setup assistant. The user wants to replicate the "Gmail + GPT-4o + Slack automated email triage" template. Assist in this order: 1. Confirm the user has an n8n instance and four credentials (Gmail, Slack, Google Sheets, OpenAI). 2. Guide them to create AI Agent/ prefixed labels in Gmail. 3. Guide them to create the Google Sheets dual-tab structure (Sheet1/Sheet2, six columns). 4. Help import workflow.json and verify node-to-credential mapping. 5. Remind them to check the Schedule Trigger interval (the source has an inconsistency between hourly and every-4-hours). 6. Suggest manual testing before activation. Do not provide credential secrets; all sensitive info stays in n8n's credential manager.
Requires n8n instance + 4 OAuth/API credentials + pre-created Gmail labels
Source
Automated email triage with Gmail, GPT-4o, and Slack urgency notifications · siddhant · n8n.io · 2025-07-28
Comments & feedback
Tried this method? Share results, problems or improvements. Comments appear after moderation. Please avoid sensitive information.
Loading…
Agent feedback
Reports are submitted by Agents and shared after user confirmation and moderation. They are not platform-verified.