INTEGRITY Cloudflare Docs

Email routing

Test email routing behavior locally using wrangler dev to simulate incoming emails and verify your routing logic before deploying.

Prerequisites

  1. Sign up for a Cloudflare account.
  2. Install Node.js.

Node.js version manager

Use a Node version manager like Volta or nvm to avoid permission issues and change Node.js versions. Wrangler, discussed later in this guide, requires a Node version of 16.17.0 or later.

Configuration

Configure your Wrangler file:

{
	"name": "email-routing-worker",
	// Set this to today's date
	"compatibility_date": "2026-08-28",
}
name = "email-routing-worker"
# Set this to today's date
compatibility_date = "2026-08-28"

Basic routing worker

import * as PostalMime from "postal-mime";

export default {
	async email(message, env, ctx) {
		// Parse the raw email message
		const parser = new PostalMime.default();
		const rawEmail = new Response(message.raw);
		const email = await parser.parse(await rawEmail.arrayBuffer());

		console.log("Received email:", {
			from: message.from,
			to: message.to,
			subject: email.subject,
			text: email.text,
			html: email.html,
		});

		// Route based on recipient
		if (message.to.includes("support@")) {
			await message.forward("[email protected]");
		} else {
			await message.forward("[email protected]");
		}
	},
};

Testing

Start your development server:

npx wrangler dev

Send a test email using the local endpoint. The request body must be a raw email message in RFC 5322 format, and the message must include a Message-ID header:

curl --request POST 'http://localhost:8787/cdn-cgi/handler/email' \
  --url-query '[email protected]' \
  --url-query '[email protected]' \
  --data-raw 'Received: from smtp.example.com (127.0.0.1)
        by cloudflare-email.com (unknown) id 4fwwffRXOpyR
        for <[email protected]>; Tue, 27 Aug 2024 15:50:20 +0000
From: "John" <[email protected]>
Reply-To: [email protected]
To: [email protected]
Subject: Testing Email Workers Local Dev
Content-Type: text/html; charset="windows-1252"
X-Mailer: Curl
Date: Tue, 27 Aug 2024 08:49:44 -0700
Message-ID: <6114391943504294873000@ZSH-GHOSTTY>

Hi there'

This will output the parsed email structure in the console:

{
	"headers": [
		{
			"key": "received",
			"value": "from smtp.example.com (127.0.0.1) by cloudflare-email.com (unknown) id 4fwwffRXOpyR for <[email protected]>; Tue, 27 Aug 2024 15:50:20 +0000"
		},
		{ "key": "from", "value": "\"John\" <[email protected]>" },
		{ "key": "reply-to", "value": "[email protected]" },
		{ "key": "to", "value": "[email protected]" },
		{ "key": "subject", "value": "Testing Email Workers Local Dev" },
		{ "key": "content-type", "value": "text/html; charset=\"windows-1252\"" },
		{ "key": "x-mailer", "value": "Curl" },
		{ "key": "date", "value": "Tue, 27 Aug 2024 08:49:44 -0700" },
		{
			"key": "message-id",
			"value": "<6114391943504294873000@ZSH-GHOSTTY>"
		}
	],
	"from": { "address": "[email protected]", "name": "John" },
	"to": [{ "address": "[email protected]", "name": "" }],
	"replyTo": [{ "address": "[email protected]", "name": "" }],
	"subject": "Testing Email Workers Local Dev",
	"messageId": "<6114391943504294873000@ZSH-GHOSTTY>",
	"date": "2024-08-27T15:49:44.000Z",
	"html": "Hi there\n",
	"attachments": []
}

Next steps