Skip to Content

Webhooks

AvatarGo 可以在事情发生时通知你的服务器——会话开始或结束了、预渲染视频做好了——方式是向你的一个地址发送 HTTPS POST。 有哪些事件、每个事件带什么,列在 API 参考的 Webhooks 下。

设置接收地址

在 AvatarGo 控制台 打开 Webhooks,按 Add endpoint:

  • URL——你服务器上一个 https:// 地址,要能从公网访问。
  • Events——要发到这里的事件类型。

接收地址的签名密钥只在添加后显示一次:当场复制,保存在你的服务器上。Send test event 会发送一个 webhook.test 事件 (data 为 {}),用来检查你的服务器能否正常回复。一个账户最多 20 个接收地址。

发送的内容

每个事件是一个带 JSON 正文的 POST:

{ "id": "evt_…", "type": "session.ended", "createdAt": "2026-11-07T09:30:00.000Z", "data": { } }

id 每个事件唯一;data 的内容取决于 type。

校验签名

每个请求都带一个 AvatarGo-Signature 请求头:

AvatarGo-Signature: t=1794040000,v1=5257a869e7ecebeda32affa62cdca3fa51cad7e77a0e56ff536d0ce8e108d8bd

t 是发送时间,自 1970 年起的秒数;v1 是以你的签名密钥为 key,对 t、一个点和请求正文计算的 HMAC-SHA256,十六进制。 要对原样收到的正文计算——在解析 JSON 之前——并检查 t 是最近的,这样旧请求无法被当作新请求重发。

import { createHmac, timingSafeEqual } from "node:crypto"; // header:AvatarGo-Signature 请求头;body:原始请求正文,字符串;secret:接收地址的签名密钥。 export function verifyAvatarGo(header, body, secret, toleranceSeconds = 300) { const parts = Object.fromEntries(header.split(",").map((p) => p.split("="))); const t = Number(parts.t); if (!t || Math.abs(Date.now() / 1000 - t) > toleranceSeconds) return false; const expected = createHmac("sha256", secret).update(`${t}.${body}`).digest(); const given = Buffer.from(parts.v1 ?? "", "hex"); return given.length === expected.length && timingSafeEqual(given, expected); }

回复与重试

10 秒内回复任意 2xx 状态。其他情况——别的状态码、没有及时回复、连接失败——会在 1 分钟、5 分钟、30 分钟、2 小时、6 小时和 15 小时后重试:一共 7 次,持续大约一天。

所以同一个事件可能到达不止一次:记下处理过的 id,跳过重复的。先回复再做事,不要反过来,免得一件慢活变成一次重试。

接收地址一直失败时

如果发往某个接收地址的投递连续 3 天全部失败,这个接收地址会被关闭,并发邮件通知你账户的所有者。修好你的服务器后,在控制台里该接收地址上按 Turn on:从那时起,新事件会重新发送;关闭期间的事件不会补发。

请求只发往公网上的地址,不跟随重定向。在控制台里,每个接收地址的 Deliveries 显示最近 30 天发送的内容及每一次尝试,Resend 可以把一个事件再发一次。