DocumentationEmail to Slack

Email to Slack

Forward email to Slack automatically. Receive an email as JSON, filter senders, format a safe Slack message, and deliver it with an incoming webhook.

Plenty of useful things still arrive as email: support requests, server alerts, order confirmations, form submissions that only email you, vendor notifications. The trouble is that email is where they go to be missed. You want each of those messages to land in a Slack channel automatically, where your team actually looks.

Webhook Relay can receive emails as webhooks. You give an inbox a unique address, every message sent to it is parsed into JSON, and a small transform reshapes it into the format Slack expects before delivery — no mail server, no glue code, no polling.

Build the message visually: the free webhook → Slack/Discord/Teams formatter lets you template the Slack message from a sample payload and copy the transform.

How it works

The whole path is a single hop with a transform in the middle:

inbound email  ──▶  Webhook Relay (parse)  ──▶  transform to Slack { text }  ──▶  Slack channel

When an email hits your Webhook Relay address, it's parsed into a structured JSON document and POSTed to the bucket's outputs. A Slack incoming webhook doesn't understand that shape — it only accepts { "text": "..." } or a Block Kit blocks array — so the transform converts one into the other in flight.

The parsed email looks like this:

{
  "from": "[email protected]",
  "from_name": "Jon Snow",
  "recipient": "<uuid>@in.webhookrelay-mail.com",
  "subject": "Order #4821 confirmed",
  "date": "Fri, 26 Jun 2026 11:27:41 +0400",
  "text": "plain body",
  "html": "<p>html body</p>",
  "spf": "pass",
  "dkim": "pass",
  "dmarc": "pass",
  "attachments": [
    { "name": "invoice.pdf", "content_type": "application/pdf", "size": 48213, "content": "<base64>", "truncated": false }
  ]
}

See the full payload reference for every field, including to, cc, message_id and the raw headers map.

Setup

1. Create a bucket. This is the container that ties an input to its outputs.

2. Add an email input. Webhook Relay gives you back a unique address of the form <uuid>@in.webhookrelay-mail.com. Anything sent there is parsed and forwarded to the bucket's outputs.

3. Add a Slack output. Create a Slack incoming webhook URL (https://hooks.slack.com/services/T0000/B0000/XXXXXXXX) for the channel you want to post to, and add it as the bucket's output destination. Each Slack incoming webhook is bound to one channel.

4. Attach the transform. Add the transform function below so the parsed email is reshaped into Slack's format before it's delivered.

5. Send a test email. Email your <uuid>@in.webhookrelay-mail.com address from any client. Within a second or two the message appears in your Slack channel. If it doesn't, open the request log in your dashboard to see exactly what was received and delivered.

The transform

Webhook Relay functions hand you the incoming request body as a string in r.body. Parse it, build the Slack payload, and write it back with r.setBody:

const email = JSON.parse(r.body)
const subject = String(email.subject || "(no subject)")
const sender = String(email.from_name || email.from || "unknown sender")
const body = String(email.text || "").slice(0, 2800)

if (email.spf === "fail" || email.dmarc === "fail") {
  r.stopForwarding()
  return
}

const slack = {
  text: `Email from ${sender}: ${subject}`,
  blocks: [
    {
      type: "section",
      text: { type: "mrkdwn", text: `:email: *${subject}*\nFrom: ${sender}` }
    },
    { type: "section", text: { type: "mrkdwn", text: body || "_(empty body)_" } }
  ]
}

r.setBody(JSON.stringify(slack))
r.setHeader("Content-Type", "application/json")

This uses Slack's documented text and blocks fields, keeps a plain-text fallback for notifications, and caps the body so a very long email does not create an invalid message. The SPF/DMARC check is an additional guard, not a replacement for the From-address allowlist.

From here the function is where the real power is. Swap the flat string for a Slack Block Kit blocks array to render the subject, sender and body as a formatted message with fields, dividers and buttons. You can also fan out to multiple channels by adding more outputs — one Slack incoming webhook per channel, or Slack and Discord at once — and shape the payload differently for each. To keep noise down, restrict who can email the address with the From-address allowlist, or inspect email.from / email.spf inside the function and return early to drop anything you don't want forwarded.

Troubleshooting

  • Slack returns invalid_payload: inspect the transformed body and confirm the output function ran. The final body must be JSON and include text or valid Block Kit blocks.
  • Messages contain raw HTML: use email.text, not email.html, for the basic template. Convert or sanitize HTML explicitly if the plain-text part is absent.
  • Legitimate mail is dropped: authentication results depend on how the sender's domain is configured. Start with an address allowlist, review captured SPF/DKIM/DMARC values, and only then enable automatic rejection.
  • Attachments do not appear: Slack incoming webhooks do not accept an email attachment object. Upload files with Slack's file API in a separate, authenticated workflow, or link to approved storage.

Get started

Turning inbound mail into Slack messages is one case of a broader pattern: Email to Webhook. Once an email is JSON, you can route it anywhere a webhook can go.

Create a free Webhook Relay account, add an email input, and have support requests, alerts and confirmations flowing into Slack in a few minutes.

Frequently asked questions

Can Slack receive an email through a webhook?

A Slack incoming webhook cannot parse email directly. Webhook Relay receives the email, converts it to JSON, and a JavaScript function maps the subject, sender and body to Slack's text or Block Kit format.

How do I stop unwanted email reaching Slack?

Use an inbound-email sender or domain allowlist, then optionally inspect from, SPF, DKIM and DMARC values in the transform before forwarding.

Can I forward one email to several Slack channels?

Yes. Add one output per Slack incoming webhook. Each Slack webhook is tied to a channel, and every output can have its own filtering or formatting function.

Did this page help you?