结账完成后,你的应用有了一笔订单和一个需要收据的收件人。它使用邮件 API提交消息,并将响应记录到该订单上。
提交只是第一步。你的应用还需要一种重试请求的方式,并且需要了解消息提交后的投递结果。
应用事件如何变成一封邮件?
你的应用将已完成的交易或账户请求转化为发送操作。邮件服务在提交后负责投递。
以收据为例,流程如下:
- 你的应用确认订单已准备好生成收据。
- 它选择收件人,并将订单详情作为内容或模板值提供。
- 它提交发送请求,并将返回的消息 ID 保存到该订单上。
- 当投递事件到达时,它更新发送记录。
邮件 API 可以同时支持事务性消息和营销消息。使用 API 不会使促销内容变成事务性内容,也不会免除 CAN-SPAM 合规义务。
成功响应意味着什么?
成功的提交响应记录了服务已接受的内容。它与接收邮件服务器后续的处理决定是分开的。
HTTP 的 202 状态表示请求已被接受并正在处理。处理尚未完成,因此该响应不能证明投递成功。
具体的响应取决于 API。例如,Bird 的发送端点会返回一条带有 id 的排队消息。将该 ID 与订单或账户事件一起保存,以便后续结果可以匹配到原始请求。
如果验证失败,Bird 返回 422,并附带一条错误信息说明请求被拒绝的原因。
重试如何避免重复消息?
幂等键标识跨重试的一次逻辑发送操作。支持幂等键的 API 可以识别重复请求,而不是再创建一次发送。
例如,订单 8472 的收据可以使用键 receipt/order-8472。如果连接在收到响应之前断开,使用同一键重试该请求即可。
新的键标识的是不同的操作。因此,你的应用需要在自身的重试和重启过程中保留原始键。
幂等性有提供商定义的保留窗口。窗口过期后,相同的键可能会被当作新请求处理。
Webhook 如何报告投递结果?
Webhook 在消息状态变化时向你的应用发送事件。它让你的应用能够在收到初始 API 响应之后更新记录。
Bird 的邮件事件区分以下结果:
| 事件 | 它表明了什么 |
|---|---|
email.delivered | 接收邮件服务器已接受该消息的投递责任 |
email.deferred | 临时投递失败,将进行重试 |
email.bounced | 接收服务器拒绝了投递 |
email.rejected | 消息未进入投递尝试阶段 |
服务器接受不代表消息到达收件箱或被阅读。接收服务器也可能在接受消息后报告延迟退信。
你的 webhook 处理程序必须验证发送方签名并处理重复投递。Bird 的 webhook 契约要求使用 webhook-id 进行去重。
模板改变了什么?
已保存的模板将可复用的消息内容与每次发送时提供的值分离。你的应用只需提供订单号和客户姓名,无需拼装完整的邮件正文。
使用 Bird 的模板时,一次发送指定已发布的模板并提供其参数。模板提供主题和正文。
模板不决定订单何时完成,也不决定密码重置是否已获授权。这些决定仍在你的应用中。
它与 SMTP 中继或营销平台有什么区别?
HTTP API 和 SMTP 中继是不同的提交接口。营销平台还管理活动工作,例如选择受众和安排发送。
| 接口或产品 | 你的应用提供什么 |
|---|---|
| 邮件 API | 结构化的 HTTP 请求,包含收件人和内容或模板 |
| SMTP 中继 | 通过 SMTP 会话提交收件人和格式化的邮件消息 |
| 营销平台 | 活动内容、受众选择和发送指令 |
SMTP 定义了提交消息及其收件人的交换方式。它可以承载事务性或营销邮件。
Bird 的 SMTP 中继和 HTTP API 使用相同的投递产品,包括事件和抑制处理。选择 SMTP 不会移除这些功能。
如何通过 Bird 发送事务性邮件?
使用已验证的发件人、收件人以及内联内容或已发布的模板调用 POST /v1/email/messages。为操作性邮件设置 category: "transactional"。响应为 202 Accepted,附带消息 ID;投递异步进行。
为每次逻辑发送使用一个 Idempotency-Key。Bird 会保留已完成的响应三小时。超过该窗口后的重试可能创建另一条消息,因此请自行记录已完成的业务事件。
订阅邮件事件,并将 email_id 和 recipient_id 与你的记录匹配。一条消息有多个收件人时,每个收件人有独立的结果。
关于提供商选择,事务性邮件服务清单涵盖了需要比较的投递和运营能力。