跳转到主要内容

Documentation Index

Fetch the complete documentation index at: https://docs.vmeg.ai/llms.txt

Use this file to discover all available pages before exploring further.

为什么需要校验

Webhook URL 对外可访问。未校验时,伪造的完成回调可能被当成真实结果。请先验签,再解析 JSON。

签名方案

VMEG 对每次 Webhook POST 使用 HMAC-SHA256 签名:
  1. API 配置 填写 Webhook URL 后,页面会生成 Webhook Secret,复制到服务端保存,回调请求中无需也不应带上 Secret。
  2. 任务完成时,VMEG 向该 URL POST JSON,并附带:
    • X-Timestamp — 发送时刻的 Unix 毫秒时间戳(字符串)
    • X-SignatureHMAC-SHA256(secret, X-Timestamp + rawBody) 的 hex(16 进制)字符串
  3. 服务端用同一 Secret 重算 HMAC,与 X-Signature 一致则视为 VMEG 发出且 body 未被篡改。若时间戳与服务器时间相差超过 300 秒,应拒绝(防重放)。

如何校验

  1. 从请求头读取 X-TimestampX-Signature
  2. 超出 300 秒时间窗则拒绝。
  3. 原始请求体字节计算 HMAC:不要重新序列化 JSON、不要格式化/排序 key、不要改动空白字符。
  4. 将计算得到的签名与 X-Signature 做比较(严格相等;不要做大小写转换)。
失败返回 401403,仍须快速响应。

示例

import crypto from "node:crypto";

function verify(secret, timestamp, rawBody, signature) {
  if (Math.abs(Number(timestamp) - Date.now()) > 300_000) return false;
  const message = Buffer.concat([Buffer.from(timestamp), rawBody]);
  const expected = crypto.createHmac("sha256", secret).update(message).digest("hex");
  return crypto.timingSafeEqual(Buffer.from(expected), Buffer.from(signature));
}

校验通过后

  1. 解析 JSON,按 event 路由(openapi-ttsopenapi-translateopenapi-clone-voiceopenapi-media-translation)— 见 Webhook 请求体
  2. API 参考 中对应 create-async 接口 Callbacks 的请求 schema 处理 data
  3. 立即返回 2xx;耗时逻辑入队。
URL 配置与接收要求见 Webhooks