Cloudflare邮件路由 cloudflare-email-routing

Cloudflare 邮件路由技能用于通过 Cloudflare Workers 实现电子邮件的接收、发送、转发和处理。它支持邮件过滤、允许列表、阻止列表、附件解析等功能,适用于构建邮件通知系统、支持票务系统、邮件自动化等场景。关键词:Cloudflare, 邮件路由, Email Workers, 邮件转发, 允许列表, 邮件处理, 电子邮件路由。

Serverless 0 次安装 0 次浏览 更新于 3/8/2026

名称: cloudflare-email-routing 描述: Cloudflare 电子邮件路由,用于通过 Workers 接收和发送电子邮件。适用于电子邮件工作者、转发、允许列表,或遇到电子邮件触发器错误、工作者调用失败、SPF 问题。

关键词: Cloudflare 电子邮件路由, 电子邮件工作者, 发送电子邮件, 接收电子邮件, 电子邮件转发, 电子邮件允许列表, 电子邮件阻止列表, postal-mime, mimetext, cloudflare:email, EmailMessage, ForwardableEmailMessage, EmailEvent, MX 记录, SPF, DKIM, 电子邮件工作者绑定, send_email 绑定, wrangler email, 电子邮件处理器, 电子邮件路由工作者, “Email Trigger not available”, “failed to call worker”, 电子邮件传递失败, 电子邮件未转发, 目标地址未验证 许可证: MIT 元数据: 版本: “2.0.0” 最后验证: “2025-11-18” 生产测试: true 令牌节省: “~60%” 防止错误: 8 包含模板: 0 包含参考: 1

Cloudflare 电子邮件路由

状态: 生产就绪 ✅ | 最后验证: 2025-11-18


什么是电子邮件路由?

两个能力:

  1. 电子邮件工作者 - 接收和处理传入的电子邮件(允许列表、转发、解析)
  2. 发送电子邮件 - 从 Workers 发送电子邮件到已验证的地址

两者都是免费的,并一起工作以实现完整的电子邮件功能。


快速开始(10 分钟)

第一部分:启用电子邮件路由

仪表板设置:

  1. 仪表板 → 域名 → 电子邮件电子邮件路由
  2. 启用电子邮件路由添加记录并启用
  3. 创建目标地址:
    • 自定义:hello@yourdomain.com
    • 目标:您的电子邮件
    • 通过电子邮件验证
  4. ✅ 基本转发激活

第二部分:接收电子邮件(电子邮件工作者)

安装依赖:

bun add postal-mime@2.5.0 mimetext@3.0.27

创建电子邮件工作者:

// src/email.ts
import { EmailMessage } from 'cloudflare:email';
import PostalMime from 'postal-mime';

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

    console.log('发件人:', message.from);
    console.log('主题:', email.subject);

    // 转发到目标地址
    await message.forward('you@gmail.com');
  }
};

配置 wrangler.jsonc:

{
  "name": "email-worker",
  "main": "src/email.ts",
  "compatibility_date": "2025-10-11",
  "node_compat": true  // 必需!
}

部署和连接:

bunx wrangler deploy

仪表板 → 电子邮件工作者 → 创建地址 → 选择工作者

第三部分:发送电子邮件

添加发送电子邮件绑定:

{
  "name": "my-worker",
  "main": "src/index.ts",
  "compatibility_date": "2025-10-11",
  "send_email": [
    {
      "name": "SES",
      "destination_address": "user@example.com"
    }
  ]
}

从工作者发送:

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

const msg = createMimeMessage();
msg.setSender({ name: 'App', addr: 'noreply@yourdomain.com' });
msg.setRecipient('user@example.com');
msg.setSubject('Hello!');
msg.addMessage({
  contentType: 'text/plain',
  data: 'Email body here'
});

const message = new EmailMessage(
  'noreply@yourdomain.com',
  'user@example.com',
  msg.asRaw()
);

await env.SES.send(message);

加载 references/setup-guide.md 以获取完整指南。


关键规则

始终要做 ✅

  1. 启用 node_compat: true 用于 postal-mime
  2. 在发送前验证目标地址
  3. 使用 postal-mime 解析 电子邮件内容
  4. 使用 mimetext 创建电子邮件
  5. 检查 message.from 用于允许列表
  6. 使用 message.forward() 转发(非手动)
  7. 处理错误(电子邮件传递可能失败)
  8. 用真实电子邮件测试(不仅仅是仪表板)
  9. 添加 MX 记录(通过仪表板自动)
  10. 记录电子邮件活动 用于调试

永远不要做 ❌

  1. 永远不要跳过 node_compat(postal-mime 需要它)
  2. 永远不要未经验证发送(传递失败)
  3. 永远不要在公共代码中硬编码电子邮件地址
  4. 永远不要跳过解析(原始电子邮件难以处理)
  5. 永远不要忽略垃圾邮件(实现允许列表/阻止列表)
  6. 永远不要超过 Gmail 限制(每天 500 封电子邮件到 Gmail)
  7. 永远不要跳过错误处理(电子邮件可能失败)
  8. 永远不要手动修改 DNS(使用仪表板)
  9. 永远不要在日志中暴露电子邮件内容(PII)
  10. 永远不要假设即时传递(电子邮件是异步的)

常见模式

允许列表

const allowlist = ['approved@domain.com'];

if (!allowlist.includes(message.from)) {
  message.setReject('未在允许列表中');
  return;
}

await message.forward('you@gmail.com');

阻止列表

const blocklist = ['spam@bad.com'];

if (blocklist.includes(message.from)) {
  message.setReject('已阻止');
  return;
}

await message.forward('you@gmail.com');

回复电子邮件

const msg = createMimeMessage();
msg.setSender({ addr: 'noreply@yourdomain.com' });
msg.setRecipient(message.from);
msg.setSubject(`回复: ${email.subject}`);
msg.addMessage({
  contentType: 'text/plain',
  data: '感谢您的电子邮件!'
});

const reply = new EmailMessage(
  'noreply@yourdomain.com',
  message.from,
  msg.asRaw()
);

await env.SES.send(reply);

解析附件

const parser = new PostalMime.default();
const email = await parser.parse(await new Response(message.raw).arrayBuffer());

for (const attachment of email.attachments) {
  console.log('文件名:', attachment.filename);
  console.log('类型:', attachment.mimeType);
  console.log('大小:', attachment.content.byteLength);
}

自定义路由逻辑

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

  // 基于主题路由
  if (email.subject.includes('[Support]')) {
    await message.forward('support@yourdomain.com');
  } else if (email.subject.includes('[Sales]')) {
    await message.forward('sales@yourdomain.com');
  } else {
    await message.forward('general@yourdomain.com');
  }
}

电子邮件消息属性

传入消息(ForwardableEmailMessage)

message.from        // 发件人电子邮件
message.to          // 收件人电子邮件
message.headers     // 电子邮件头
message.raw         // 原始电子邮件流
message.rawSize     // 大小(字节)

// 方法
message.forward(address)        // 转发到地址
message.setReject(reason)       // 拒绝电子邮件

解析的电子邮件(PostalMime)

email.from          // { name, address }
email.to            // [{ name, address }]
email.subject       // 主题行
email.text          // 纯文本正文
email.html          // HTML 正文
email.attachments   // 附件数组
email.headers       // 所有头

前 5 个防止的错误

  1. “Email Trigger not available”:启用 node_compat: true
  2. 目标未验证:验证所有发送目标
  3. Gmail 速率限制:每天最多 500 封电子邮件到 Gmail
  4. SPF permerror:使用仪表板配置 DNS
  5. 工作者调用失败:检查日志以查找解析错误

使用案例

使用案例 1:支持票务系统

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

  // 在数据库中创建票务
  await env.DB.prepare(
    'INSERT INTO tickets (email, subject, body, created_at) VALUES (?, ?, ?, ?)'
  ).bind(message.from, email.subject, email.text, Date.now()).run();

  // 发送确认
  const msg = createMimeMessage();
  msg.setSender({ addr: 'support@yourdomain.com' });
  msg.setRecipient(message.from);
  msg.setSubject('票务已创建');
  msg.addMessage({
    contentType: 'text/plain',
    data: '您的支持票务已创建。'
  });

  const confirmation = new EmailMessage(
    'support@yourdomain.com',
    message.from,
    msg.asRaw()
  );

  await env.SES.send(confirmation);
}

使用案例 2:电子邮件通知

export default {
  async fetch(request, env, ctx) {
    // 用户注册
    const { email, name } = await request.json();

    const msg = createMimeMessage();
    msg.setSender({ name: 'App', addr: 'noreply@yourdomain.com' });
    msg.setRecipient(email);
    msg.setSubject('欢迎!');
    msg.addMessage({
      contentType: 'text/html',
      data: `<h1>欢迎, ${name}!</h1>`
    });

    const message = new EmailMessage(
      'noreply@yourdomain.com',
      email,
      msg.asRaw()
    );

    await env.SES.send(message);

    return new Response('欢迎电子邮件已发送!');
  }
};

使用案例 3:带有过滤的电子邮件转发

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

  // 过滤垃圾关键词
  const spamKeywords = ['viagra', 'lottery', 'prince'];
  const isSpam = spamKeywords.some(keyword =>
    email.subject.toLowerCase().includes(keyword) ||
    email.text.toLowerCase().includes(keyword)
  );

  if (isSpam) {
    message.setReject('检测到垃圾邮件');
    return;
  }

  await message.forward('you@gmail.com');
}

何时加载参考

加载 references/setup-guide.md 当:

  • 第一次设置电子邮件路由时
  • 配置 MX 记录时
  • 设置电子邮件工作者时
  • 配置发送电子邮件绑定时
  • 需要完整指南时

使用捆绑资源

参考 (references/):

  • setup-guide.md - 完整设置指南(启用路由、电子邮件工作者、发送电子邮件)
  • common-errors.md - 所有 8 个记录的错误及解决方案和预防
  • dns-setup.md - MX 记录、SPF、DKIM 配置指南
  • local-development.md - 本地测试和开发模式

模板 (templates/):

  • receive-basic.ts - 基本电子邮件接收工作者
  • receive-allowlist.ts - 电子邮件允许列表实现
  • receive-blocklist.ts - 电子邮件阻止列表实现
  • receive-reply.ts - 自动回复电子邮件工作者
  • send-basic.ts - 基本发送电子邮件示例
  • send-notification.ts - 通知电子邮件模式
  • wrangler-email.jsonc - 电子邮件路由的 Wrangler 配置

官方文档


问题?问题?

  1. 检查 references/setup-guide.md 以获取完整设置
  2. 验证 wrangler.jsonc 中的 node_compat: true
  3. 确认目标地址已验证
  4. 检查日志以查找错误