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

How to Broadcast Gmail Project Updates to Slack with n8n

Polls Gmail for labeled project emails and posts the sender, subject, and a trimmed body excerpt to the matching Slack channel automatically.

Steps and UI details are based on platform versions at time of writing — check each platform for the latest interface.

Best for

Distributed project teams who need external emails — vendor replies, client feedback, stakeholder updates — visible in Slack without anyone forwarding manually.

Not ideal for

Teams receiving 200+ project emails per day; at that volume, digest batching in Make is cheaper and less noisy.

Sync type

scheduled

Use case type

notification

Real-World Example

💡

A 22-person product agency manages six active client projects. Client emails land in a shared Gmail inbox and get manually forwarded to Slack by whoever notices them first — which often means a 3-6 hour lag. With this workflow, any email tagged with a project label (e.g. 'Project-Orion') posts to #proj-orion within 5 minutes of arrival, including the sender name, subject line, and first 300 characters of the body. The team stopped missing vendor deadline changes within the first week.

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 OAuth2 access enabled in Google Cloud Console (scopes: gmail.readonly, gmail.modify)
Slack workspace admin access or permission to install apps and invite bots to channels
n8n instance running (cloud or self-hosted v1.0+) with Gmail and Slack nodes available
Gmail labels created for each project before building the workflow (names must match exactly what you'll reference in the Switch node)
Slack channel IDs collected for each project channel (right-click channel > Copy link > extract last URL segment)

Field Mapping

Map these fields between your apps.

FieldAPI Name
Required
Email Message ID
Subject Line
Sender Email and Name
Email Body (trimmed)
Label IDs
Slack Channel ID
2 optional fields▸ show
Received Timestamp
Email Thread ID

Step-by-Step Setup

1

Gmail > Settings > Labels > Create new label

Create Gmail Labels for Each Project

Before building anything in n8n, set up one Gmail label per project (e.g. 'Project-Orion', 'Project-Atlas'). Open Gmail, click the gear icon top-right, go to 'See all settings', then the 'Labels' tab. Scroll to the bottom and click 'Create new label'. You'll apply these labels manually or via Gmail filters — the n8n workflow reads them to decide which Slack channel to post to.

  1. 1Open Gmail and click the gear icon (top-right)
  2. 2Click 'See all settings'
  3. 3Select the 'Labels' tab
  4. 4Scroll to the bottom and click 'Create new label'
  5. 5Type the label name (e.g. 'Project-Orion') and click 'Create'
What you should see: The new label appears in the left sidebar of Gmail under 'Labels' and in your Labels settings list.
Common mistake — Label names are case-sensitive in the Gmail API. 'Project-Orion' and 'project-orion' are different labels. Pick a consistent naming convention before building the workflow — changing labels later breaks the n8n filter.
2

n8n Dashboard > Workflows > + New workflow

Create a New Workflow in n8n

Log into your n8n instance (cloud at app.n8n.io or self-hosted). Click the '+ New workflow' button in the top-left of the Workflows dashboard. Give it a clear name like 'Gmail → Slack Project Broadcasting'. You'll land on the canvas with an empty workflow ready for nodes.

  1. 1Log into your n8n instance
  2. 2Click '+ New workflow' in the top-left
  3. 3Click the workflow name at the top and rename it to 'Gmail → Slack Project Broadcasting'
  4. 4Click anywhere on the canvas to deselect
What you should see: You see an empty workflow canvas with the workflow name showing at the top of the screen.
3

Canvas > + > Gmail > Gmail Trigger

Add the Gmail Trigger Node

Click the '+' button in the center of the canvas to open the node panel. Search for 'Gmail' and select it. Choose 'Gmail Trigger' as the node type. This node polls Gmail on a schedule — you'll configure it to check every 5 minutes. Set the 'Polling Times' field to '*/5 * * * *' (every 5 minutes). Under 'Filters', set 'Label' to the first project label you created (e.g. 'Project-Orion').

  1. 1Click the '+' button on the canvas
  2. 2Search for 'Gmail' in the node search box
  3. 3Select 'Gmail Trigger'
  4. 4In the 'Polling Times' field, enter '*/5 * * * *'
  5. 5Under 'Filters > Label', type your project label name exactly as created in Gmail
What you should see: The Gmail Trigger node appears on the canvas with a clock icon indicating polling mode. You'll see the label filter listed in the node summary panel.
Common mistake — The Gmail Trigger only watches ONE label per node. If you have five projects, you need five separate trigger nodes or one trigger on a parent label. Using a parent label (e.g. 'Projects') and then routing by sub-label in a Switch node is the cleaner approach for 3+ projects.
n8n
+
click +
search apps
Slack
SL
Slack
Add the Gmail Trigger Node
Slack
SL
module added
4

Gmail Trigger Node > Credential for Gmail API > Create new credential

Connect Gmail Credentials

Click 'Credential for Gmail API' inside the trigger node and select 'Create new credential'. n8n will prompt you to authenticate via OAuth2. Click 'Sign in with Google', choose the Google account that owns the Gmail inbox, and grant the requested scopes (read mail, modify mail). After authentication, the credential name appears in the dropdown.

  1. 1Click the 'Credential for Gmail API' dropdown
  2. 2Select 'Create new credential'
  3. 3Click 'Sign in with Google'
  4. 4Choose the correct Google account
  5. 5Click 'Allow' on the permissions screen
What you should see: The credential dropdown shows your new credential name (usually the Gmail address). The node no longer shows a red credential error badge.
Common mistake — If you're self-hosting n8n, your OAuth redirect URI must be whitelisted in Google Cloud Console as 'https://your-n8n-domain.com/rest/oauth2-credential/callback'. Cloud n8n handles this automatically.
5

Canvas > + > Code

Add a Code Node to Parse and Trim the Email Body

Click the '+' after the Gmail Trigger node and add a 'Code' node. This node strips HTML from the email body and trims it to 300 characters — raw Gmail API bodies include encoded HTML that looks broken in Slack. Paste the JavaScript below into the code editor. Set the 'Mode' dropdown to 'Run Once for Each Item'.

  1. 1Click '+' after the Gmail Trigger node
  2. 2Search for 'Code' and select it
  3. 3Set 'Mode' to 'Run Once for Each Item'
  4. 4Paste the transformation code into the editor (see pro_tip_code below)
  5. 5Click 'Execute node' to test with live Gmail data
What you should see: The output panel shows a 'cleanBody' field with plain text, no HTML tags, truncated to 300 characters with an ellipsis if longer.
Common mistake — Gmail sometimes sends emails with only a 'text/html' part and no 'text/plain' fallback. If 'cleanBody' returns empty, check that your regex is stripping HTML correctly — the pro tip code handles both cases.

Paste this into the Code node (Step 5) set to 'Run Once for Each Item' mode. It decodes the base64 Gmail body, strips HTML, trims to 300 chars, resolves the label ID to a Slack channel ID, and builds the Gmail deep link — all in one pass so you don't need separate transformation nodes.

JavaScript — Code Node// n8n Code Node — Gmail body parser + label-to-channel resolver
▸ Show code
// n8n Code Node — Gmail body parser + label-to-channel resolver
// Mode: Run Once for Each Item
// Place after Gmail Trigger, before Switch node

... expand to see full code

// n8n Code Node — Gmail body parser + label-to-channel resolver
// Mode: Run Once for Each Item
// Place after Gmail Trigger, before Switch node

const item = $input.item.json;

// --- 1. Label ID → Slack Channel ID lookup map ---
// Replace these with your actual Gmail label IDs and Slack channel IDs
const labelChannelMap = {
  'Label_3872910456': 'C04ORION123',  // Project-Orion → #proj-orion
  'Label_4921037281': 'C04ATLAS456',  // Project-Atlas → #proj-atlas
  'Label_5034829174': 'C04HERMES789', // Project-Hermes → #proj-hermes
};

// --- 2. Resolve Slack channel from label IDs ---
const labelIds = item.labelIds || [];
let slackChannelId = null;
for (const labelId of labelIds) {
  if (labelChannelMap[labelId]) {
    slackChannelId = labelChannelMap[labelId];
    break;
  }
}

// --- 3. Extract and decode email body ---
// Gmail API returns body as base64url-encoded string
let rawBody = '';
try {
  // Try text/plain part first
  const parts = item.payload?.parts || [];
  const plainPart = parts.find(p => p.mimeType === 'text/plain');
  const htmlPart = parts.find(p => p.mimeType === 'text/html');
  
  const bodyData = plainPart?.body?.data 
    || htmlPart?.body?.data 
    || item.payload?.body?.data 
    || '';
  
  if (bodyData) {
    // Decode base64url to string
    rawBody = Buffer.from(bodyData.replace(/-/g, '+').replace(/_/g, '/'), 'base64').toString('utf-8');
  } else {
    // Fallback: use snippet from Gmail trigger
    rawBody = item.snippet || '';
  }
} catch (e) {
  rawBody = item.snippet || '[Body unavailable]';
}

// --- 4. Strip HTML tags if body is HTML ---
const cleanBody = rawBody
  .replace(/<style[\s\S]*?<\/style>/gi, '')
  .replace(/<script[\s\S]*?<\/script>/gi, '')
  .replace(/<[^>]+>/g, ' ')
  .replace(/&nbsp;/g, ' ')
  .replace(/&amp;/g, '&')
  .replace(/&lt;/g, '<')
  .replace(/&gt;/g, '>')
  .replace(/\s+/g, ' ')
  .trim()
  .substring(0, 300);

const bodyExcerpt = cleanBody.length === 300 ? cleanBody + '...' : cleanBody;

// --- 5. Format received timestamp ---
const receivedDate = item.internalDate 
  ? new Date(parseInt(item.internalDate)).toLocaleString('en-US', {
      month: 'short', day: 'numeric', year: 'numeric',
      hour: 'numeric', minute: '2-digit', hour12: true
    })
  : 'Unknown time';

// --- 6. Build Gmail deep link ---
const gmailLink = `https://mail.google.com/mail/u/0/#inbox/${item.id}`;

// --- 7. Build Slack message text ---
const slackText = [
  `*New email: ${item.subject || '(no subject)'}*`,
  `From: ${item.from || 'Unknown sender'}`,
  `Received: ${receivedDate}`,
  '',
  bodyExcerpt,
  '',
  `<${gmailLink}|Open in Gmail>`
].join('\n');

// --- 8. Return enriched item ---
return {
  json: {
    ...item,
    slackChannelId,
    cleanBody: bodyExcerpt,
    receivedDate,
    gmailLink,
    slackText,
    routingResolved: slackChannelId !== null,
  }
};
6

Canvas > + > Switch

Add a Switch Node to Route by Project Label

Click '+' after the Code node and add a 'Switch' node. This routes each email to the correct Slack channel based on its Gmail label. Set 'Mode' to 'Rules'. Add one rule per project: set the condition to 'String > Contains' and check '{{ $json.labelIds }}' against the label name (e.g. 'Project-Orion'). Each rule gets its own output branch.

  1. 1Click '+' after the Code node
  2. 2Search for 'Switch' and select it
  3. 3Set 'Mode' to 'Rules'
  4. 4Click 'Add Rule'
  5. 5Set condition: Value 1 = '{{ $json.labelIds.join(",") }}', Operation = 'Contains', Value 2 = 'Project-Orion'
  6. 6Repeat for each additional project label
What you should see: The Switch node shows multiple output branches, one per rule, labeled with rule numbers. The canvas shows separate lines coming out of the Switch node.
Common mistake — The 'labelIds' field from Gmail contains internal label IDs (e.g. 'Label_12345678'), not the human-readable names you created. In Step 7, you'll need to map IDs to readable names — or use the 'labelNames' field if your n8n Gmail node version exposes it. Test by running the trigger and inspecting the raw output.
7

Canvas > + > Code (after Switch, on each branch)

Resolve Label IDs to Readable Channel Names

After the Switch node, add another Code node on each branch (or one before the Switch) to map Gmail label IDs to Slack channel IDs. Gmail's API returns label IDs like 'Label_1234567890' rather than 'Project-Orion'. Build a simple lookup object in the Code node that maps each label ID to the corresponding Slack channel ID. You get the Slack channel ID by right-clicking a channel in Slack and selecting 'Copy link' — the ID is the last segment after the final slash.

  1. 1Right-click each Slack channel and copy its link to get the channel ID
  2. 2Click '+' before or after the Switch node
  3. 3Add a Code node in 'Run Once for Each Item' mode
  4. 4Paste the label-to-channel lookup map (included in pro_tip_code)
  5. 5Verify the output shows a 'slackChannelId' field with the correct channel ID
What you should see: Each email item now has a 'slackChannelId' field populated with the correct Slack channel ID string (e.g. 'C04XYZ1234').
Common mistake — Slack channel IDs start with 'C' for public channels and 'G' for private groups. If you paste the full Slack channel URL instead of just the ID segment, the Slack node will throw a 'channel_not_found' error.

Paste this into the Code node (Step 5) set to 'Run Once for Each Item' mode. It decodes the base64 Gmail body, strips HTML, trims to 300 chars, resolves the label ID to a Slack channel ID, and builds the Gmail deep link — all in one pass so you don't need separate transformation nodes.

JavaScript — Code Node// n8n Code Node — Gmail body parser + label-to-channel resolver
▸ Show code
// n8n Code Node — Gmail body parser + label-to-channel resolver
// Mode: Run Once for Each Item
// Place after Gmail Trigger, before Switch node

... expand to see full code

// n8n Code Node — Gmail body parser + label-to-channel resolver
// Mode: Run Once for Each Item
// Place after Gmail Trigger, before Switch node

const item = $input.item.json;

// --- 1. Label ID → Slack Channel ID lookup map ---
// Replace these with your actual Gmail label IDs and Slack channel IDs
const labelChannelMap = {
  'Label_3872910456': 'C04ORION123',  // Project-Orion → #proj-orion
  'Label_4921037281': 'C04ATLAS456',  // Project-Atlas → #proj-atlas
  'Label_5034829174': 'C04HERMES789', // Project-Hermes → #proj-hermes
};

// --- 2. Resolve Slack channel from label IDs ---
const labelIds = item.labelIds || [];
let slackChannelId = null;
for (const labelId of labelIds) {
  if (labelChannelMap[labelId]) {
    slackChannelId = labelChannelMap[labelId];
    break;
  }
}

// --- 3. Extract and decode email body ---
// Gmail API returns body as base64url-encoded string
let rawBody = '';
try {
  // Try text/plain part first
  const parts = item.payload?.parts || [];
  const plainPart = parts.find(p => p.mimeType === 'text/plain');
  const htmlPart = parts.find(p => p.mimeType === 'text/html');
  
  const bodyData = plainPart?.body?.data 
    || htmlPart?.body?.data 
    || item.payload?.body?.data 
    || '';
  
  if (bodyData) {
    // Decode base64url to string
    rawBody = Buffer.from(bodyData.replace(/-/g, '+').replace(/_/g, '/'), 'base64').toString('utf-8');
  } else {
    // Fallback: use snippet from Gmail trigger
    rawBody = item.snippet || '';
  }
} catch (e) {
  rawBody = item.snippet || '[Body unavailable]';
}

// --- 4. Strip HTML tags if body is HTML ---
const cleanBody = rawBody
  .replace(/<style[\s\S]*?<\/style>/gi, '')
  .replace(/<script[\s\S]*?<\/script>/gi, '')
  .replace(/<[^>]+>/g, ' ')
  .replace(/&nbsp;/g, ' ')
  .replace(/&amp;/g, '&')
  .replace(/&lt;/g, '<')
  .replace(/&gt;/g, '>')
  .replace(/\s+/g, ' ')
  .trim()
  .substring(0, 300);

const bodyExcerpt = cleanBody.length === 300 ? cleanBody + '...' : cleanBody;

// --- 5. Format received timestamp ---
const receivedDate = item.internalDate 
  ? new Date(parseInt(item.internalDate)).toLocaleString('en-US', {
      month: 'short', day: 'numeric', year: 'numeric',
      hour: 'numeric', minute: '2-digit', hour12: true
    })
  : 'Unknown time';

// --- 6. Build Gmail deep link ---
const gmailLink = `https://mail.google.com/mail/u/0/#inbox/${item.id}`;

// --- 7. Build Slack message text ---
const slackText = [
  `*New email: ${item.subject || '(no subject)'}*`,
  `From: ${item.from || 'Unknown sender'}`,
  `Received: ${receivedDate}`,
  '',
  bodyExcerpt,
  '',
  `<${gmailLink}|Open in Gmail>`
].join('\n');

// --- 8. Return enriched item ---
return {
  json: {
    ...item,
    slackChannelId,
    cleanBody: bodyExcerpt,
    receivedDate,
    gmailLink,
    slackText,
    routingResolved: slackChannelId !== null,
  }
};
8

Canvas > + > Slack > Message > Post

Add the Slack Node to Post the Message

Click '+' at the end of each Switch branch and add a 'Slack' node. Set 'Resource' to 'Message' and 'Operation' to 'Post'. Set 'Channel' to '{{ $json.slackChannelId }}'. In the 'Text' field, build the message using the parsed fields from earlier nodes. A good format: '*New email: {{ $json.subject }}*\nFrom: {{ $json.from }}\n{{ $json.cleanBody }}'.

  1. 1Click '+' after each Switch branch
  2. 2Search for 'Slack' and select 'Slack' node
  3. 3Set 'Resource' to 'Message', 'Operation' to 'Post'
  4. 4Set 'Channel' to '{{ $json.slackChannelId }}'
  5. 5Paste the message template into the 'Text' field
What you should see: The Slack node configuration panel shows the channel and text fields populated. When you click 'Execute node', a test message appears in the target Slack channel within seconds.
Common mistake — Map fields using the variable picker — don't type field names manually. Hand-typed variable names often have invisible spacing errors that produce blank output.
message template
🔔 New Record: {{text}} {{user}}
channel: {{channel}}
ts: {{ts}}
#sales
🔔 New Record: Jane Smith
Company: Acme Corp
9

Slack Node > Credential for Slack API > Create new credential

Connect Slack Credentials

Inside the Slack node, click 'Credential for Slack API' and select 'Create new credential'. Choose 'OAuth2' and click 'Connect my account'. You'll be redirected to Slack to install the n8n app into your workspace. Grant the required scopes: 'chat:write' and 'channels:read'. After approval, the credential appears and the node shows no error.

  1. 1Click 'Credential for Slack API' dropdown
  2. 2Select 'Create new credential'
  3. 3Click 'Connect my account'
  4. 4Select your Slack workspace
  5. 5Click 'Allow' to grant chat:write and channels:read scopes
What you should see: The credential dropdown shows your Slack workspace name. The node panel shows no red error badges.
Common mistake — The Slack bot must be manually invited to each private channel it needs to post to. Run '/invite @n8n' (or whatever you named the bot) in each private project channel. Without this, you'll get a 'not_in_channel' error even with correct credentials.
10

Canvas > + > Gmail > Message > Modify

Mark Processed Emails to Prevent Duplicates

Add a second Gmail node after the Slack node. Set 'Resource' to 'Message' and 'Operation' to 'Modify'. Pass in '{{ $json.id }}' as the message ID. Under 'Add Labels', add a label called 'n8n-processed' (create this in Gmail first). This prevents the polling trigger from picking up the same email on the next 5-minute cycle.

  1. 1Create an 'n8n-processed' label in Gmail (Settings > Labels > Create new label)
  2. 2Click '+' after the Slack node
  3. 3Search for 'Gmail' and select it
  4. 4Set 'Resource' to 'Message', 'Operation' to 'Modify'
  5. 5Set 'Message ID' to '{{ $json.id }}'
  6. 6Under 'Add Labels', select 'n8n-processed'
What you should see: After a successful run, the processed email in Gmail shows the 'n8n-processed' label. On the next polling cycle, the trigger skips it because n8n's Gmail Trigger tracks seen message IDs internally — the label is a visual backup.
Common mistake — n8n's Gmail Trigger stores processed message IDs in its internal state. If you delete and recreate the workflow, that state resets and old emails may re-trigger. The 'n8n-processed' label acts as a secondary safety net — update your trigger filter to exclude this label by adding a Gmail filter rule.
11

n8n Canvas > Save > Active toggle > Executions tab

Activate and Monitor the Workflow

Click 'Save' in the top-right, then toggle the workflow from 'Inactive' to 'Active' using the switch at the top of the canvas. Send a test email to the Gmail inbox with the correct label applied and wait up to 5 minutes for the poll cycle to fire. Check the 'Executions' tab in n8n to see run history, input/output data per node, and any errors. Set up n8n's built-in error workflow to alert you if the Gmail or Slack nodes fail.

  1. 1Click 'Save' (top-right)
  2. 2Toggle the workflow switch from 'Inactive' to 'Active'
  3. 3Send a test email to Gmail with the project label applied
  4. 4Wait up to 5 minutes, then check the 'Executions' tab
  5. 5Verify the test message appears in the correct Slack channel
What you should see: The Executions tab shows a green 'Success' status entry. The Slack channel displays the formatted project update message with sender, subject, and body excerpt.

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 your team self-hosts or has strict data residency requirements. Project emails from clients and vendors often contain sensitive commercial terms — you may not want that content passing through Zapier's or Make's cloud infrastructure. n8n lets you run this entire workflow on your own server, and the Code node gives you real body parsing (stripping HTML, decoding base64) that Zapier's Formatter can't match without multiple steps. The one scenario where you'd pick something else: if your team has no one comfortable editing a JavaScript snippet, Make's Gmail-to-Slack scenario does the same routing with a visual text parser and no code required.

Cost

The cost math here is straightforward. n8n cloud charges by workflow executions. This workflow runs 3 nodes per email (Gmail Trigger fires, Code runs, Slack posts) plus one cleanup node — call it 4 executions per email processed. At 50 project emails per day, that's 200 executions/day, roughly 6,000/month. n8n's Starter plan includes 2,500 executions/month for $20; Pro gives you 10,000 for $50. At 50 emails/day you're on Pro. Zapier at the same volume costs $49/month (Professional, 2,000 tasks — you'd blow past it fast since Zapier counts each action separately). Make's Core plan gives you 10,000 operations for $9/month — the same workflow in Make costs about 4 operations per email, so 50 emails/day = 6,000 ops/month, well inside Make's Core tier. Make wins on price here by $41/month.

Tradeoffs

Make's Gmail watch trigger is marginally more reliable for this use case — it uses push notifications via Gmail's watch API rather than polling, so emails hit Slack in under 60 seconds instead of up to 5 minutes. Zapier's Gmail trigger is similarly near-real-time on paid plans and has a cleaner label filter UI, but its text formatting step requires a separate Formatter action that costs an extra task. Power Automate's Office 365 version of this workflow is excellent if your org runs Exchange, but its Gmail connector is throttled and often laggy — avoid it for Gmail specifically. Pipedream handles this well with its native Gmail source that uses push notifications, and the code step is cleaner to write than n8n's for developers. n8n is still the right call if you want self-hosting, the most control over body parsing, and don't mind the 5-minute polling delay.

Three things you'll hit after launch. First: Gmail's base64url encoding. The API doesn't return plain text — it returns base64url-encoded body data. If you skip the decoding step and just use the 'snippet' field, you get 100 characters of plain text with no HTML, which looks clean in testing but loses context in production. Decode the full body. Second: Slack's rate limit is 1 message per second per channel. If a batch of emails arrives simultaneously (common after a weekend), n8n will try to post several times per second and you'll get 429 errors. Add a 'Wait' node set to 1 second between each Slack post if you're processing more than 5 emails per execution cycle. Third: Google's OAuth token refresh silently fails when your Cloud project is in Testing mode — the workflow just stops executing with no error email to you. This happens to everyone who sets up Gmail OAuth for the first time. Publish the app to Production in Google Cloud Console immediately after testing.

Ideas for what to build next

  • Add Attachment Detection and AlertsExtend the Code node to check 'payload.parts' for attachment MIME types. If an attachment exists, append a warning line to the Slack message like '📎 1 attachment — open in Gmail to download'. Teams miss attached contracts and specs when only the body excerpt posts.
  • Build a Daily Digest Instead of Per-Email PostsReplace the 5-minute polling trigger with a scheduled trigger at 9am and 3pm. Batch all unprocessed project emails since the last run into a single Slack message per channel, formatted as a numbered list. This cuts Slack noise by 80% for high-volume projects.
  • Log All Broadcasts to a Google SheetAdd a Google Sheets node after the Slack post that appends a row with: timestamp, sender, subject, project label, Slack channel, and message ID. After 30 days you'll have a full audit trail of external communications per project — useful for client billing and post-mortems.

Related guides

Was this guide helpful?
Slack + Gmail overviewn8n profile →