Forwards incoming email to a Discord channel. Runs on Cloudflare Email Routing + Workers.
Email Routing hands the raw message to this worker's email() handler. It gets parsed with postal-mime, HTML is converted to Discord markdown (links become [text](url)), and the result is posted to a Discord webhook as an embed: subject as title, sender as author, To/From in the footer.
Long emails get trimmed to fit Discord's embed limits. If the body doesn't fit, the full text is attached as email-full.txt instead. Webhook posts retry on rate limits, 5xx, and network errors with backoff.
If posting to Discord fails (or DISCORD_WEBHOOK_URL isn't set), the original email is forwarded to FALLBACK_EMAIL instead, when set. See Env vars below for what happens when either is missing.
You need a Cloudflare account with Email Routing set up on the domain, and a Discord webhook URL for the target channel (channel settings → Integrations → Webhooks → New Webhook → Copy Webhook URL).
pnpm install
pnpm wrangler secret put DISCORD_WEBHOOK_URL
pnpm wrangler secret put FALLBACK_EMAIL # optionalThen in the Cloudflare dashboard, under Email Routing → Routing rules, point the address you want to catch at this worker.
| Command | Purpose |
|---|---|
pnpm dev |
Local dev (wrangler dev) |
pnpm deploy |
Deploy |
wrangler dev won't trigger email(), that only fires through real Email Routing once deployed. Use wrangler tail to check behavior after deploying.
DISCORD_WEBHOOK_URL— Discord webhook to post emails to. Without it, the worker just forwards toFALLBACK_EMAIL(if set) and does nothing else.FALLBACK_EMAIL— backup address that gets a copy only when the Discord post fails. Without it, a failed Discord post loses that email for good.
File attachments are capped at 10MB, Discord's default for non-boosted servers (boosted servers get 50-100MB, but the worker has no way to know the target server's boost level). Anything over that gets truncated on a UTF-8 boundary instead of a raw byte cut.
Email size itself is capped by Cloudflare's Email Routing limits.