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

How to Broadcast Gmail Project Updates to Slack with Pipedream

Watches Gmail for labeled project-related emails and instantly forwards their sender, subject, and body snippet to the matching Slack channel.

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

Best for

Distributed teams that receive vendor emails or stakeholder feedback in Gmail and need the right Slack channel notified within seconds — without forwarding entire inboxes.

Not ideal for

Teams using Google Groups or shared inboxes where multiple accounts receive the same email; deduplication becomes complex and a dedicated email routing tool handles it better.

Sync type

real-time

Use case type

notification

Real-World Example

💡

A 22-person product agency receives client feedback, vendor invoices, and contractor updates across three active projects — all landing in one project manager's Gmail. Before this workflow, the PM copy-pasted emails into Slack manually, often hours after receipt, and engineers missed blockers. Now, emails labeled 'Project-Alpha' trigger an instant post to #proj-alpha with the sender, subject line, and first 400 characters of the body — the team sees it in under 30 seconds.

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 Pipedream

Copy the pre-built Pipedream blueprint and paste it straight into Pipedream. 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 OAuth access enabled — the account must allow third-party app connections (not blocked by Google Workspace admin policy)
Gmail labels already created for each project — e.g., 'Project-Alpha', 'Project-Beta' — with emails manually or filter-assigned to those labels
Slack workspace with permission to install apps and a bot token that has the `chat:write` scope
Slack channels already created for each project (e.g., #proj-alpha) with the Pipedream bot invited to each channel via `/invite`
Pipedream account — free tier works for up to 10,000 credits/month; a workflow this size costs roughly 2–3 credits per run

Field Mapping

Map these fields between your apps.

FieldAPI Name
Required
Email Subject
Sender Name and Email
Email Snippet / Body Preview
Email Timestamp
Gmail Label Name
Gmail Message ID
Target Slack Channel
1 optional field▸ show
Gmail Thread ID

Step-by-Step Setup

1

pipedream.com > Workflows > New Workflow

Create a new Pipedream Workflow

Log into pipedream.com and click 'New Workflow' in the top-right corner. Give the workflow a clear name — 'Gmail → Slack Project Broadcaster' works well. You'll land on the workflow canvas with an empty trigger slot at the top. Pipedream workflows run top-to-bottom: trigger fires, then each step executes in order.

  1. 1Go to pipedream.com and sign in
  2. 2Click the blue 'New Workflow' button in the top-right
  3. 3Type 'Gmail → Slack Project Broadcaster' in the workflow name field
  4. 4Press Enter to confirm the name
What you should see: You should see a blank workflow canvas with a single grey 'Add Trigger' block at the top and a '+ Add Step' button below it.
2

Workflow Canvas > Add Trigger > Gmail > New Email

Add Gmail as the trigger source

Click the grey 'Add Trigger' block. Search for 'Gmail' in the app search bar and select it. Choose the 'New Email' trigger — this fires every time a new email arrives that matches your filter criteria. Pipedream uses Gmail's push notification API (not polling), so the trigger fires within 5–15 seconds of email delivery.

  1. 1Click the grey 'Add Trigger' block on the canvas
  2. 2Type 'Gmail' in the search bar
  3. 3Select 'Gmail' from the results
  4. 4Choose 'New Email' from the trigger list
What you should see: The trigger block expands to show a Gmail configuration panel with fields for Connected Account, Label/Filter, and optional search query.
Common mistake — Pipedream's Gmail trigger uses OAuth push notifications, not polling. This means you must complete the Connected Account step before the trigger can register with Gmail's API — skipping ahead breaks the setup.
Pipedream
+
click +
search apps
Slack
SL
Slack
Add Gmail as the trigger sou…
Slack
SL
module added
3

Gmail Trigger > Connected Account > Connect Account

Connect your Gmail account

In the trigger configuration panel, click 'Connect Account' under the Connected Account field. A Google OAuth window will open — sign in with the Gmail account that receives project-related emails. Grant Pipedream the requested Gmail scopes. After connecting, the account email address appears in the dropdown and the field shows a green checkmark.

  1. 1Click 'Connect Account' in the Gmail trigger panel
  2. 2Select your Google account in the OAuth popup
  3. 3Click 'Allow' to grant Gmail read access
  4. 4Confirm the connected account appears in the dropdown
What you should see: You should see your Gmail address listed in the Connected Account dropdown with a green checkmark next to it.
Common mistake — If your Google Workspace admin has restricted third-party OAuth apps, the connection will silently fail or show a 'blocked by organization' error. You'll need your admin to allowlist Pipedream's OAuth client ID before continuing.
Pipedream settings
Connection
Choose a connection…Add
click Add
Slack
Log in to authorize
Authorize Pipedream
popup window
Connected
green checkmark
4

Gmail Trigger > Label > [your label name]

Filter emails by Gmail label

In the trigger's Label field, type the name of the Gmail label you use for project emails — for example, 'Project-Alpha'. If you manage multiple projects, you'll build separate workflows per label, or use a label prefix like 'Project-' and handle routing in a code step. Leave the Search Query field blank unless you need additional filtering (e.g., specific senders). Click 'Save and continue'.

  1. 1Click into the 'Label' field in the trigger config
  2. 2Type your exact Gmail label name (case-sensitive)
  3. 3Leave the Search Query field blank unless you need sender filtering
  4. 4Click 'Save and continue'
What you should see: Pipedream displays a 'Test Event' section below the trigger config. You should see a sample Gmail event payload with fields like subject, from, snippet, and labelIds.
Common mistake — Gmail label names are case-sensitive in the API. If your label is 'project-alpha' (lowercase) but you type 'Project-Alpha', the trigger will never fire. Copy the exact label name from Gmail's left sidebar.
Slack
SL
trigger
filter
Condition
matches criteria?
yes — passes through
no — skipped
Gmail
GM
notified
5

Gmail Trigger > Generate Test Event

Load a test email event

Click 'Generate Test Event' to pull a recent email from Gmail matching your label. Pipedream fetches the last matching message and displays its raw payload in the event inspector on the right side of the canvas. Expand the payload to confirm you can see fields like `subject`, `from`, `snippet`, `body`, and `labelIds`. You'll reference these field paths in later steps.

  1. 1Click 'Generate Test Event' in the trigger panel
  2. 2Wait 3–5 seconds for Pipedream to fetch from Gmail
  3. 3Click the event in the inspector panel to expand the payload
  4. 4Verify 'subject', 'from', and 'snippet' fields are visible
What you should see: The right-hand inspector panel shows a JSON tree with your email's metadata. You should see `steps.trigger.event.subject`, `steps.trigger.event.from`, and `steps.trigger.event.snippet` as accessible paths.
Pipedream
▶ Deploy & test
executed
Slack
Gmail
Gmail
🔔 notification
received
6

Workflow Canvas > + Add Step > Run Node.js code

Add a Node.js code step to build the Slack message

Click '+ Add Step' below the trigger, then select 'Run Node.js code'. This step extracts the relevant email fields and builds a formatted Slack Block Kit message. Using a code step here — rather than a pre-built action — lets you truncate the body snippet, strip HTML characters, and format the sender name cleanly. Paste the code from the Pro Tip section into the code editor.

  1. 1Click '+ Add Step' below the Gmail trigger block
  2. 2Click 'Run Node.js code' from the step type options
  3. 3Clear the default placeholder code in the editor
  4. 4Paste the Pro Tip code into the editor
What you should see: The code step shows your pasted Node.js code in the editor. The step is labeled 'code' by default — you can rename it 'build_slack_message' by clicking the step title.
Common mistake — Pipedream code steps run in Node.js 18. If you paste code written for older Node versions that uses `require()` for built-in modules differently, you may get a module resolution error. The Pro Tip code uses only built-in Node and Pipedream's `$` helper — no npm installs needed.

Paste this into the Node.js code step (Step 6) — it extracts the Gmail event fields, strips HTML entities from the snippet, maps the Gmail label to the correct Slack channel, and returns a Block Kit payload ready to pass directly into the Slack 'Send Message' action. The `labelToChannelMap` object is where you add new projects — update it and redeploy without touching anything else.

JavaScript — Code Stepexport default defineComponent({
▸ Show code
export default defineComponent({
  async run({ steps, $ }) {
    const email = steps.trigger.event;

... expand to see full code

export default defineComponent({
  async run({ steps, $ }) {
    const email = steps.trigger.event;

    // Map Gmail labels to Slack channel names
    const labelToChannelMap = {
      'Project-Alpha': '#proj-alpha',
      'Project-Beta': '#proj-beta',
      'Project-Gamma': '#proj-gamma',
    };

    // Find the matching project label from the email's label list
    const projectLabel = email.labelIds?.find(label => labelToChannelMap[label]);
    const channelName = projectLabel ? labelToChannelMap[projectLabel] : '#general-projects';

    // Clean the snippet: strip HTML tags and decode common HTML entities
    const rawSnippet = email.snippet || 'No preview available.';
    const cleanSnippet = rawSnippet
      .replace(/<[^>]+>/g, '')
      .replace(/&nbsp;/g, ' ')
      .replace(/&amp;/g, '&')
      .replace(/&lt;/g, '<')
      .replace(/&gt;/g, '>')
      .replace(/&quot;/g, '"')
      .trim()
      .slice(0, 400);

    // Format sender display name
    const from = email.from || 'Unknown Sender';
    const senderDisplay = from.replace(/<([^>]+)>/, '(<$1>)').trim();

    // Format the received timestamp
    const receivedDate = email.date
      ? new Date(email.date).toLocaleString('en-US', {
          month: 'short', day: 'numeric', year: 'numeric',
          hour: 'numeric', minute: '2-digit', timeZoneName: 'short'
        })
      : 'Unknown time';

    // Build Slack Block Kit message
    const slackBlocks = [
      {
        type: 'header',
        text: { type: 'plain_text', text: '📧 New Project Email', emoji: true }
      },
      {
        type: 'section',
        fields: [
          { type: 'mrkdwn', text: `*From:*\n${senderDisplay}` },
          { type: 'mrkdwn', text: `*Channel:*\n${channelName}` }
        ]
      },
      {
        type: 'section',
        text: { type: 'mrkdwn', text: `*Subject:* ${email.subject || '(no subject)'}` }
      },
      { type: 'divider' },
      {
        type: 'section',
        text: {
          type: 'mrkdwn',
          text: `${cleanSnippet}${rawSnippet.length > 400 ? '…' : ''}`
        }
      },
      {
        type: 'context',
        elements: [
          { type: 'mrkdwn', text: `Received: ${receivedDate} · Message ID: ${email.id}` }
        ]
      }
    ];

    return { channelName, slackBlocks, senderDisplay, receivedDate };
  }
});
message template
🔔 New Record: {{text}} {{user}}
channel: {{channel}}
ts: {{ts}}
#sales
🔔 New Record: Jane Smith
Company: Acme Corp
7

Code Step > Test

Test the code step

Click 'Test' on the code step. Pipedream re-runs the step using the test event data loaded from Gmail in Step 5. The return value appears in the inspector panel on the right. Check that `slackBlocks`, `channelName`, and `senderDisplay` all have the expected values. If the snippet is showing HTML tags (e.g., `&nbsp;`), the code step strips those — confirm the output looks clean.

  1. 1Click the 'Test' button inside the code step
  2. 2Wait 2–3 seconds for the step to execute
  3. 3Expand the 'Return Value' section in the right inspector
  4. 4Verify slackBlocks, channelName, and senderDisplay are populated correctly
What you should see: The inspector shows a return object with `slackBlocks` containing a formatted Block Kit array, `channelName` as a string (e.g., '#proj-alpha'), and `senderDisplay` showing the sender's name and email.

Paste this into the Node.js code step (Step 6) — it extracts the Gmail event fields, strips HTML entities from the snippet, maps the Gmail label to the correct Slack channel, and returns a Block Kit payload ready to pass directly into the Slack 'Send Message' action. The `labelToChannelMap` object is where you add new projects — update it and redeploy without touching anything else.

JavaScript — Code Stepexport default defineComponent({
▸ Show code
export default defineComponent({
  async run({ steps, $ }) {
    const email = steps.trigger.event;

... expand to see full code

export default defineComponent({
  async run({ steps, $ }) {
    const email = steps.trigger.event;

    // Map Gmail labels to Slack channel names
    const labelToChannelMap = {
      'Project-Alpha': '#proj-alpha',
      'Project-Beta': '#proj-beta',
      'Project-Gamma': '#proj-gamma',
    };

    // Find the matching project label from the email's label list
    const projectLabel = email.labelIds?.find(label => labelToChannelMap[label]);
    const channelName = projectLabel ? labelToChannelMap[projectLabel] : '#general-projects';

    // Clean the snippet: strip HTML tags and decode common HTML entities
    const rawSnippet = email.snippet || 'No preview available.';
    const cleanSnippet = rawSnippet
      .replace(/<[^>]+>/g, '')
      .replace(/&nbsp;/g, ' ')
      .replace(/&amp;/g, '&')
      .replace(/&lt;/g, '<')
      .replace(/&gt;/g, '>')
      .replace(/&quot;/g, '"')
      .trim()
      .slice(0, 400);

    // Format sender display name
    const from = email.from || 'Unknown Sender';
    const senderDisplay = from.replace(/<([^>]+)>/, '(<$1>)').trim();

    // Format the received timestamp
    const receivedDate = email.date
      ? new Date(email.date).toLocaleString('en-US', {
          month: 'short', day: 'numeric', year: 'numeric',
          hour: 'numeric', minute: '2-digit', timeZoneName: 'short'
        })
      : 'Unknown time';

    // Build Slack Block Kit message
    const slackBlocks = [
      {
        type: 'header',
        text: { type: 'plain_text', text: '📧 New Project Email', emoji: true }
      },
      {
        type: 'section',
        fields: [
          { type: 'mrkdwn', text: `*From:*\n${senderDisplay}` },
          { type: 'mrkdwn', text: `*Channel:*\n${channelName}` }
        ]
      },
      {
        type: 'section',
        text: { type: 'mrkdwn', text: `*Subject:* ${email.subject || '(no subject)'}` }
      },
      { type: 'divider' },
      {
        type: 'section',
        text: {
          type: 'mrkdwn',
          text: `${cleanSnippet}${rawSnippet.length > 400 ? '…' : ''}`
        }
      },
      {
        type: 'context',
        elements: [
          { type: 'mrkdwn', text: `Received: ${receivedDate} · Message ID: ${email.id}` }
        ]
      }
    ];

    return { channelName, slackBlocks, senderDisplay, receivedDate };
  }
});
8

Workflow Canvas > + Add Step > Slack > Send Message

Add the Slack 'Send Message' action

Click '+ Add Step' below the code step and search for 'Slack'. Select the 'Send Message' action. Connect your Slack workspace via the Connected Account dropdown — this opens a Slack OAuth screen where you authorize Pipedream to post messages. In the Channel field, reference the output from your code step: click the '{}' icon and select `steps.build_slack_message.$return_value.channelName`. In the Blocks field, select `steps.build_slack_message.$return_value.slackBlocks`.

  1. 1Click '+ Add Step' below the code step
  2. 2Search for 'Slack' and select it
  3. 3Choose 'Send Message' from the action list
  4. 4Click 'Connect Account' and authorize your Slack workspace
  5. 5Set Channel to `steps.build_slack_message.$return_value.channelName`
  6. 6Set Blocks to `steps.build_slack_message.$return_value.slackBlocks`
What you should see: The Slack action shows your workspace name in the Connected Account field with a green checkmark, and the Channel and Blocks fields reference your code step's output paths.
Common mistake — The Slack OAuth bot token requires the `chat:write` scope and the bot must be invited to the target channel. If you see a 'channel_not_found' error during testing, the bot hasn't been added to the channel — run `/invite @YourBotName` in Slack first.
9

Slack Action > Test

Test the Slack action

Click 'Test' on the Slack action step. Pipedream sends the formatted Block Kit message to your Slack channel using the test event data. Switch to Slack and look for the message in the target channel — it should appear within 5 seconds. Verify the sender name, subject, timestamp, and body snippet all display correctly. If the message posts but Block Kit formatting looks broken, check the slackBlocks JSON structure in the inspector.

  1. 1Click 'Test' inside the Slack action step
  2. 2Open Slack and navigate to your target project channel
  3. 3Confirm the message appears with correct formatting
  4. 4Check the inspector for any error responses from the Slack API
What you should see: A formatted Slack message appears in the target channel showing the sender's name, email, subject line, timestamp, and the first 400 characters of the email body.
10

Workflow Canvas > Deploy

Deploy the workflow

Click the grey 'Deploy' button in the top-right of the workflow canvas. Pipedream registers the Gmail push notification subscription and activates the workflow. The status indicator in the top bar changes from 'Inactive' to 'Active' with a green dot. From this point, every new email with your label triggers the workflow and posts to Slack automatically — no manual intervention needed.

  1. 1Click the grey 'Deploy' button in the top-right corner
  2. 2Confirm the status indicator turns green and shows 'Active'
  3. 3Send a test email to your Gmail with the project label applied
  4. 4Verify the Slack message appears within 30 seconds
What you should see: The workflow status shows 'Active' with a green dot. In the Runs tab, you should see a new run appear within seconds of the next matching email arriving in Gmail.
Common mistake — Gmail push notification subscriptions expire after 7 days unless Pipedream renews them. Pipedream handles renewal automatically, but if your workflow is paused or erroring during the renewal window, the subscription lapses and you'll stop receiving events. Check the workflow's health status weekly.
11

Workflow > Runs Tab > Settings > Notifications

Monitor runs in the Pipedream inspector

Navigate to your workflow and click the 'Runs' tab to see every execution. Each run shows the Gmail payload that triggered it, the output of your code step, and the Slack API response. If a run fails, the failing step is highlighted in red with the error message. Set up error notifications under Settings > Notifications to get an email when the workflow errors — critical for catching Gmail subscription lapses or Slack token expiry.

  1. 1Click the 'Runs' tab at the top of your workflow
  2. 2Click any run to expand its step-by-step execution details
  3. 3Navigate to Settings > Notifications
  4. 4Enable email alerts for workflow errors
What you should see: The Runs tab shows a list of recent executions with green (success) or red (error) status indicators. Each run is expandable to show inputs, outputs, and timing per step.

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 Pipedream for this if your team has even one engineer who can read JavaScript. The Node.js code step is the entire reason to pick Pipedream here — you get HTML stripping, label-to-channel routing, and Block Kit formatting in a single step that takes 20 minutes to write and runs in under 200ms. The Gmail push notification integration fires in under 15 seconds from email delivery. The one scenario where you'd pick something else: if your team is entirely non-technical and needs someone to maintain this long-term, Zapier's no-code Gmail trigger and Slack action get you 80% of the way there with zero code — you just lose the formatting control and routing logic.

Cost

Pipedream's pricing for this workflow is straightforward. Each run consumes roughly 2–3 credits (one for the trigger, one for the code step, one for the Slack action). At 200 project emails per month — a busy agency with 5 active projects — that's 400–600 credits/month. Pipedream's free tier includes 10,000 credits/month. You'd need to receive roughly 3,300 project emails per month before hitting the free limit. The paid Basic plan at $19/month gives you 100,000 credits. Zapier's equivalent — Gmail trigger + Slack action — costs one task per run, and at 200 emails/month you'd burn through the free tier's 100-task limit in a day. Zapier's Starter plan at $29.99/month gives you 750 tasks. Pipedream is cheaper at any meaningful volume.

Tradeoffs

Zapier's Gmail trigger is slightly easier to configure for non-coders — the label filter UI is more forgiving and doesn't require exact case matching. Make's scenario builder lets you visually route emails to different Slack channels using a Router module, which is more intuitive than a JavaScript object map if you have many projects. n8n's Gmail node gives you full access to the raw MIME payload, which is better if you need to process attachments or parse structured email bodies. Power Automate has a native Gmail connector but it's slower — polling every 1–5 minutes instead of push — and the Slack connector is limited in scope. Pipedream wins here because the code step collapses what would be 3–4 Make modules or a complex n8n Function node into clean, readable JavaScript that's easy to hand off to another engineer.

Three things you'll hit after this is running in production. First, Gmail occasionally fires duplicate push events for the same email — specifically when a filter applies a label and then another rule modifies it within the same second. Without the Message ID deduplication check in the code step, you'll see two identical Slack messages. Add it before you go live. Second, the Gmail push notification subscription silently expires if your Pipedream workflow errors continuously for more than 24 hours — the subscription renewal fails and you stop getting events with no obvious error in the UI. Set up error notifications and check the Runs tab weekly. Third, Slack's Block Kit `section` fields have a 2,000-character limit per text element — if you ever extend the snippet beyond 400 characters without a truncation check, the Slack API returns a `invalid_blocks` error that isn't immediately obvious from the error message alone.

Ideas for what to build next

  • Add an email reply link to the Slack messageInclude a 'Reply in Gmail' button in the Block Kit message using the email's message ID to build a deep link (`https://mail.google.com/mail/u/0/#inbox/{messageId}`). This lets team members respond directly from the Slack notification without searching their inbox.
  • Route to multiple channels based on sender domainExtend the code step to check the sender's email domain in addition to the label — so emails from `@vendorA.com` always go to #vendor-a even if mislabeled. Add a secondary routing map keyed by domain and merge the two routing signals with a fallback.
  • Build a daily digest instead of instant notificationsReplace the Gmail push trigger with a Pipedream scheduled trigger that runs at 8 AM. Use the Gmail search action to pull all project-labeled emails from the last 24 hours, batch them by project label, and post a single digest message per channel — reducing Slack noise for lower-urgency projects.

Related guides

Was this guide helpful?
Slack + Gmail overviewPipedream profile →