如何用 AWS 实现邮件发送和接收

SES

SES 全名 Simple Email Service,是 Amazon 提供的电子邮件发送服务。

配置 SES

在使用 SES 发送电子邮件之前,需要配置在 Amazon 中配置一下。

进入 SES 服务中,点击 Identities,并点击 Create identity 按钮:

image-20240413130536802

接着选择 Identity type,这将决定使用特定的 Domain 发送邮件还是仅使用特定的邮箱发送。

image-20240413131603352

  • 选择 Email Address 配置邮箱发送。

    image-20240413131758848

    填写好 Email 地址后,点击确定创建。

    Amazon 会给该邮箱发送一个验证邮件。

    img

    点击 URL 确认。

    再返回 AWS 控制台的 Identities 管理页面,当显示该 Email 地址为Verified后即代表生效。

    image-20240413132729203

  • 选择 Domain type 配置 Domain 发送。

    我们经常会收到这样一种邮件,它来自于某个网站,它可能长这样:

    image-20240420210724843

    其中 algolia.com就是域名。no-reply@algolia.com是来自于这个域名的。

    为了实现这个目标,我们需要在 SES 中配置 Domain。

    image-20240420212220530

    输入对应的域名后,点击 Create identity 按钮。

    接着就会看到一段信息:

    image-20240420212815689

    在 publish record 中找到对应的 CNAME,拷贝到域名托管的 DNS 记录中。

    image-20240420213025247

    如果你的域名是用 Route 53 托管的,那么 AWS 会自动帮你添加到 Route 53 中。

    如果你的域名用其他平台(腾讯云、阿里云),则需要手动拷贝记录到 DNS 记录中。

    由于我的域名是交给 Route 53 托管的,所以会自动帮我拷贝过去。

    image-20240420213624251

    然后等待审核,审核通过后也会有一个 Verified 状态。

    image-20240413132617071

    当看到这个状态,意味着配置生效了。

发送测试邮件

我们以 domain 为例,点击发送测试邮件。

image-20240420214247970

然后填写 no-reply 作为 subdomain,填写你想要送达的邮箱地址和邮件内容:

image-20240420214738173

这里有一个小的注意点,如果当前还是 SES 沙盒模式,就只能发送给已验证过的邮箱(或者已验证过的域名下的邮箱)。

对此 AWS 做了提示,就是这行小字。

image-20240420215421673

最后点击发送。

如果没有意外的话,你将收到这封邮件:

image-20240420210600452

SNS

我们的网站有可能会有专门用于处理接收邮件的应用程序代码,比如接受到一封邮件后转发给对应的处理专员;或者接收邮件后,为用户生成一个订单。

对此,发布订阅模式是一个很好的处理方案。

这个方案大概是这样的:

  1. 给接收到的邮件配置一个 publish,让邮件可以发布出来。
  2. 订阅该发布行为,当拿到发布的内容后,让内容转发到我们自己写的 API 中。

用 SNS 实现

Amazon Simple Notification Service (SNS) 就是一个 AWS 提供的完全托管的发布/订阅消息传递系统。

通过 SNS 和 SES 的结合,我们可以轻松实现接收邮件并处理的逻辑。

在 SES 的 Configuration 中,点击 Email receiving,并在右侧点击 Create rule Set。

image-20240420221532655

添加 rule name

image-20240422102944319

设置条件

image-20240422103032356

设置 action

image-20240422103059638

如果此时没有 SNS topic,则要创建一个

image-20240422103149074

image-20240422103334938

完成创建后选择该 topic,并点击下一步,确认无误后,点击 Create rule。

最后返回到列表页,查看已经设置完成的 rule 列表。

image-20240422103546168

虽然 Status 已经是 Enabled 状态了,但是还需要将其设置为 active 才能真正生效。

点击Set as active按钮,最终的结果应当是这样的:

image-20240422123636895

创建订阅

现在我们已经将接收到的邮件用 SNS 发布了,接下来就是创建订阅。

在 SNS 中,点击刚才创建的 email-receiving-publish topic。

image-20240422104555373

创建一个订阅

image-20240422104654460

选择 protocol

image-20240422104837413

这里可选的很多,我将以 HTTPS 为例,让 SNS 接受到的邮件能够转发到我的本地 API 中。

先在本地创建一个 Adonisjs 简易的 API 程序:

js
1Route.post('/', async ({ request, response }: HttpContextContract) => {
2  console.log('——————🚀🚀🚀🚀🚀 —— Route.get —— request:', request.raw())
3  response.send('Hello world')
4})

再开启一个 ngrok 以映射到公网上:

bash
1ngrok http 3000

确保使用 ngrok 提供的公网域名能够访问到你的本地程序:

image-20240422114840558

然后将这个公网域名填写到 SNS 上。

image-20240422105750419

点击 Create subscription按钮。

你将在控制台看到 SubscribeURL 这个字段:

image-20240422112811334

这是 AWS 发送的确认身份的 URL,打开它以验证身份从而使得订阅生效。

验证成功后,你的 subscription 将变成 Confirmed 状态。

image-20240422113150418

设置 MX 记录

邮件交换器记录(MX 记录)是一种配置,指定哪些邮件服务器可以接受发送到你的域名的电子邮件。

要让 Amazon SES 管理您的传入电子邮件,需要将 MX 记录添加到域的 DNS 配置中。

我们到 Route 53 中配置一下 MX 记录。

image-20240422124324180

记录名称是我们需要接收邮件的域名。

值是固定的,格式是这样的:

bash
110 inbound-smtp.<region>.amazonaws.com

将 region 改成用户的 AWS 区域即可。

例如我设置的位置是 Toyko,所以就是 ap-northeast-1

我们测试一下:

image-20240422113427788

发送后,你的终端应该就可以打印出接受到的邮件的内容了:

image-20240422124834356

如果想要解析 email 的原始内容,可以使用类似于 mailparser这样的 npm 包解析出完整的 Email 信息。

总结

在本节中,我们将 AWS 的 SES 和 SNS 结合,完成了发送邮件和接收邮件的逻辑。

在 SES 的配置中,分成 domain 和 email 两个类型。

  1. domain 就是你的网站的域,如果你想要用你的网站作为发送人来发送信息,就需要配置它。
  2. email 就是特定的邮箱,如果你有特定的邮箱来发送信息,就需要配置它。

接收邮件的配置过程是这样的:

  1. 在 SES 中配置接收规则。
  2. 接收规则中可以指定接手后做的 action,这里是将其发布给 SNS。
  3. 在 SNS 中,我们配置了一个订阅,将邮件内容发布到本地 API 中。
  4. 配置完 SES 接收规则后,需要设置成 active 状态才真正生效。
  5. SES 和 SNS 都配置完后,还要记得配置 MX 记录,这样邮件可以发送到 AWS 的邮件服务器中并且被 SES 处理。