什么是 Webhook?
Webhook 允许你在系统发生某些 action 时,通过向你提供的 URL 发起调用来收到通知。Webhook 也被称为 “URL 回调” 或 “HTTP push 调用”。你的 URL 必须使用 SSL,并以 HTTPS 开头。Webhook Actions
查看 webhook 可用的 action。
理解 Ayrshare 的 Webhook
Webhook 按具体的 action 分类,且 在 Primary Profile 或 User Profile 层面进行注册。Primary Profile 或 User Profile 的任何更新都会优先发送到该 User Profile 已注册的 Webhook。如果该 User Profile 没有注册 Webhook,更新将发送到 Primary Profile 注册的 Webhook。 例如:- 如果某个 User Profile 注册了 Social Action Webhook 并解绑了 TikTok,则会调用该 User Profile 注册的 Social Action Webhook URL。Primary Profile 的 webhook 不会 被调用。
- 如果某个 User Profile 解绑了 TikTok 且 未 注册 Social Action Webhook,但 Primary Profile 已注册了 Webhook,则会调用 Primary Profile 注册的 Social Action Webhook URL。
注册 Webhook
通过向 POST/hook/webhook 端点提供一个端点 URL 及 action 类型来注册 Webhook。当该 action 发生时,系统会向所提供的 URL 发送一个 HTTP POST 消息。
例如,注册一个 URL 以获取定时帖子的状态通知。
Webhook 端点 URL 不应使用重定向,必须是最终目标 URL。
如果你只为 Primary Profile 注册了 webhook,则各个 User Profile 会自动继承该 Primary Profile 的 webhook。
如需为每个 User Profile 使用独立的 webhook,则必须分别为每个 User Profile 注册 webhook。
当你的 Webhook 收到
HTTP POST 后,你的服务器必须返回 HTTP 200 状态,以将该调用标记为成功。如果你的服务器在 15 秒内没有响应,该次尝试会被记为失败并进行重试。收到请求后请尽快响应,并异步完成处理 —— 超时并不等于拒绝,因此如果你的处理器完成了工作但响应过晚,重试仍会到达,导致你重复处理一次。Webhook 重试
如果你服务器返回的 HTTP 响应不在200-299 成功范围内,或你的服务器在 15 秒内没有响应,系统会自动再重试两次 Webhook 调用。第一次重试将在 5 秒后进行,第二次重试将在此后 30 秒进行。重试请求会保留相同的 hookId 和相同的 payload。
投递语义与幂等性
Ayrshare 对 webhook 采用**至少一次(at least once)**的投递语义。偶发的重复投递属于正常运作,而非缺陷 —— 每个消费者都需要将幂等性作为一项长期属性来保证。 重复投递会以两种不同形式出现,而每一种都需要不同的键来识别:hookId 标识的是一次投递。它在该次投递的每次重试中都相同,因此以它为键做认领可以让重试变得安全 —— 但同一底层事件的一次新通知会带来一个新的 hookId,所以仅凭 hookId 无法识别这种情况。
推荐的接收端处理模式:
- **先响应。**立即返回
2xx,然后异步处理。超时并不等于拒绝 —— 如果你完成了处理但响应过晚,该事件仍会被再次发送。 - 以原子方式认领
hookId,在请求到达的那一刻就完成认领 —— 使用唯一约束、INSERT ... ON CONFLICT DO NOTHING,或SET NX—— 而不是先读后写的检查方式。两次尝试可能并发到达,而 check-then-act 型防护会同时放行两者。 - 同时也认领一个你自己的键,由 payload 构建而来,这样即使带着新
hookId的第二次通知到达,你也能识别出来。对于messages,将id与subAction组合起来使用效果良好。 - 然后再执行实际工作,并让两个认领都保持足够长的时间,以覆盖重试窗口和后续可能的再次通知。
payload 中的
id 对每种事件类型来说并非单独唯一 —— 相同的 message id 会在编辑和反应(reactions)中重复出现,而 messageRead 类型的 payload 中也不携带 id —— 因此请将其与 subAction 组合使用,而不要单独使用。投递元数据 Header
每次投递都会携带两个用于标识该次具体传输的 header,便于你区分首次发送与重试:X-Ayrshare-Delivery-Attempt 在首次发送时为 0,每次重试递增 1,因此只要该值大于 0,就说明我们已至少发送过一次该次投递。请将其视为无上限的计数器,而不是一组固定的取值 —— 重试次数是可能会变化的运行细节。X-Ayrshare-Delivery-Id 对每次尝试都是唯一的 —— 联系支持时提供该值,可精准定位到具体的投递记录。
这些 header 标识的是传输(transmission);hookId 标识的是事件(event)。请基于 hookId 去重,而不要基于 delivery id —— delivery id 在每次尝试时都不同(这是设计上的行为),因此若用它去重,任何投递都不会被识别为重复。
Webhook 安全性
你可以通过将 HMAC 认证设置为 HTTP 请求的一部分来增加额外的安全性,这通常用于防止重放攻击。Ayrshare 使用 HMAC-SHA256 对消息 body 进行哈希,并将其与 UNIX 时间戳一起放入 POST 的 header 中。X-Authorization-Content-SHA256 与 POST body 的 HMAC-SHA256 进行比较来验证该请求。签名密钥是按 profile 统一的 —— 每个 User Profile 只有一个密钥,并在该 profile 的所有 webhook action 中通用,因此为某个 action 设置它就等于修改了该 profile 上所有 action 的密钥。多 profile 账户会按 profile 分别管理各自的密钥(通过 Profile-Key header 指定目标 profile)。