投递行为
标准载荷、5 秒时限、不重试的原因,以及每种投递状态的含义。
Webhook 投递机制刻意保持简单,而这种设计会直接影响您的接收端:仅尝试 1 次 HTTP 请求,限时 5 秒,不重试。在决定处理程序同步执行多少工作之前,请先阅读本页。
标准负载
除 listing.submission 外,所有事件都采用相同的顶层结构,事件特有的字段嵌套在 data 下。
{ "event": "connection.location_connected", "timestamp": "2026-08-25T14:32:10Z", "account_id": 11073, "location_id": "279381", "data": { "platform": "google", "connected_account_id": "ba03bc4b-9f8c-4d3b-8e93-9628034c63cc" }}data 中的可选字段为空时会被省略,而不是以 null 发送。请采用防御性编程方式:对缺失的键和显式的 null 采用相同的处理方式,切勿假定文档中标为可选的键一定存在。
2 种例外情况
5 秒时限
每次投递仅发送 1 次 POST,连接超时和读取超时均为 5 秒。如果您的端点未及时响应,此次尝试将被放弃,并记录为 timeout。
此时限涵盖整个处理程序的执行过程。唯一安全的设计是:
- 验证签名。
- 将负载写入持久化存储,例如队列、表或日志。
- 返回
200。
其他所有操作(补充数据、分发、回调 REST API,以及任何涉及第三方的操作)都应在从该队列取出数据后执行。
不进行重试
每次投递只尝试 1 次。没有退避机制、重试队列或死信队列。如果您的端点停机 2 分钟,这 2 分钟内触发的事件就会丢失。它们不会在稍后送达。
需要明确说明的 2 个结果:
- 不会跟随重定向。重定向已完全禁用,因此您的端点返回
301或302时,会被记录为投递失败,不会继续请求另一个 URL。请将您的 webhooks URL 配置为最终 URL。请留意许多 Web 服务器默认添加的从裸域名到www的重定向,以及添加尾部斜杠的重定向。 - 只有
2xx才算投递成功。3xx、4xx和5xx都会被记录为失败。
重复事件与顺序
- 您可能会收到同一事件 2 次,也可能在 2 次不同的变更中收到相同的 id。
data中的标识符(交互 id、帖子条目 id、已连接账号 id)标识的是资源,而不是变更。每次评价发生变更时,interaction.review都会以相同的交互 id 再次触发,而且所有载荷都不包含版本或更新时间字段,因此,如果处理程序根据 id +event永久去重,就会在不提示的情况下丢弃实际发生的编辑。应改为检测完全相同的重复事件:对原始请求体字节计算哈希值,并在有明确时限的短时间窗口内忽略哈希值相同的重复事件(以分钟计,而非永久)。同一 id 对应的请求体如果不同,就表示一次新的变更,而不是重复事件。然后通过 REST API 回读资源,并以读取结果为准;写入时以资源 id 为键,而不是跳过写入。 - 不保证事件顺序,
timestamp也无法解决这一问题。事件来自多个独立通道,并在到达时投递,因此,local_post.published可能先于您预期先收到的local_post.created到达。不要根据timestamp对同一资源的 2 次变更排序:该时间戳是在构建投递内容时记录的,而不是在变更发生时记录的,并且载荷中没有任何版本号或序列号。如果顺序很重要,请回读资源并使用 API 返回的结果。 profile.updated采用防抖机制,每个地点每 60 秒最多投递 1 次,并在窗口起始时触发。这会直接合并事件,而不是延迟投递:首次编辑开启窗口并触发投递,窗口内的每次后续编辑都会被丢弃,永远不会送达,而changed_fields仅描述开启该窗口的那次编辑。因此,您会在窗口开始时收到事件,由事件到达触发的回读只能看到首次编辑。请安排在窗口关闭后进行第 2 次回读,即至少在事件发生 60 秒后,并定时核对地点数据,因为通知本身也可能丢失:仅尝试投递 1 次,不会重试。其他事件均不采用防抖机制。
遗漏事件后的恢复
系统不会重试,也不支持重放,因此每个事件类别都需要有一种可作为后备方案的权威数据读取方式。请定期核对数据,不要仅在发现异常时才核对。
投递结果
每次尝试都会记录状态,即使请求根本没有发出也不例外。以下是具体的状态字符串。
接收端检查清单
- 验证每个请求的签名;如果签名不匹配,返回
401,且不执行任何处理。 - 对原始请求体字节计算哈希,切勿对重新序列化的对象计算哈希。
- 在远少于 5 秒的时间内返回
2xx;将处理工作加入队列。 - 以
data中的 ID 作为处理程序每次写入的键,使重复处理产生相同的结果,但切勿将重复的 id 视为无需执行任何操作。 - 不要根据到达顺序推断事件顺序,也不要按
timestamp排序。 - 在接收数据时,将
location_id统一转换为字符串。 - 忽略无法识别的
event值,并仍然返回200。 - 确保 webhooks URL 是最终地址,不发生任何重定向。
- 定期通过 REST API 核对数据;系统不会重试来弥补遗漏。