跳转到主要内容

Documentation Index

Fetch the complete documentation index at: https://docs.cyberun.cloud/llms.txt

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

Webhook 将事件投递到你控制的 HTTPS 端点。可用于在不轮询的情况下 对任务完成或失败作出反应。

开始之前

  • 你的侧边栏需要有 Webhooks 入口。如果没有, 说明此部署未启用 webhook —— 请联系你的团队管理员。
  • 你需要在拥有该 webhook 的团队中具备管理员角色。
  • 一个可从公网访问的 HTTPS 端点。不接受 http://

创建 webhook

  1. 打开侧边栏中的 Webhooks
  2. 点击 创建 webhook
  3. 填写:
    • URL —— 你的端点。必须为 https://
    • 事件 —— 选择哪些事件会触发投递。见下方列表。
    • 描述 —— 内部标签。
  4. 点击 创建。控制台会显示 webhook 的 签名密钥。 立即复制 —— 与凭证一样,只显示一次。

事件

目前投递两个任务事件。
事件触发时机
task.completed任务干净地完成。负载包含任务输出。
task.failed任务出错、超时或其代理已断开。负载包含错误信息。
更细粒度的状态转换(queued、running、cancelled)请改为订阅任务的 SSE 事件流,而不是 webhook。

负载结构

每次投递都是一个 JSON POST。请求头:
POST /your/path HTTP/1.1
Content-Type: application/json
X-Webhook-Signature-256: sha256=<hex_hmac>
主体:
{
  "event_type": "task.completed",
  "task_id": "019c65a0-aaaa-7bbb-cccc-dddddddddddd",
  "task_status": "completed",
  "task_output": {
    "storage_key": "tasks/019c65a0.../output.png",
    "image_count": 1
  },
  "task_error": "",
  "timestamp": "2026-02-16T09:00:00Z"
}
task.failed 投递的结构相同,task_status"failed"task_outputnull,并由 task_error 给出失败原因。
字段含义
event_typetask.completedtask.failed
task_id触发事件的任务 UUID。
task_status终态任务状态:completedfailed
task_output成功时为任务输出对象(结构按工作流运行时而定),失败时为 null
task_error失败时为错误字符串,成功时为空字符串。
timestamp事件触发时间,ISO 8601 格式。

验证签名

Cyberun 用创建 webhook 时显示的密钥,以 HMAC-SHA256 对每次投递签名。 在信任负载之前请先验证签名。 签名在原始请求体上计算,通过 X-Webhook-Signature-256: sha256=<hex_hmac> 请求头发送。
import { createHmac, timingSafeEqual } from 'node:crypto';

function verify(body: Buffer, header: string, secret: string): boolean {
  const expected = createHmac('sha256', secret).update(body).digest('hex');
  const received = header.replace(/^sha256=/, '');
  return (
    expected.length === received.length &&
    timingSafeEqual(Buffer.from(expected, 'hex'), Buffer.from(received, 'hex'))
  );
}
import hmac, hashlib

def verify(body: bytes, header: str, secret: str) -> bool:
    expected = hmac.new(secret.encode(), body, hashlib.sha256).hexdigest()
    return hmac.compare_digest(f"sha256={expected}", header)
对缺失或不匹配签名的投递,返回 HTTP 401 拒绝。

及时回执

  • 尽快回复 2xx。响应较慢会算作失败并触发重试策略。
  • 把繁重的工作异步执行。处理器应当校验签名、把任务入队后立即返回 —— 不要在下游系统上阻塞。

重试

5xx 或超时时,Cyberun 最多重试 4 次,采用指数退避: 即时 → 5 秒 → 30 秒 → 2 分钟。全部重试失败后会丢弃这次投递。 task_id 在所有重试中保持不变 —— 你的处理器应该把同一组 task_id + event_type 的重复投递视为无操作。

轮换签名密钥

如果怀疑密钥泄露,打开 webhook 的详情页并轮换。新密钥只显示一次, 之后所有投递都立即用新密钥签名。

不要

  • ❌ 在没有验证签名的情况下信任负载。
  • ❌ 在请求处理器中阻塞执行慢任务 —— 先回执,后处理。
  • ❌ 把签名密钥暴露在客户端代码中。它是服务端密钥。

相关