目录

使用 CloudFlare Workers、MailChannels API 邮件发送

用途

  1. 用户注册,邮箱用于验证码接收。

  2. 应用或网站订阅内容推送。

为什么选择CloudFlare

  • 费用低。
  • 服务稳定。❓❓❓
  • 方便集成CloudFlare提供的各种服务中。

绑定域名

主域名绑定到 CloudFlare 中,网站配置开启邮件路由(Email Routing)。

https://image.ericzzz.com/2024%2F03%2F15%2F811d1a6f-e25f-4f3e-a7db-b9097c96dc2a.webp

配置 DNS

以下配置中myaccount.workers.dev,可以在 Cloudflare dashboard Workers&Pages 页面中寻找,如下图。

https://image.ericzzz.com/2024%2F03%2F15%2F1c0df914-3e74-4f55-ab2e-e8c0704c4b83.webp

  1. 配置_mailchannelsDNS 解析。
Type Name Content
TXT _mailchannels v=mc1 cfid=myaccount.workers.dev
  1. 配置 SPFDNS 解析。
Type Name Content
TXT @ v=spf1 include:_spf.mx.cloudflare.net include:relay.mailchannels.net -all

https://image.ericzzz.com/2024%2F03%2F15%2Fd90fc9b2-c7e1-4b4b-9d17-2c8dab387617.webp

  1. 选配DKIM(暂时略过)

新建 Workers 项目

  1. 使用Wrangler命令行工具创建项目。
1
wrangler init send-mail-service
  1. 调用MailChannelsAPI 服务发送邮件,以下是index.js文件内容。
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
export default {
  async fetch(request, env, ctx) {
    if (request.method !== "POST") {
      return new Response("Request method must be POST");
    }
    const contentType = request.headers.get("content-type");

    if (contentType === null || !contentType.includes("application/json")) {
      return new Response("Request body must be JSON", {
        status: 400
      });
    }
    // 获取 request body 数据,使用 JSON 获取
    const jsonObj = await request.json();
    if (!this.checkOrGetFormData(jsonObj)) {
      return new Response("Request params error", {
        status: 400
      });
    }

    this.sendEmail(jsonObj);
    return new Response("ok");
  },

  checkOrGetFormData(jsonObj) {
    let allFieldsValid = true;
    const keys = ["recipient_email", "sender_email", "sender_name", "subject", "message"];
    // 判断字段是否不为空
    if (Object.keys(jsonObj).length === 0) {
      allFieldsValid = false;
    }
    keys.forEach(key => {
      if (jsonObj[key] === undefined || jsonObj[key] === '') {
        allFieldsValid = false;
      }
    });
    return allFieldsValid;
  },

  sendEmail(data) {

    fetch("https://api.mailchannels.net/tx/v1/send", {
      method: "POST",
      headers: {
        "content-type": "application/json"
      },
      body: JSON.stringify({
        personalizations: [{
          to: [{
            email: data.recipient_email,
            name: data.recipient_email
          }]
        }],
        from: {
          email: data.sender_email,
          name: data.sender_name
        },
        subject: data.subject,
        content: [{
          "type": "text/plain",
          "value": "Test message content\n\n" + data.message,
        }]
      })
    });
  },
};	  
  1. 部署到 CloudFlare Workers 中
1
wrangler deploy
  1. 测试

使用 Http 调试工具,我使用的是 Apifox

  • POST 请求
1
2
3
4
5
6
7
{
	"recipient_email": "[email protected]",
	"sender_email": "[email protected]",
	"sender_name": "Test",
	"subject": "Hello Guy!",
	"message": "My first email sent!"
}
  • recipient_email: 接收邮箱。
  • sender_email:发送邮箱。
  • sender_name:发送名称。
  • subject:主题。
  • message:邮件内容。

https://image.ericzzz.com/2024%2F03%2F15%2F8664249f-cf01-41a8-bb5c-e663a96a645e.webp

遇到的问题

  1. 经常发送后,没收到邮件。

  2. 国内邮箱还没接收成功。

参考文档

Cloudflare Email Worker as a Service / API. Cloudflare Email Routing 免费邮件发送(作为 Service 服务)用于 Workers/Pages 项目中

Sending Email from Cloudflare Workers using MailChannels Send API

官方文档:MailChannels Pages Plugin