

How to Route Gmail Support Emails to Slack with n8n
Polls a Gmail support inbox, extracts sender, subject, and body, then posts a formatted summary to a designated Slack channel so your team can coordinate responses internally.
Steps and UI details are based on platform versions at time of writing — check each platform for the latest interface.
Best for
Small support teams (2–15 people) who want internal Slack discussion before replying to customer emails, without buying a dedicated helpdesk tool.
Not ideal for
Teams handling 200+ support emails per day — at that volume, a real helpdesk like Zendesk or Linear handles assignment, SLAs, and threading natively.
Sync type
real-timeUse case type
routingReal-World Example
A 10-person B2B SaaS company routes all email sent to [email protected] into a private #support-tickets Slack channel. Before this workflow, the support alias sat in a shared Gmail inbox that three people checked inconsistently — emails went unanswered for 4–6 hours. Now every new email fires a Slack message within 2 minutes with the sender name, subject line, and first 300 characters of the body, and a team member claims it by reacting with an emoji before replying.
What Will This Cost?
Drag the slider to your expected monthly volume.
Each platform counts differently — Zapier: 1 task per trigger. Make: 1 operation per module per record. n8n: 1 execution per run.





Prices shown for annual billing. Based on published pricing as of April 2026.
Estimated ROI
1000
min saved/mo
$583
labor value/mo
Free
no platform cost
Based on ~2 min manual effort per operation at $35/hr fully loaded labor cost.
Implementation
Import this workflow directly into n8n
Copy the pre-built n8n blueprint and paste it straight into n8n. All modules, filters, and field mappings are already configured — you just need to connect your accounts.
Before You Start
Make sure you have everything ready.
Field Mapping
Map these fields between your apps.
| Field | API Name | |
|---|---|---|
| Required | ||
| Gmail Message ID | id | |
| Sender Email Address | payload.headers[name=From].value | |
| Email Subject | payload.headers[name=Subject].value | |
| Email Body (Plain Text) | payload.body.data | |
| Email Received Date | internalDate | |
| Slack Channel Target | ||
| Formatted Slack Message Text | ||
1 optional field▸ show
| Thread ID | threadId |
Step-by-Step Setup
n8n Canvas > + New workflow
Create a new workflow in n8n
Open your n8n instance (cloud at app.n8n.cloud or self-hosted). Click the orange '+ New workflow' button in the top-left of the canvas. Rename it immediately by clicking 'My workflow' at the top and typing 'Gmail → Slack Support Routing'. Saving the name now prevents confusion when you have multiple workflows running.
- 1Click '+ New workflow' in the left sidebar
- 2Click the workflow title 'My workflow' at the top center of the canvas
- 3Type 'Gmail → Slack Support Routing' and press Enter
- 4Click 'Save' in the top-right corner
Canvas > Add first step > Gmail > On Message Received
Add the Gmail trigger node
Click the gray 'Add first step' node on the canvas. In the node picker panel that opens on the right, type 'Gmail' in the search box. Select 'Gmail' and then choose 'On Message Received' as the trigger. This trigger polls Gmail on a schedule you define — it is not a push webhook, so there is an inherent delay between email arrival and trigger firing.
- 1Click the gray 'Add first step' node
- 2Type 'Gmail' in the search field of the node panel
- 3Click 'Gmail' in the results list
- 4Select 'On Message Received' under the Triggers section
Gmail Trigger Node > Parameters > Credential > Create new credential
Connect your Gmail account
In the Gmail Trigger configuration panel, click 'Create new credential' under the Credential field. A modal opens asking you to sign in with Google. Click 'Sign in with Google', choose the Google account that owns your support inbox, and grant n8n the requested Gmail read permissions. The credential is stored encrypted in n8n and reused across nodes.
- 1Click the 'Credential' dropdown in the Gmail Trigger panel
- 2Select 'Create new credential'
- 3Click 'Sign in with Google' in the OAuth modal
- 4Select your support Google account from the account picker
- 5Click 'Allow' on the Google permissions screen
Gmail Trigger Node > Parameters > Filters
Filter to support emails only
In the Gmail Trigger parameters, set 'Filters' to narrow which emails fire the trigger. Set 'Label' to 'INBOX' to catch all incoming mail, then add a custom filter in the 'Search' field using Gmail query syntax. Type 'to:[email protected] is:unread' — this ensures only unread emails addressed to your support alias trigger the workflow, ignoring sent items, spam, and already-read threads.
- 1Scroll to the 'Filters' section in the Gmail Trigger panel
- 2Set 'Label' to 'INBOX'
- 3Click '+ Add filter' and select 'Search'
- 4Type: to:[email protected] is:unread
- 5Set 'Poll Times' to 'Every Minute' under the trigger schedule
Canvas > + > Code > JavaScript
Add a Code node to format the message
Click the '+' connector below the Gmail Trigger node to add the next node. Search for 'Code' and select the Code node. This is where you parse the raw Gmail data and build the formatted Slack message. The Code node runs JavaScript and gives you full access to the email fields — sender, subject, date, and body snippet. Paste the transformation code from the Pro Tip section below into the JavaScript editor.
- 1Click the '+' icon below the Gmail Trigger node
- 2Search for 'Code' in the node picker
- 3Select 'Code' and choose 'JavaScript' mode
- 4Click inside the code editor and select all existing placeholder code
- 5Paste the Pro Tip code from this guide
Paste this into the Code node (Step 5). It decodes the base64 Gmail body, extracts the sender name separately from the email address, formats a human-readable timestamp, truncates the body to 300 characters, and builds both a plain-text Slack message and a Block Kit JSON object so you can choose either format in the Slack node.
JavaScript — Code Node// n8n Code Node — Gmail to Slack Support Routing▸ Show code
// n8n Code Node — Gmail to Slack Support Routing // Runs in 'Run Once for Each Item' mode const email = items[0].json;
... expand to see full code
// n8n Code Node — Gmail to Slack Support Routing
// Runs in 'Run Once for Each Item' mode
const email = items[0].json;
// --- 1. Decode base64 email body ---
let bodyText = '';
try {
const rawBody = email?.payload?.body?.data || '';
bodyText = rawBody
? Buffer.from(rawBody, 'base64').toString('utf-8').replace(/<[^>]+>/g, '').trim()
: '[No body content]';
} catch (e) {
bodyText = '[Body decode failed]';
}
// --- 2. Extract sender name and address separately ---
const fromHeader = (email?.payload?.headers || [])
.find(h => h.name === 'From')?.value || 'Unknown Sender';
const senderMatch = fromHeader.match(/^(.+?)\s*<(.+)>$/);
const senderName = senderMatch ? senderMatch[1].trim() : fromHeader;
const senderEmail = senderMatch ? senderMatch[2].trim() : fromHeader;
// --- 3. Extract subject ---
const subject = (email?.payload?.headers || [])
.find(h => h.name === 'Subject')?.value || '(No Subject)';
// --- 4. Format timestamp ---
const receivedMs = parseInt(email?.internalDate || Date.now(), 10);
const receivedDate = new Date(receivedMs).toLocaleString('en-US', {
month: 'short', day: 'numeric', year: 'numeric',
hour: '2-digit', minute: '2-digit', timeZoneName: 'short'
});
// --- 5. Truncate body to 300 chars ---
const bodyPreview = bodyText.length > 300
? bodyText.substring(0, 300) + '...'
: bodyText;
// --- 6. Build Gmail deep link ---
const gmailLink = `https://mail.google.com/mail/u/0/#inbox/${email.id}`;
// --- 7. Plain text Slack message ---
const slackMessage =
`🎫 *New Support Ticket*\n` +
`*From:* ${senderName} <${senderEmail}>\n` +
`*Subject:* ${subject}\n` +
`*Received:* ${receivedDate}\n` +
`*Preview:* ${bodyPreview}\n` +
`<${gmailLink}|View in Gmail>`;
// --- 8. Block Kit JSON for rich formatting ---
const slackBlocks = JSON.stringify([
{
type: 'header',
text: { type: 'plain_text', text: '🎫 New Support Ticket', emoji: true }
},
{
type: 'section',
fields: [
{ type: 'mrkdwn', text: `*From:*\n${senderName}` },
{ type: 'mrkdwn', text: `*Email:*\n${senderEmail}` },
{ type: 'mrkdwn', text: `*Subject:*\n${subject}` },
{ type: 'mrkdwn', text: `*Received:*\n${receivedDate}` }
]
},
{
type: 'section',
text: { type: 'mrkdwn', text: `*Preview:*\n${bodyPreview}` }
},
{
type: 'actions',
elements: [{
type: 'button',
text: { type: 'plain_text', text: 'View in Gmail' },
url: gmailLink,
action_id: 'view_gmail'
}]
}
]);
return [{
json: {
slackMessage,
slackBlocks,
senderName,
senderEmail,
subject,
receivedDate,
bodyPreview,
gmailLink,
messageId: email.id,
threadId: email.threadId
}
}];channel: {{channel}}
ts: {{ts}}
Canvas > + > Gmail > Mark as Read
Mark the email as read to prevent duplicates
Add a Gmail node (not the trigger — a regular action node) after the Code node. Set the action to 'Mark as Read' and pass in the message ID from the trigger output using the expression '{{ $node["Gmail Trigger"].json.id }}'. This tells Gmail to flag the email as read so the trigger won't pick it up again on the next poll cycle. Connect this node between the Code node and the Slack node.
- 1Click '+' below the Code node
- 2Search for 'Gmail' and select it
- 3Set the Action to 'Mark as Read'
- 4In the 'Message ID' field, click the expression toggle (the pill icon)
- 5Type: {{ $node["Gmail Trigger"].json.id }}
Canvas > + > Slack > Send a Message
Add the Slack node
Click '+' after the Mark as Read node and search for 'Slack'. Select the Slack node and set the action to 'Send a Message'. Connect your Slack workspace using 'Create new credential' — this opens a Slack OAuth flow where you authorize n8n to post messages. Choose the OAuth 2.0 option, not the Bot Token option, unless you have already created a Slack app with a bot token.
- 1Click '+' after the Gmail 'Mark as Read' node
- 2Search 'Slack' and select it
- 3Set Action to 'Send a Message'
- 4Click 'Create new credential' under the Credential field
- 5Click 'Connect' and authorize n8n in the Slack OAuth window that opens
Slack Node > Parameters > Channel / Text
Configure the Slack message content and channel
In the Slack node, set 'Channel' to the exact Slack channel name where tickets should appear — for example '#support-tickets'. In the 'Text' field, click the expression toggle and reference the output from your Code node. Use '{{ $node["Code"].json.slackMessage }}' to pull in the pre-formatted message block. If you want rich block formatting, switch 'Message Type' from 'Text' to 'Block' and reference '{{ $node["Code"].json.slackBlocks }}'.
- 1Set the 'Channel' field to '#support-tickets' (or your channel name)
- 2Click the expression toggle next to the 'Text' field
- 3Type: {{ $node["Code"].json.slackMessage }}
- 4Optional: Switch 'Message Type' to 'Block' for richer formatting
- 5If using Block: set Blocks field to {{ $node["Code"].json.slackBlocks }}
Slack Node > Right-click > Add node on error > Slack
Add an error notification node
Click the canvas background to deselect all nodes, then right-click the Slack node and select 'Add node on error'. Add another Slack node and point it to a private '#automation-errors' channel (or your personal DMs). Configure the text to include '{{ $json.message }}' so you see the actual error when something breaks. This ensures silent failures don't leave tickets unrouted.
- 1Right-click the Slack 'Send a Message' node
- 2Select 'Add node on error'
- 3In the new Slack node, set Channel to '#automation-errors' or your Slack user ID
- 4Set Text to: 'Support routing failed: {{ $json.message }} — check n8n workflow Gmail→Slack'
- 5Click 'Save' on the canvas
Gmail Trigger Node > Fetch Test Event > Execute Workflow
Test with a real email
Click the Gmail Trigger node and press 'Fetch Test Event' at the bottom of the panel. n8n will poll Gmail immediately and return the most recent unread email matching your filter. If the inbox is empty, send yourself a test email to [email protected] from a different address and wait 30 seconds, then retry. Once you have a test event, click 'Execute Workflow' to run all nodes manually and verify each output.
- 1Click the Gmail Trigger node to open its panel
- 2Click 'Fetch Test Event' at the bottom of the panel
- 3Wait for n8n to return an email sample — it appears as JSON in the 'Output' tab
- 4Click 'Execute Workflow' in the top toolbar to run all nodes with that test data
- 5Click each downstream node to verify its Output tab shows the expected data
Canvas > Top-right toggle > Active
Activate the workflow
Once the test run succeeds, click the toggle in the top-right corner of the canvas to switch the workflow from 'Inactive' to 'Active'. The toggle turns green and n8n begins polling Gmail on your configured schedule. You will see executions appear in the 'Executions' tab in the left sidebar as emails arrive. Set a reminder to check the error log after the first 24 hours in production.
- 1Confirm all nodes show green checkmarks from the test run
- 2Click 'Save' one final time before activating
- 3Click the gray 'Inactive' toggle in the top-right corner
- 4Confirm the toggle turns green and reads 'Active'
- 5Navigate to 'Executions' in the left sidebar to monitor live runs
Going live
Production Checklist
Before you turn this on for real, confirm each item.
Troubleshooting
Common errors and how to fix them.
Frequently Asked Questions
Common questions about this workflow.
Analysis
Use n8n for this if you want to avoid paying per-task fees as your support volume grows, or if you need to write custom body-parsing logic that a drag-and-drop tool cannot do cleanly. A support team getting 200 emails per month pays nothing extra on n8n Cloud's Starter plan — the same volume on Zapier at 2 Zaps per email (trigger + Slack) runs 400 tasks/month and hits the free tier ceiling fast. The one scenario where you should skip n8n: if your team has zero technical capacity and breaks, because n8n's error messages require you to understand what a base64-encoded string is. In that case, Zapier's pre-built Gmail-to-Slack template requires no code and is live in 8 minutes.
Cost math: each email arrival fires 3 n8n executions (Gmail Trigger, Code node, Gmail Mark as Read, Slack — but n8n counts this as one workflow execution). At 150 support emails per month, that is 150 executions. n8n Cloud's Starter plan includes 2,500 executions/month for $20/month. Self-hosted n8n is free beyond server costs (a $6/month DigitalOcean droplet handles this easily). Compare to Zapier: 150 emails × 3 Zap steps = 450 tasks/month, which stays under Zapier's free tier (100 tasks) only at very low volume — at 150 emails you are on the $19.99/month Starter plan. n8n self-hosted is cheaper by $20/month at this volume.
Make handles the Gmail body parsing with a built-in base64 decode function, which means you skip the Code node entirely — the whole workflow is 3 modules. Zapier has a native Gmail + Slack template that a non-technical user can copy and activate in 5 minutes, but it cannot decode base64 bodies without a Code by Zapier step. Power Automate has a Gmail connector, but it is clunky — most teams on Microsoft 365 use Outlook instead, where Power Automate is genuinely excellent. Pipedream gives you the cleanest code experience if you prefer Node.js with full npm access, and its Gmail source fires faster than n8n's polling. n8n is still the right call here if you want the control of code-based transformation plus a visual workflow editor, without committing to a JavaScript-only environment like Pipedream.
Three things you will hit after the first week: First, Gmail's 'From' header sometimes includes display names with quoted commas — 'Smith, John <[email protected]>' — which breaks naive string splitting. The Pro Tip code uses a regex match to handle this correctly. Second, very long email threads can have the body stored in 'payload.parts' as a multipart MIME structure rather than 'payload.body.data' directly — the code handles the simple case but you will need to recurse through parts for complex threads. Third, if your support inbox uses a Google Workspace account with strict OAuth app verification requirements, you may need to submit your n8n OAuth app for Google verification — this process takes 1–4 weeks and blocks the credential setup entirely until it is approved. Check your Google Workspace admin's OAuth app trust settings before starting.
Ideas for what to build next
- →Add keyword-based channel routing — Extend the Code node to inspect the email subject for keywords like 'billing', 'bug', or 'enterprise' and route to different Slack channels (#billing-support, #bug-reports) instead of a single channel. Add an n8n Switch node after the Code node with one branch per channel.
- →Post the reply back to Gmail from Slack — Use Slack's Interactivity features and an n8n Webhook node to capture when a team member clicks a 'Reply' button in the Slack message, then use the Gmail 'Reply to a Message' action to send the response back to the customer — all without leaving Slack.
- →Log every ticket to a Google Sheet — Add a Google Sheets node at the end of the workflow to append a row for each routed ticket with sender, subject, timestamp, and a 'Responded' column. This gives you a lightweight ticket tracker and lets you spot volume trends without a dedicated helpdesk tool.
Related guides
How to Share Notion Meeting Notes to Slack with Pipedream
~15 min setup
How to Share Notion Meeting Notes to Slack with Power Automate
~15 min setup
How to Share Notion Meeting Notes to Slack with n8n
~20 min setup
How to Send Notion Meeting Notes to Slack with Zapier
~8 min setup
How to Share Notion Meeting Notes to Slack with Make
~12 min setup
How to Create Notion Tasks from Slack with Pipedream
~15 min setup