什么是 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 和相同的负载。
投递语义与幂等性
Ayrshare 采用至少一次(at least once)的方式投递 webhook。偶发的重复属于正常运行,而非缺陷 —— 每个消费者都需要将幂等性作为一项长期属性。 重复以两种不同形式出现,每一种都需要不同的键来识别:hookId 标识一次投递中的事件。它在该次投递的每次重试中都保持一致,因此以它作为幂等键可以让重试变得安全 —— 但同一底层事件的一次新通知会带来一个全新的 hookId,所以仅凭 hookId 无法识别此类情况。
推荐的接收方处理模式:
- 先响应。 立即返回
2xx,然后异步处理。超时并不等于拒绝 —— 如果你完成了工作却响应过晚,事件会被再次发送。 - 原子地占用
hookId,在请求到达的那一刻就完成 —— 使用唯一约束、INSERT ... ON CONFLICT DO NOTHING或SET NX,而不是先读后写的检查。两次尝试可能并发到达,而”先检查再执行”的守卫会让它们双双通过。 - 同时占用你自己的键,基于负载构建,以便在携带新
hookId的第二次通知到达时仍能识别。对于messages,将id与subAction组合使用效果良好。 - 然后执行实际工作,并将两个占用保持足够长的时间,以覆盖重试窗口和之后可能出现的再次通知。
负载中的
id 对每种事件类型来说并不总是唯一的 —— 同一 message id 会在编辑和反应事件中重复出现,而 messageRead 负载则完全没有 id —— 因此应将其与 subAction 组合使用,而不要单独使用。投递元数据 Header
每次投递都会携带两个用于标识该次具体传输的 header,便于你区分原始投递与重试:X-Ayrshare-Delivery-Attempt 在首次发送时为 0,每次重试递增 1,因此任何大于 0 的值都意味着我们至少已发送过一次该投递。请将其视为一个无上限的计数器,而不是固定的取值集合 —— 重试次数属于可能变化的运行细节。X-Ayrshare-Delivery-Id 对每次尝试都是唯一的 —— 向支持团队反馈时引用它,可精确定位到具体的投递记录。
这两个 header 标识的是传输;而 hookId 标识的是事件。请基于 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)。