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

How to Forward Gmail Emails to Slack with Pipedream

Watches a Gmail inbox for messages matching specific senders, subject keywords, or labels, then posts a formatted summary to a designated 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

Engineering or ops teams who want to route customer emails, vendor alerts, or labeled messages to specific Slack channels without writing a full backend service.

Not ideal for

Teams that need two-way email-to-Slack threading or want replies sent back via email — that requires a different architecture entirely.

Sync type

real-time

Use case type

notification

Real-World Example

💡

A 12-person SaaS support team forwards all emails tagged with the Gmail label 'customer-inquiry' to #support in Slack so the whole team sees new tickets within seconds. Before this, a single support rep had to check a shared inbox and manually paste email content into Slack — which meant a 30-to-90-minute lag on busy days. With Pipedream running the workflow, the message hits Slack within 15 seconds of Gmail receiving the email.

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 — the account must allow third-party app connections (not blocked by a Google Workspace admin policy)
Slack workspace where you have permission to install apps and post to the target channel
Pipedream account (free tier works) — sign up at pipedream.com
Gmail account must have the Gmail API enabled — this is handled automatically via Pipedream's OAuth flow for personal accounts, but Workspace admins may need to whitelist Pipedream's OAuth client ID
Target Slack channel must exist and the Pipedream bot must be invited to it if it's a private channel

Field Mapping

Map these fields between your apps.

FieldAPI Name
Required
Sender Emailfrom.email
Subject Linesubject
Snippetsnippet
Slack Channel ID
6 optional fields▸ show
Sender Namefrom.name
Gmail Label IDslabelIds
Thread IDthreadId
Message IDid
Received TimestampinternalDate
Plain Text Bodybody.text

Step-by-Step Setup

1

pipedream.com > Workflows > New Workflow

Create a new Pipedream workflow

Go to pipedream.com and log in. From the left sidebar, click 'Workflows', then click the blue 'New Workflow' button in the top right. You'll land on a blank canvas with a single prompt: 'Add a trigger'. This is your starting point — everything flows from the trigger you pick here.

  1. 1Log in at pipedream.com
  2. 2Click 'Workflows' in the left sidebar
  3. 3Click the blue 'New Workflow' button in the top right
  4. 4Click the '+ Add Trigger' tile on the canvas
What you should see: You should see the trigger selection panel open on the right side of the screen with a search bar and a list of apps.
Common mistake — Pipedream has two product areas: Workflows and Sources. Do not click 'Sources' — that's a standalone event source builder. You want 'Workflows'.
2

Trigger Panel > Search 'Gmail' > New Email

Add the Gmail trigger

In the trigger search panel, type 'Gmail' and select it. You'll see a list of available Gmail triggers. Choose 'New Email' — this fires every time a new message arrives in the connected inbox. Do not choose 'New Email Matching Search' unless you want to write a Gmail search query right now; you can add filters in a later step using code.

  1. 1Type 'Gmail' in the trigger search bar
  2. 2Click the Gmail app icon
  3. 3Select 'New Email' from the trigger list
  4. 4Click 'Connect Gmail Account' and authorize via the OAuth popup
What you should see: After OAuth completes, you should see a green checkmark next to your Gmail address and a 'Test Trigger' button appears below the configuration panel.
Common mistake — Gmail's Pub/Sub push notification — which Pipedream uses under the hood — requires the connected Gmail account to have Google Cloud Pub/Sub API access. Personal @gmail.com accounts work fine. Google Workspace accounts with restrictive admin policies may silently fail here; check with your Workspace admin before building.
Pipedream
+
click +
search apps
Slack
SL
Slack
Add the Gmail trigger
Slack
SL
module added
3

Trigger Panel > Test Trigger

Test the Gmail trigger

Click 'Test Trigger'. Pipedream will pull the most recent email from your inbox as sample data. You'll see a JSON object appear with fields like `subject`, `from.email`, `snippet`, `labelIds`, and `body.html`. This sample data is what all downstream steps will reference. If your inbox is empty or the account is fresh, send yourself a test email first.

  1. 1Click the 'Test Trigger' button
  2. 2Wait 5-10 seconds for Pipedream to fetch a recent email
  3. 3Expand the returned JSON to inspect the `from`, `subject`, and `body` fields
What you should see: You should see a JSON payload in the 'Results' tab with at least a `subject`, `from.email`, `snippet`, and `labelIds` array populated from a real email in your inbox.
Pipedream
▶ Deploy & test
executed
Slack
Gmail
Gmail
🔔 notification
received
4

Workflow Canvas > + > Run Node.js Code

Add a Node.js code step to filter emails

Click the '+' button below the trigger to add a new step. Choose 'Run Node.js code'. This is where you decide which emails actually get forwarded. You'll write a short filter that checks the sender address, subject line, or label — and calls `$.flow.exit()` to stop the workflow if the email doesn't match. Without this step, every single email in your inbox gets posted to Slack.

  1. 1Click the '+' button below the Gmail trigger tile
  2. 2Select 'Run Node.js code' from the step options
  3. 3Paste your filter logic into the code editor (see the pro tip below)
  4. 4Click 'Test' to confirm the filter runs against your sample email data
What you should see: If the test email matches your filter, you should see 'Exports: {}' in the Results tab. If it doesn't match, Pipedream shows 'Workflow was cancelled at step 2' — which means the filter is working correctly.
Common mistake — $.flow.exit() stops execution for that specific event only — it does not pause or disable the workflow. Don't confuse a cancelled run with an error. Cancelled runs are free and don't count against your credit usage.

Paste this as your Step 2 Node.js filter + Step 3 formatter combined. It handles sender filtering, label matching, plain-text body extraction, and HTML tag stripping in one step — then exports everything the Slack step needs. Place it directly after the Gmail trigger, before the Slack step.

JavaScript — Code Step// Step: Filter + Format Gmail Email for Slack
▸ Show code
// Step: Filter + Format Gmail Email for Slack
// Place this immediately after the Gmail trigger
export default defineComponent({

... expand to see full code

// Step: Filter + Format Gmail Email for Slack
// Place this immediately after the Gmail trigger

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

    // --- FILTER CONFIGURATION ---
    const ALLOWED_SENDERS = ['[email protected]', '[email protected]'];
    const REQUIRED_LABEL = 'vendor-invoices'; // set to null to skip label check
    const SUBJECT_KEYWORDS = ['invoice', 'payment', 'action required'];

    // Check sender
    const senderEmail = email.from?.email?.toLowerCase() ?? '';
    const senderName = email.from?.name ?? senderEmail;
    const senderMatch = ALLOWED_SENDERS.length === 0 || ALLOWED_SENDERS.includes(senderEmail);

    // Check label
    const labelMatch = !REQUIRED_LABEL || (email.labelIds ?? []).includes(REQUIRED_LABEL);

    // Check subject keywords
    const subject = email.subject ?? '';
    const keywordMatch = SUBJECT_KEYWORDS.length === 0 ||
      SUBJECT_KEYWORDS.some(kw => subject.toLowerCase().includes(kw.toLowerCase()));

    if (!senderMatch || !labelMatch || !keywordMatch) {
      $.flow.exit(`Email filtered out — sender: ${senderMatch}, label: ${labelMatch}, keyword: ${keywordMatch}`);
    }

    // --- FORMAT FOR SLACK ---
    // Strip HTML tags from body if plain text unavailable
    const rawBody = email.body?.text ?? email.snippet ?? '';
    const cleanBody = rawBody
      .replace(/<[^>]+>/g, '') // strip HTML tags
      .replace(/\s+/g, ' ')   // collapse whitespace
      .trim()
      .substring(0, 300);     // cap at 300 chars for Slack readability

    // Build Gmail deep link
    const gmailLink = `https://mail.google.com/mail/u/0/#inbox/${email.threadId}`;

    // Format received date
    const receivedAt = email.internalDate
      ? new Date(parseInt(email.internalDate)).toLocaleString('en-US', { timeZone: 'America/New_York' })
      : 'Unknown time';

    // Export values for Slack step
    return {
      senderEmail,
      senderName,
      subject,
      bodyPreview: cleanBody,
      gmailLink,
      receivedAt,
      slackMessage: `*New email from ${senderName} <${senderEmail}>*\n*Subject:* ${subject}\n*Received:* ${receivedAt}\n\n${cleanBody}\n\n<${gmailLink}|Open in Gmail>`,
    };
  },
});
// In the Slack step, set Text = {{steps.filter_and_format.$return_value.slackMessage}}
Slack
SL
trigger
filter
Condition
matches criteria?
yes — passes through
no — skipped
Gmail
GM
notified
5

Workflow Canvas > + > Run Node.js Code

Extract and format the email fields

Add a second Node.js code step. This step pulls the fields you care about — sender name, sender email, subject, timestamp, and a plain-text snippet — and formats them into a clean Slack message string. Gmail's `body.html` is messy HTML; use a simple regex or string replacement to strip tags for the Slack preview. Export the formatted values so the Slack step can reference them.

  1. 1Click '+' below the filter step
  2. 2Select 'Run Node.js code'
  3. 3Write code to extract `steps.trigger.event.subject`, `steps.trigger.event.from.email`, and `steps.trigger.event.snippet`
  4. 4Use `$.export()` to make these values available to downstream steps
  5. 5Click 'Test' and verify the exported values appear in the Results tab
What you should see: The Results tab should show a populated 'Exports' object with keys like `senderEmail`, `subject`, `snippet`, and `receivedAt` — ready to be referenced in the Slack step.
Common mistake — Gmail's `snippet` field is capped at 100 characters and strips all HTML. It's fine for a Slack preview but not for forwarding the full email body. If you need the full body, parse `steps.trigger.event.body.text` — not `body.html` — to avoid sending raw HTML into Slack.
Slack fields
text
user
channel
ts
thread_ts
available as variables:
1.props.text
1.props.user
1.props.channel
1.props.ts
1.props.thread_ts
6

Workflow Canvas > + > Slack > Send Message to Channel

Add the Slack step

Click '+' below your formatting step and search for 'Slack'. Select the 'Send Message to Channel' action. Connect your Slack workspace via OAuth — Pipedream will open a Slack authorization popup. Once connected, select the target channel from the dropdown (e.g., #vendor-updates or #customer-inquiries). Pipedream lists all channels your bot has access to.

  1. 1Click '+' below the formatting step
  2. 2Type 'Slack' in the search bar and select the Slack app
  3. 3Choose 'Send Message to Channel'
  4. 4Click 'Connect Slack Account' and authorize via the OAuth popup
  5. 5Select your target channel from the 'Channel' dropdown
What you should see: You should see a green 'Connected' badge next to your Slack workspace name and the channel dropdown populates with your workspace's channels.
Common mistake — Pipedream's Slack bot must be invited to private channels before they appear in the dropdown. If your target channel is private, type `/invite @Pipedream` in that channel first, then reload the Pipedream step.
7

Slack Step > Text Field > {{}} Reference Picker

Build the Slack message text

In the 'Text' field of the Slack step, click the '{{}}' icon to reference exported values from earlier steps. Build a message that includes the sender, subject, and snippet. Use Slack's mrkdwn formatting — asterisks for bold, backticks for code. For example: `*New email from {{steps.format_email.$return_value.senderEmail}}*\n*Subject:* {{steps.format_email.$return_value.subject}}\n{{steps.format_email.$return_value.snippet}}`. Add a direct Gmail link using the `threadId` from the trigger payload.

  1. 1Click inside the 'Text' field in the Slack step
  2. 2Type your message template and use '{{}}' to insert dynamic values
  3. 3Reference `steps.format_email.$return_value.senderEmail` for the sender
  4. 4Reference `steps.trigger.event.threadId` to build a deep link to Gmail
  5. 5Click 'Test' to send a real message to your Slack channel
What you should see: A Slack message should appear in the target channel within 5 seconds showing the sender email, subject line, snippet, and a clickable Gmail link.
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.
8

Workflow Canvas > + > Run Node.js Code

Add error handling with $.send.email()

Add a final Node.js step wrapped in a try/catch. If the Slack API call fails (network timeout, channel archived, token revoked), use Pipedream's built-in `$.send.email()` to notify your own inbox instead of silently dropping the event. This gives you a fallback that works without any external monitoring setup. Set the `to` field to the workflow owner's email.

  1. 1Click '+' after the Slack step
  2. 2Select 'Run Node.js code'
  3. 3Wrap a check of `steps.slack.$return_value` in a try/catch block
  4. 4In the catch block, call `$.send.email({ subject: 'Slack forward failed', text: error.message })`
  5. 5Click 'Test' to verify the step runs without errors on a successful flow
What you should see: On a successful run, this step exports nothing and passes silently. On a Slack failure, you receive an email to your Pipedream account's registered address within 1-2 minutes.
Common mistake — $.send.email() sends to the Pipedream account owner's email only — you cannot override the recipient to an external address on the free plan. If you need alerts to go to a team email, use a separate HTTP request step to a webhook-based alerting tool instead.
9

Workflow Canvas > Deploy > Event History

Deploy and monitor the workflow

Click the 'Deploy' button in the top right. Your workflow moves from Draft to Active status. From the workflow detail page, click 'Event History' in the left sidebar to watch live runs come in. Each row shows the event timestamp, which steps ran, how long each took, and whether the run succeeded, was cancelled (filtered out), or errored. This is your primary debugging surface.

  1. 1Click the blue 'Deploy' button in the top right corner
  2. 2Confirm the status indicator changes from 'Draft' to 'Active'
  3. 3Send a real test email to your Gmail inbox that matches your filter
  4. 4Click 'Event History' in the left sidebar to watch the run appear
  5. 5Click into the run to inspect step-by-step output
What you should see: Within 15-30 seconds of the test email arriving in Gmail, you should see a new row in Event History with status 'Success' and a Slack message in your target channel.
Common mistake — Gmail's Pub/Sub subscription that Pipedream creates has a 7-day expiration on inactive subscriptions. If your inbox goes quiet for 7+ days and the subscription lapses, Pipedream silently stops receiving events. Check Event History if you suspect a gap — you'll see no events rather than errors.

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 at least one person comfortable reading JavaScript, you need the filter logic to go beyond simple keyword matching, or you want to add a second action (like a Gmail auto-reply or a Notion log entry) in the same workflow without paying per step. Pipedream's Node.js code steps make custom parsing — stripping HTML, resolving label IDs to human names, formatting timestamps by timezone — trivial to add. If nobody on your team will touch code and you just need 'forward emails with this label to this channel,' Zapier's Gmail + Slack Zap gets the job done in 8 minutes with zero code.

Cost

Pipedream's free tier gives you 10,000 credits per month. This workflow costs roughly 2 credits per run — one for the trigger, one for the Slack step. At 50 emails per day that match your filter, that's 3,000 credits per month, well inside the free tier. At 200 matching emails per day, you're at 12,000 credits — just over the free limit. The next paid tier is $29/month for 100,000 credits, which handles up to 1,650 matching emails per day. Zapier's equivalent at that volume costs $49-$73/month depending on task count. Make handles 1,000 operations per month free and then $9/month for 10,000 — cheaper than Pipedream for low volume, but Make's Gmail trigger polls every 15 minutes instead of reacting instantly.

Tradeoffs

Zapier gets the Gmail label filter right out of the box in the trigger config — no code required. Make has a better visual router for sending one email to multiple Slack channels based on conditions. n8n's Gmail node lets you batch-fetch emails with full header access, which is useful if you're processing digest-style. Power Automate has native Office 365 Mail integration but its Gmail connector is third-party and unreliable for production use. Pipedream beats all of them on latency — the Pub/Sub webhook fires within 5-10 seconds of email delivery, whereas Make and Zapier poll at 1-15 minute intervals on most plans. If your team needs to react to customer emails within seconds, that gap matters.

Three things you'll hit after go-live. First, Gmail label IDs are not the same as label names. The API returns strings like `Label_1234567890` for custom labels — not 'vendor-invoices'. You need to call the Gmail Labels API once to map IDs to names, or hardcode the ID after finding it in the trigger payload. Second, forwarded email threads with long reply chains can produce a `snippet` that's mid-sentence from a reply, not the original message — always check what snippet you're actually displaying. Third, if the Gmail account receives more than ~500 emails per day total, Pub/Sub delivery can occasionally be delayed 1-3 minutes during peak periods. This is a Gmail API infrastructure constraint, not a Pipedream bug, and there's no workaround other than switching to polling at short intervals — which defeats the purpose.

Ideas for what to build next

  • Add a daily digest instead of per-email pingsSwap the instant trigger for a scheduled Pipedream workflow that runs at 9am, queries the Gmail API for all matching messages from the past 24 hours, and posts a single Slack digest. This is better for high-volume inboxes where per-email Slack pings become noise.
  • Route to different channels based on sender domainExtend the filter step to check the sender's domain and export a different `targetChannel` value for each — vendor emails go to #vendor-ops, customer emails go to #support, press emails go to #comms. One workflow replaces three.
  • Auto-reply to the sender via Gmail when the Slack message postsAdd a Gmail 'Send Email' step after the Slack step to fire an acknowledgment reply to the original sender — 'Your message has been received and routed to our team.' No extra workflow needed; it's a second step in the same flow.

Related guides

Was this guide helpful?
Slack + Gmail overviewPipedream profile →