Intermediate~20 min setupCommunication & EmailVerified April 2026
Slack logo
Gmail logo

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-time

Use case type

routing

Real-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.

/mo
505005K50K

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

Skip the setup

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.

Gmail account with full access to the support inbox — delegated access works if granted 'Manage' permissions, not just 'View'
Slack account with permission to add apps to your workspace — check with your Slack admin if you are not the workspace owner
n8n instance running on cloud (app.n8n.cloud) or self-hosted with a publicly accessible URL for OAuth callbacks
Gmail OAuth credential scoped to 'gmail.readonly' and 'gmail.modify' — readonly alone is not enough because you need to mark emails as read
Slack bot or OAuth token with 'chat:write' and 'channels:read' scopes — 'chat:write' is required to post messages to public channels

Field Mapping

Map these fields between your apps.

FieldAPI Name
Required
Gmail Message IDid
Sender Email Addresspayload.headers[name=From].value
Email Subjectpayload.headers[name=Subject].value
Email Body (Plain Text)payload.body.data
Email Received DateinternalDate
Slack Channel Target
Formatted Slack Message Text
1 optional field▸ show
Thread IDthreadId

Step-by-Step Setup

1

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.

  1. 1Click '+ New workflow' in the left sidebar
  2. 2Click the workflow title 'My workflow' at the top center of the canvas
  3. 3Type 'Gmail → Slack Support Routing' and press Enter
  4. 4Click 'Save' in the top-right corner
What you should see: You should see an empty canvas with your workflow title displayed at the top and a single gray 'Add first step' placeholder node in the center.
2

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.

  1. 1Click the gray 'Add first step' node
  2. 2Type 'Gmail' in the search field of the node panel
  3. 3Click 'Gmail' in the results list
  4. 4Select 'On Message Received' under the Triggers section
What you should see: A blue Gmail node labeled 'Gmail Trigger' appears on the canvas with a configuration panel open on the right side.
Common mistake — n8n's Gmail trigger uses OAuth polling, not a Gmail push notification. The minimum poll interval in n8n Cloud is 1 minute; self-hosted instances can go lower but Gmail's API has a default quota of 250 read units per second per user. Setting poll to under 1 minute on a busy inbox will burn quota fast.
n8n
+
click +
search apps
Slack
SL
Slack
Add the Gmail trigger node
Slack
SL
module added
3

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.

  1. 1Click the 'Credential' dropdown in the Gmail Trigger panel
  2. 2Select 'Create new credential'
  3. 3Click 'Sign in with Google' in the OAuth modal
  4. 4Select your support Google account from the account picker
  5. 5Click 'Allow' on the Google permissions screen
What you should see: The Credential field now shows your Google account email address with a green checkmark. The modal closes automatically.
Common mistake — You must authenticate with the exact Google account that owns the support inbox. Authenticating with a personal account and pointing the label filter at [email protected] will return zero results unless that inbox is delegated.
n8n settings
Connection
Choose a connection…Add
click Add
Slack
Log in to authorize
Authorize n8n
popup window
Connected
green checkmark
4

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.

  1. 1Scroll to the 'Filters' section in the Gmail Trigger panel
  2. 2Set 'Label' to 'INBOX'
  3. 3Click '+ Add filter' and select 'Search'
  4. 4Type: to:[email protected] is:unread
  5. 5Set 'Poll Times' to 'Every Minute' under the trigger schedule
What you should see: The Filters section shows Label = INBOX and Search = 'to:[email protected] is:unread'. The node is configured to poll every minute.
Common mistake — n8n marks emails as 'seen' after reading them only if you configure a subsequent Gmail node to do so. Without that step, the same email will re-trigger on every poll cycle — leading to duplicate Slack messages. You will handle this in Step 6.
Slack
SL
trigger
filter
Condition
matches criteria?
yes — passes through
no — skipped
Gmail
GM
notified
5

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.

  1. 1Click the '+' icon below the Gmail Trigger node
  2. 2Search for 'Code' in the node picker
  3. 3Select 'Code' and choose 'JavaScript' mode
  4. 4Click inside the code editor and select all existing placeholder code
  5. 5Paste the Pro Tip code from this guide
What you should see: The Code node appears on the canvas connected to the Gmail Trigger. The code editor shows your pasted JavaScript with no red syntax errors highlighted.
Common mistake — Gmail returns the email body as base64-encoded text in the 'payload.body.data' field. If you try to read the body directly without decoding it, you will get garbled output in Slack. The Pro Tip code handles this decoding — do not skip it.

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
  }
}];
message template
🔔 New Record: {{text}} {{user}}
channel: {{channel}}
ts: {{ts}}
#sales
🔔 New Record: Jane Smith
Company: Acme Corp
6

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.

  1. 1Click '+' below the Code node
  2. 2Search for 'Gmail' and select it
  3. 3Set the Action to 'Mark as Read'
  4. 4In the 'Message ID' field, click the expression toggle (the pill icon)
  5. 5Type: {{ $node["Gmail Trigger"].json.id }}
What you should see: The Gmail 'Mark as Read' node is connected in sequence after the Code node. Hovering over the Message ID field shows the resolved expression in the preview tooltip.
7

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.

  1. 1Click '+' after the Gmail 'Mark as Read' node
  2. 2Search 'Slack' and select it
  3. 3Set Action to 'Send a Message'
  4. 4Click 'Create new credential' under the Credential field
  5. 5Click 'Connect' and authorize n8n in the Slack OAuth window that opens
What you should see: The Slack node shows your workspace name in the Credential field with a green checkmark. The action is set to 'Send a Message'.
Common mistake — If your Slack workspace requires admin approval for new app installs, the OAuth flow will stall waiting for approval. Check with your Slack admin before starting this step — the credential modal times out after 5 minutes.
8

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 }}'.

  1. 1Set the 'Channel' field to '#support-tickets' (or your channel name)
  2. 2Click the expression toggle next to the 'Text' field
  3. 3Type: {{ $node["Code"].json.slackMessage }}
  4. 4Optional: Switch 'Message Type' to 'Block' for richer formatting
  5. 5If using Block: set Blocks field to {{ $node["Code"].json.slackBlocks }}
What you should see: The Channel field shows '#support-tickets' and the Text field shows the expression referencing your Code node output. The expression preview at the bottom of the panel shows example formatted text.
Common mistake — Slack channel names are case-sensitive in the n8n Slack node. '#Support-Tickets' and '#support-tickets' are different channels. If the channel name doesn't match exactly, the node will throw a 'channel_not_found' error rather than silently failing.
9

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.

  1. 1Right-click the Slack 'Send a Message' node
  2. 2Select 'Add node on error'
  3. 3In the new Slack node, set Channel to '#automation-errors' or your Slack user ID
  4. 4Set Text to: 'Support routing failed: {{ $json.message }} — check n8n workflow Gmail→Slack'
  5. 5Click 'Save' on the canvas
What you should see: A red error connector line runs from the Slack node to the new error-notification Slack node. The canvas shows both the main path and the error path as distinct colored lines.
10

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.

  1. 1Click the Gmail Trigger node to open its panel
  2. 2Click 'Fetch Test Event' at the bottom of the panel
  3. 3Wait for n8n to return an email sample — it appears as JSON in the 'Output' tab
  4. 4Click 'Execute Workflow' in the top toolbar to run all nodes with that test data
  5. 5Click each downstream node to verify its Output tab shows the expected data
What you should see: Each node in the workflow shows a green checkmark and a number badge indicating how many items passed through. The Slack channel receives a formatted test message.
Common mistake — The 'Fetch Test Event' button uses your live Gmail credentials and will actually mark the test email as read if you run the full workflow. Use a throwaway test email address as the sender so you do not accidentally mark a real customer email as read without replying.
n8n
▶ Run once
executed
Slack
Gmail
Gmail
🔔 notification
received
11

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.

  1. 1Confirm all nodes show green checkmarks from the test run
  2. 2Click 'Save' one final time before activating
  3. 3Click the gray 'Inactive' toggle in the top-right corner
  4. 4Confirm the toggle turns green and reads 'Active'
  5. 5Navigate to 'Executions' in the left sidebar to monitor live runs
What you should see: The workflow status badge shows 'Active' in green. Within 1–2 minutes of your next support email arriving, a Slack message appears in '#support-tickets'.

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

VerdictWhy n8n for this workflow

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

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.

Tradeoffs

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 routingExtend 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 SlackUse 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 SheetAdd 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

Was this guide helpful?
Slack + Gmail overviewn8n profile →