准备工作
- 连接并注册用于发送消息的 WhatsApp 商业电话号码。
- 在服务器端妥善保存您的 YCloud API Key。
- 为
whatsapp.message.updated配置带签名的 Webhook 端点。 - 定义系统如何记录用户许可、退订请求、消息用途以及数据留存策略。
- 指定消息发送、Webhook 处理及突发事件响应的负责人。
选择发送端点
默认使用队列端点。仅当应用程序在继续执行前必须确认 WhatsApp 是否已接受提交时,才使用直接发送端点。
任一端点返回的成功响应均不代表最终投递成功。请存储返回的消息
id,并使用 whatsapp.message.updated 事件来了解消息是处于 sent、failed、delivered 还是 read 状态。
创建内部发送记录
在调用 API 之前创建一条持久化记录。为该记录指定唯一的业务键(如订单事件 ID 加上消息用途)。在数据库中强制实施唯一性约束,以防止并发工作进程对同一业务事件重复发送。 至少记录以下内容:
使用不包含消息内容或个人数据的不透明
externalId。API 建议传入唯一值,但 externalId 仅作为参考字段。它不是服务端的幂等键,不能使重复的 POST 请求保持安全幂等。
将响应与状态 Webhook 关联
以下示例在整个发送工作流中使用相同的标识符。1. 发送消息
2. 存储已接受的响应
MESSAGE_ID、accepted 和响应时间保存到已有的内部记录中。切勿直接将业务通知标记为已送达。
3. 应用后续状态事件
whatsappMessage.id 匹配事件。使用 externalId 进行业务对账,使用 wamid 进行服务商排查。
构建收敛状态模型
常见的流转过程为accepted → sent → delivered → read。failed 可能在 sent 更新之前或之后发生。Webhook 可能会重复、延迟或乱序送达。read 更新也可能在没有单独 delivered 事件的情况下到达。
按以下方式处理每个事件:
- 使用原始请求体验证 Webhook 签名。
- 持久化存储事件,使用事件
id作为去重键。 - 及时返回
2xx响应,然后异步处理事件。 - 将
whatsappMessage.id与内部发送记录进行匹配。 - 存储事件状态及其可用的消息时间戳。保留审计所需的原始事件元数据,但移除不必要的消息内容。
- 更新当前业务视图,且不丢弃冲突或后续的凭证。即使没有收到单独的
delivered事件,也将read视为消息已投递的证据。 - 当事件冲突、终态超出服务目标仍未达到或 Webhook 管道不可用时,检索
GET /whatsapp/messages/{id}。
重试时不产生重复发送
在重试前对失败进行分类。
安全的应用程序策略可以从少量重试、指数延迟、完全抖动和最大耗时限制开始。这些属于应用程序控制,而非 API 保证。将耗尽尝试次数的任务发送到审查队列,而不是无休止地重试。
在每次重试之前:
- 锁定或原子性地认领内部业务主键。
- 检查该记录是否已拥有 YCloud
id或状态事件。 - 不要使用新的
externalId来掩盖早期不明确的尝试。 - 在达到配置的尝试次数或时长限制后停止。
- 在重放不明确的发送前,需要操作员明确执行操作。
选择模板和会话消息
在主动发起商业消息或在 24 小时客户服务窗口期外发送时,请使用已获批的模板。根据用户接收消息的原因选择消息模板类别,并在应用程序配置中维护其名称、语言和变量约束。 仅在客户服务窗口期处于开启状态且允许该内容类型时,才发送文本、媒体、互动、位置、联系人或心情回应消息。请根据客户最近发送的消息来确定窗口期。不要通过自己最后发送的出站消息来推断窗口期是否开启。 有关模板版本控制、审批关卡、语言区域和回滚的信息,请参阅 管理 WhatsApp 模板。高效处理媒体
- 在上传前验证文件支持的 MIME 类型和大小。对于超大或不受支持的文件, 请勿在未做更改的情况下重试。
- 使用将要发送消息的商业电话号码进行上传。
- 在返回的媒体 ID 有效期内,重复发送同一已获批素材时可复用该 媒体 ID。上传的媒体文件将保留 30 天。
- 存储素材校验和、MIME 类型、媒体 ID、发送者和过期时间, 以避免工作节点为每个收件人重复上传相同文件。
- 过期后或发送者上下文发生变更时重新上传。
- 当消息结构要求提供链接时(包括互动消息标头中的媒体), 请改用公开 URL。
- 从存储流式传输大文件上传,设置请求超时,并在使用后删除 本地临时文件。
执行授权许可并最小化数据
在发送前记录许可来源、目的、时间和允许的渠道。在营销活动、政策要求的事务性工作流、重试以及手动重放中应用最新的有效退订状态。 对于POST /whatsapp/messages,当工作流必须强制执行 YCloud 抑制列表时,请设置 filterUnsubscribed: true 和 filterBlocked: true。这些字段默认为 false。它们不适用于 sendDirectly,因此直接发送工作流必须在调用 API 之前检查抑制列表。
抑制过滤器是最终的安全检查,不能替代许可。仅存储所述目的所需的标识符和送达元数据。不要在常规应用程序日志中记录 API 密钥、模板变量、消息正文和电话号码。对消息和 Webhook 记录实施保留和访问控制。
控制批量吞吐量
将批量任务放入有界队列中,并通过固定的工作节点池进行发送。按账户和商业电话号码分别跟踪并发量,避免单个发送者或租户占满所有工作节点。 当以下任一信号增加时,应用背压:429响应- 请求延迟和超时
5xx响应- 队列堆积时长或重试积压
- Webhook 延迟和未解决的
accepted消息
accepted 到后续各状态的时间、队列深度、最老队列时长、重试次数、Webhook 延迟、去重次数和对账偏差。针对偏离正常基线的持续变化发出告警,而不是针对单条失败消息。
常见反模式
- 当 API 返回
accepted时即标记消息已送达。 - 将
externalId视为 YCloud 幂等性密钥。 - 对所有非
2xx响应或超时进行无限制重试。 - 对所有流量均使用
sendDirectly。 - 假定 Webhook 具有唯一性、有序性或完整性。
- 在客户服务窗口期外发送自由格式消息。
- 为每个接收者重复上传相同的媒体文件。
- 仅依赖抑制过滤器而未记录用户同意信息。
- 记录 API 密钥、完整负载或不必要的个人数据。
- 以无限制并发且缺乏背压控制的方式启动批处理。
上线前检查清单
- 终端节点的选择符合工作负载和延迟要求。
- 数据库唯一性规则保护了内部业务键。
-
externalId、YCloudid以及wamid各自具有明确记录的职责。 - 在收到状态凭证之前,初始响应保持为非最终状态。
- Webhook 签名、事件去重、快速确认响应及重放机制均已通过测试。
- 配置了定时拉取任务以对账延迟或丢失的事件。
- 可重试和不可重试的失败均具有受限的处理路径。
- 发送前严格执行模板规则与会话窗口规则。
- 媒体上传经过校验、复用、过期管理并能安全清理。
- 同意记录、退订、阻止列表、保留策略与日志记录管控均已核实。
- 批处理队列具备并发限制、背压机制、监控面板与告警设置。
- 运维人员可以暂停发送并审核状态不确定的尝试,而不会自动重放它们。
发送 WhatsApp 消息
查看请求类型、字段、示例以及响应数据。
配置 Webhook
验证签名并安全处理重复的事件推送。
上传 WhatsApp 媒体文件
上传受支持的媒体文件并复用返回的媒体 ID。
处理 API 错误
解析错误响应并应用有上限的重试策略。

