tech/cloudflare/email

EMAIL

Cloudflare Email Routing — inbound email processing in Workers + MailChannels outbound.

production Cloudflare Workers, Email Routing
improves: tech/cloudflare

Cloudflare Email Routing

Email Routing lets you process inbound email inside a Worker via the email event handler. MailChannels integration enables outbound transactional email — no separate ESP required.

Free on any Cloudflare-managed domain.

wrangler.toml

[[email]]
type = "receive"
name = "email-handler"
destination_address = "worker"   # routes all matched email to your Worker

Inbound — receiving email in a Worker

import { EmailMessage } from 'cloudflare:email';
import { createMimeMessage } from 'mimetext';

export default {
  async email(message: EmailMessage, env: Env, ctx: ExecutionContext) {
    // Reject spam before processing
    if (message.headers.get('x-spam-flag') === 'YES') {
      message.setReject('Spam rejected');
      return;
    }

    // Read raw MIME content
    const rawEmail = await new Response(message.raw).text();

    // Forward to another address
    await message.forward('penny@2nth.ai');

    // Or trigger an AI workflow with the email body
    await env.QUEUE.send({
      type: 'email_intake',
      from: message.from,
      subject: message.headers.get('subject'),
      body: rawEmail,
    });
  }
};

Outbound — sending email via MailChannels

async function sendEmail(params: {
  to: string;
  subject: string;
  html: string;
  from?: string;
}, env: Env): Promise<void> {
  const response = await fetch('https://api.mailchannels.net/tx/v1/send', {
    method: 'POST',
    headers: { 'content-type': 'application/json' },
    body: JSON.stringify({
      personalizations: [{ to: [{ email: params.to }] }],
      from: { email: params.from ?? 'penny@2nth.ai', name: 'Penny — 2nth.ai' },
      subject: params.subject,
      content: [{ type: 'text/html', value: params.html }],
    }),
  });

  if (!response.ok) {
    throw new Error(`MailChannels error: ${response.status}`);
  }
}

Common Gotchas

See Also