仅看到接受事件就重新发送可能会产生重复消息。在决定重试之前,先通过后续事件追踪第一次发送的结果。
保存发送请求返回的消息标识符。它将初始接受与该消息的后续事件关联起来。
从接受到送达之间发生了什么?
Email 会经过准备阶段。SMS 消息会经过移交到移动运营商的阶段。
您可以通过以下事件类型追踪 Bird 的发送过程:
| 渠道 | 事件 | 说明 |
|---|---|---|
email.accepted | Bird 接受了发送请求并正在准备消息,每个请求的收件人触发一次。 | |
email.processed | Bird 已准备好消息,可以投递到收件人的邮件服务器。 | |
email.delivered | 收件人的邮件服务器已接受该消息。 | |
| SMS | sms.accepted | Bird 接受了发送请求并将其排队等待处理。 |
| SMS | sms.sent | Bird 已将消息移交给运营商。 |
| SMS | sms.delivered | 运营商报告消息已送达收件人终端设备。 |
在 timestamp 中比较事件时间以定位延迟。Webhook 到达时间本身也包含投递延迟。
对于 Email,用准备时间减去接受时间来衡量 Bird 内部的准备耗时。准备之后的时间间隔还包括等待到达接收服务器的时间。
对于 SMS,用运营商移交时间减去接受时间来衡量移交前的耗时。从移交到送达的时间间隔衡量剩余的投递时间。
例如,一条 SMS 在中午被接受,两秒后完成移交,则运营商移交前耗时两秒。如果八秒后送达,总耗时为十秒。
为什么仍未送达?
消息可能仍在等待中。后续事件也可能报告投递失败。
仅凭接受事件无法区分这两种结果。在决定是否重新发送之前,先查看同一消息的后续事件。
Email 报告以下结果:
email.deferred表示由于临时故障导致投递延迟。Bird 会重试,因此消息仍可能被送达或稍后退回。email.bounced表示接收服务器拒绝了投递。email.rejected表示 Bird 在尝试投递之前就拒绝了该消息。在更改收件人的邮件服务器设置之前,先调查拒绝原因。
SMS 使用一组不同的结果:
sms.undelivered报告来自运营商的非永久性投递失败。sms.failed报告永久性投递失败。sms.rejected表示 Bird 在运营商移交之前就拒绝了该消息。sms.expired表示消息的有效期在送达之前已过期。
查看失败结果附带的错误信息以确定原因。运营商对 SMS 的过滤解释了一种可能的原因。
是否有一个统一的生命周期可以学习?
每个渠道都有自己的投递状态序列。
Email 服务器可以要求发送方稍后重试。SMS 运营商可以在消息过期时停止尝试。这些结果需要不同的恢复操作。
WhatsApp 和语音也报告各自的事件类型。它们的事件指南描述了相关状态:Email、SMS、WhatsApp 和语音。
已送达的消息还会变成未送达吗?
Email 可以在接收邮件服务器报告后续投递失败后,从已送达变为已退回。
服务器先通过 SMTP 接受消息,然后可以在该交换结束后单独报告失败。
Bird 将该报告记录为 email.out_of_band_bounce。当报告被归类为退回时,收件人的状态从已送达变为已退回。对于硬退回,Bird 还会抑制该地址以阻止后续发送,因为该失败是永久性的。
自动回复可以出现在时间线上,但不会改变送达状态。报告的分类决定了先前的接受是否被撤销。
在成功事件之后仍需保持送达状态可更新。Webhook 可能乱序到达,因此在应用可能覆盖较新状态的更改之前,先比较事件时间戳。
简而言之
接受确认的是发送请求。
Bird 在接受后开始准备消息。该事件不确认消息已到达邮件服务器或终端设备。
准备和移交是不同的边界。
Email 通过 email.processed 报告准备完成。SMS 通过 sms.sent 报告运营商移交。
失败在不同渠道有不同含义。
Email 可能被延迟、退回或拒绝。SMS 区分未送达、失败、拒绝和过期等结果。
Email 送达后仍可能被退回。
后续的退回报告可以将 Email 收件人的状态从已送达变为已退回。自动回复不会改变送达状态。