跳到主要内容

《林一的 Cloudflare 通关记》第 13 篇-连邮件也能搞定——Email Routing 邮件转发

· 阅读需 13 分钟

《林一的 Cloudflare 通关记》第 13 篇

Access 配好后的第二天,小王风风火火地冲过来。

"林一,客户要个联系方式!我在官网上挂了个 contact@星火ai.com,但这个邮箱不存在啊,邮件发出去全弹回来了。"

故事引入

"那得搞个企业邮箱吧?"林一打开浏览器搜了搜,"阿里云企业邮箱,最低套餐 600 块一年。腾讯企业邮箱现在也要收费了……"

"又花钱?"老张不知道什么时候走到了背后,"你的域名在 Cloudflare 上吧?"

"对。"

"Cloudflare 有 Email Routing,免费帮你收邮件,转发到你个人邮箱就行。contact@星火ai.com 收到的邮件,自动转到你的 Gmail。"

"这么省?"

"创业公司不寒碜,能省则省。"老张坐下来,"不过它主要是收邮件的,发送邮件得另外想办法——Cloudflare 现在也有邮件发送功能,但需要 Workers 付费版。免费的方案也有,待会一起说。"


技术讲解

邮件收发的基本原理

"先快速过一下邮件是怎么收发的,"老张在白板上画了个简图:

发邮件(发送方 → 收件方):
发件人 → SMTP服务器 → 收件方SMTP服务器 → 收件人邮箱

收邮件(收件方 → 本地邮箱):
收件方SMTP服务器 ← MX记录指向 → 你的域名DNS

"关键在 MX 记录——它告诉互联网'发到 @星火ai.com 的邮件应该交给哪个服务器'。你把 MX 记录指向 Cloudflare,Cloudflare 就替你收邮件。"

"这个我知道,"林一点头,"就像 DNS 的 A 记录指向网站服务器一样,MX 记录指向邮件服务器。"

"对,不多说了。重点看 Cloudflare Email Routing 能干什么。"

A记录 vs MX记录


Cloudflare Email Routing 的工作原理

老张画了张流程图:

客户发邮件到 contact@星火ai.com


┌──────────────┐
│ Cloudflare │ ← MX记录指向Cloudflare
│ 邮件服务器 │
└──────┬───────┘
│ 根据转发规则匹配收件地址

┌──────────────┐
│ 转发规则匹配 │ contact@ → 转发到 linyi@gmail.com
└──────┬───────┘
│ 转发邮件

┌──────────────┐
│ 你的个人邮箱 │ linyi@gmail.com 收到邮件
└──────────────┘

"注意一个关键点:Cloudflare 不存储邮件。它只是个'转发站'——收到邮件,立刻按规则转发到你指定的目标邮箱。邮件最终存在你的 Gmail/QQ 邮箱里。"

"那和 Gmail 的自动转发有什么区别?"

"区别大了。Gmail 转发是'先收再转'——邮件先到 Gmail 服务器,再转发。而 Email Routing 是'域名级别'的——contact@星火ai.com 这个地址根本不存在实体邮箱,它就是个别名,Cloudflare 直接把邮件改投到你的真实邮箱。"

"相当于一个邮件层的反向代理?"

"没错!跟 Cloudflare 代理 HTTP 请求一个道理——用户访问的是 admin.星火ai.com,但实际响应的是你的 Worker。邮件也是——发件人发到 contact@星火ai.com,实际收到的是你的 Gmail。"

Cloudflare Email Routing 工作原理


Email Routing 能做什么?

功能说明
按地址转发contact@ → 你的邮箱,support@ → 客服邮箱
Catch-all 转发任何 @星火ai.com 的邮件都转发到一个邮箱
Email Worker不转发,而是交给 Worker 处理——存数据库、调 API、自动回复
自动 DNS 配置启用时自动添加 MX、SPF、DKIM 记录

国内类比:类似阿里云/腾讯云企业邮箱的"邮件转发"功能,但那些通常绑定在企业邮箱套餐里(需要付费),Cloudflare 的 Email Routing 是完全免费的,而且支持 Worker 编程化处理。

Email Routing 能做什么


实操指导

第一步:启用 Email Routing

"开始配置。"老张打开 Cloudflare Dashboard。

  1. 进入 Cloudflare Dashboard → 选择你的域名 星火ai.com
  2. 左侧菜单 → EmailEmail Routing
  3. 第一次进入会看到引导页面,点击 Get started

Cloudflare 会自动帮你添加三条 DNS 记录:

记录类型名称作用
MX星火ai.comroute1.mx.cloudflare.net(优先级 69)告诉互联网发到这个域名的邮件交给 Cloudflare
MX星火ai.comroute2.mx.cloudflare.net(优先级 4)备用 MX 服务器
MX星火ai.comroute3.mx.cloudflare.net(优先级 13)备用 MX 服务器
TXT星火ai.comv=spf1 include:_spf.mx.cloudflare.net ~allSPF 记录,授权 Cloudflare 处理你的邮件
TXT_dmarcDMARC 策略DMARC 记录,防止邮件被冒充

"这些全都是自动的?"林一问。

"全自动。因为你域名 DNS 在 Cloudflare 上(还记得第 1 篇说的吗?域名托管在 Cloudflare 的好处),一键搞定。如果 DNS 不在 Cloudflare 上,你就得手动去注册商后台一条条加这些记录,光 MX 记录就三条,还有 SPF 和 DMARC……"

"又是一个'把域名放在 Cloudflare 上就省事'的理由。"

"对。DNS 托管、SSL 证书、CDN、邮件路由——全部一键打通。这就是生态的力量。"

  1. 点击 Done,等待 DNS 生效(通常 5-15 分钟)

第二步:添加目标邮箱

"转发到哪里?得先验证你的目标邮箱。"

  1. 在 Email Routing 页面 → Destination addresses 标签
  2. 输入你的个人邮箱,比如 linyi@gmail.com
  3. Cloudflare 会发一封验证邮件到这个地址
  4. 打开邮件,点击 Verify email address

"为什么要验证?"

"防止你把邮件转发到一个不属于你的邮箱——不然任何人都能配置 ceo@apple.com 的转发规则了。"

"那能转发到多个邮箱吗?"

"可以。每个目标地址都要单独验证。验证一次以后,所有域名下的转发规则都能复用。"


第三步:创建转发规则

"现在来配 contact@ 邮箱。"

  1. 在 Email Routing 页面 → Routing rules 标签
  2. 点击 Create routing rule

配置规则:

字段填写说明
Email patterncontact匹配 contact@星火ai.com
ActionSend to an email转发到邮箱
Destinationlinyi@gmail.com你刚验证的目标邮箱
  1. 点击 Save

"来试试。"老张用自己的手机给 contact@星火ai.com 发了封测试邮件。

30 秒后,林一的 Gmail 收到了。

"成了!"林一兴奋地打开邮件,发件人显示的是老张的邮箱地址,但收件人是 contact@星火ai.com

"注意看,"老张指了指邮件头,"Cloudflare 会加一个 X-Forwarded-To 的头,标识这封邮件是转发过来的。"


第四步:配置 Catch-all(全量接收)

"如果有人发到 random@星火ai.com,但你没有配转发规则怎么办?"

"弹回去?"

"默认是的。但你可以开 Catch-all——所有没匹配到规则的邮件,统一转发到一个邮箱。"

  1. 在 Routing rules 页面底部找到 Catch-all address
  2. 开启开关
  3. Action 选 Send to an email,目标选你的邮箱
  4. 保存

"这样不管别人发到 support@hr@ 还是 abcdef@,全都能收到。"

Catch-all 万能收件箱

"这个功能好!"小王凑过来看,"我以后名片上印 xiaowang@星火ai.com,邮件直接到我邮箱,还不用单独配。"

"对,Catch-all 就是个'万能收件箱'。不过要注意垃圾邮件——开了 Catch-all 意味着所有地址都能收到邮件,垃圾邮件也会进来。建议配合 Cloudflare 的邮件过滤使用。"


第五步:Email Worker——用代码处理邮件

"光转发还不够酷,"老张搓了搓手,"Email Routing 还能跟 Workers 结合——收到邮件后不转发,而是交给 Worker 处理。"

"能干什么?"

"什么都行——存到 D1 数据库、调 AI 分析邮件内容、自动回复、转发到 Slack Webhook……你写代码就行。"

"来个实际例子——收到客户邮件自动存到数据库并发送确认回信。"

先在 wrangler.toml 里配置 Email Worker:

name = "email-handler"
main = "src/index.js"
compatibility_date = "2024-09-01"

# Email Routing 绑定
[[email]]
name = "EMAIL_HANDLER"

# D1 数据库绑定(第9篇配的)
[[d1_databases]]
binding = "DB"
database_name = "xinghuo-db"
database_id = "你的数据库ID"

Worker 代码:

export default {
// 处理 HTTP 请求(正常的 API)
async fetch(request, env, ctx) {
return new Response("Email Worker is running");
},

// 处理收到的邮件
async email(message, env, ctx) {
// 1. 获取邮件信息
const from = message.from; // 发件人
const to = message.to; // 收件人
const subject = message.headers.get("subject"); // 邮件主题

// 2. 读取邮件正文
const rawEmail = await new Response(message.raw).text();

// 3. 存到 D1 数据库
await env.DB.prepare(
`INSERT INTO emails (from_address, to_address, subject, body, created_at)
VALUES (?, ?, ?, ?, datetime('now'))`
).bind(from, to, subject, rawEmail).run();

// 4. 同时转发到林一的个人邮箱(保留转发功能)
await message.forward("linyi@gmail.com");

// 5. 记录日志
console.log(`收到邮件: ${from}${to} | 主题: ${subject}`);
},
};

"看到了吧?email() 这个 handler 就是专门处理收到的邮件的。message 对象里有发件人、收件人、邮件头和原始邮件内容。你可以读邮件内容、存数据库、转发、调 API——什么都行。"

"那怎么把 Worker 和 Email Routing 绑定?"

"在 Email Routing 的 Routing rules 里,Action 不选 'Send to an email',而是选 Send to a Worker,然后选你部署好的 Email Worker。"

Routing rule:
Email pattern: contact@星火ai.com
Action: Send to a Worker
Worker: email-handler

"这样 contact@星火ai.com 收到的邮件就不会转发到邮箱了,而是交给 Worker 处理。Worker 里你可以同时做转发和存库——两不误。"

Email Worker 处理邮件


发送邮件怎么办?

"收邮件搞定了,"林一问,"那发邮件呢?小王说要从 contact@星火ai.com 给客户回邮件。"

"这个确实是 Email Routing 的短板——它只管收,不管发。"老张想了想,"不过现在有几个方案。"

发送邮件的三方案

方案一:Cloudflare Email Sending(官方方案,需付费)

"Cloudflare 2024 年底推出了邮件发送功能,目前是 Beta。可以直接在 Worker 里用 EMAIL binding 发邮件:

// wrangler.toml
// [[send_email]]
// name = "EMAIL"

export default {
async fetch(request, env, ctx) {
await env.EMAIL.send({
to: "customer@example.com",
from: "contact@星火ai.com",
subject: "感谢您的来信",
html: "<h1>您好!</h1><p>我们已收到您的邮件,会尽快回复。</p>",
text: "您好!我们已收到您的邮件,会尽快回复。",
});
return new Response("邮件已发送");
},
};

"代码很简洁,但问题是——这个功能目前需要 Workers Paid Plan(每月 $5)。免费版用不了。"

方案二:用 Gmail 代发(免费)

"最省钱的方案——在 Gmail 设置里添加'以其他地址发送邮件',通过 Gmail 的 SMTP 服务器以 contact@星火ai.com 的身份发邮件。"

  1. Gmail → 设置 → 账户和导入 → "添加其他电子邮件地址"
  2. 输入 contact@星火ai.com
  3. SMTP 服务器填 Gmail 的(smtp.gmail.com,端口 587)
  4. 用你自己的 Gmail 账号验证

"这样你在 Gmail 里写信,发件人可以选 contact@星火ai.com。收件人看到的就是企业邮箱地址,但实际通过 Gmail 发出。"

"免费?"

"完全免费。但注意——这种方式发出去的邮件,SPF 和 DKIM 验证可能不完美,有些严格的邮箱(比如 Outlook)可能标记为可疑。对于创业公司初期够用了。"

方案三:第三方邮件服务(免费额度)

"如果需要从代码里发邮件(比如注册确认邮件、密码重置),用第三方邮件 API:

服务免费额度特点
Resend每月 3000 封 / 100 封/天API 友好,有 Node SDK
Brevo (Sendinblue)每月 300 封老牌服务
Mailgun前 3 个月 5000 封/月之后付费

"在 Worker 里调这些服务的 API 就行,几十行代码搞定。"

// 用 Resend 发邮件的示例
export default {
async fetch(request, env, ctx) {
const res = await fetch("https://api.resend.com/emails", {
method: "POST",
headers: {
"Authorization": `Bearer ${env.RESEND_API_KEY}`,
"Content-Type": "application/json",
},
body: JSON.stringify({
from: "contact@星火ai.com",
to: "customer@example.com",
subject: "感谢您的来信",
html: "<p>我们已收到您的邮件</p>",
}),
});
return new Response("邮件已发送");
},
};

"把 RESEND_API_KEY 放到 Worker 的环境变量里就行。"


Email Routing 的局限性

"总结一下 Email Routing 的限制,别踩坑:"

限制说明
只能收不能发Email Routing 本身只处理入站邮件,发邮件需要其他方案
不存储邮件邮件收到后立即转发/处理,不会存在 Cloudflare 上
需要 Cloudflare DNSMX 记录必须在 Cloudflare 上管理,不能用其他 DNS
转发延迟通常几秒到几分钟,不是实时的
附件大小限制25MB(与标准邮件一致)
目标邮箱需验证转发目标必须先验证所有权

小结与预告

本篇知识点回顾

知识点要点
Email Routing 原理MX 记录指向 Cloudflare → 收到邮件 → 按规则转发/处理
自动 DNS 配置启用时自动添加 MX、SPF、DKIM 记录(域名需在 Cloudflare 上)
转发规则按地址匹配转发到指定邮箱
Catch-all所有未匹配的邮件统一转发,适合小团队
Email Workeremail() handler 处理收到的邮件,可存库/调 API/自动回复
发送邮件方案Cloudflare Email Sending(付费)/ Gmail 代发(免费)/ Resend 等(免费额度)
局限性只收不发、不存储、需 Cloudflare DNS

动手挑战

基础挑战:在你的域名上启用 Email Routing,配置 contact@你的域名 转发到你的个人邮箱。用另一个邮箱发测试邮件,确认能收到。

进阶挑战:写一个 Email Worker,收到邮件后把发件人、主题、时间存到 D1 数据库(参考第 9 篇的 D1 操作),同时自动回复一封"我们已收到您的邮件"的确认信。提示:

  1. wrangler.toml 里配置 [[email]][[d1_databases]] 绑定
  2. email() handler 里读邮件内容、写数据库
  3. 用 Resend API 或 Cloudflare Email Sending 发送确认回信

思考题:如果你开了一个 support@ 邮箱,想收到邮件后自动在 Slack 群里发一条通知——你会怎么实现?(提示:Email Worker + Slack Webhook URL,fetch() 发 POST 请求到 Slack 的 Incoming Webhook 地址。)

下回预告

"邮件搞定了!"小王满意地走了。林一长舒一口气,转头看老张。

"张哥,功能差不多齐了吧?DNS、SSL、CDN、Pages、Workers、AI、R2、KV、D1、Turnstile、WAF、Access、Email——还差啥?"

"上线前还有一件事。"老张指着 Dashboard 上的一个标签页。

"Analytics?"

"你的网站跑得快不快?哪里慢?有多少人访问?有没有出错?这些你都不知道就上线,那叫'蒙眼狂奔'。明天教你看看数据——上线前的体检报告。"

下篇预告:《上线前的"体检报告"——Analytics 与性能监控》

wp