投递时机:
| 终态 | 是否投递 |
| 执行成功(success) | 投递,event 为 task_success |
| 执行失败(failed) | 投递,event 为 task_failed |
| 执行超时(timeout) | 投递,event 为 task_timeout |
| 任务被主动取消 | 不投递 |
是否真正发出由投递目标的 events 订阅关系决定,见下文。
一、事件订阅
投递目标可通过 events 声明只关心哪些终态:
[ { "type": "webhook", "url": "https://your-domain.com/hook", "events": ["failed", "timeout"] }]
| 配置 | 行为 |
| events 为 ["failed"] | 仅在执行失败时投递 |
| events 为 ["success", "failed", "timeout"] | 任何终态都投递 |
| events 为空或未配置 | 按全订阅处理(成功、失败、超时都投递) |
·取值仅支持 success / failed / timeout,大小写不敏感,前后空白会被忽略。
·订阅关系按目标独立生效,多个目标可以各配各的。
·某目标未订阅本次终态时,不会发起请求,也不会记录投递失败信息。
二、请求头
| Header | 是否必有 | 说明 |
| Content-Type | 是 | 固定 application/json,不可覆盖 |
| User-Agent | 是 | 固定 automation-scheduler/1.0 |
| X-Webhook-Signature | 否 | HMAC-SHA256 签名(hex,小写),仅当投递目标配置了 secret 时携带 |
| 自定义 Header | 否 | 投递目标 headers 中配置的 KV |
Content-Type、User-Agent 由平台统一下发,即使 headers 中配置了同名值也会被覆盖。
三、请求体示例
成功投递示例:
{ "event": "task_success", "taskNo": 2149837465201983489, "taskId": "task_abc123def456", "taskName": "每日构建检查", "logId": 2149837465201984001, "status": "success", "result": "今日完成 5 项任务", "durationMs": 30021, "timestamp": 1761120000000}
失败投递示例:
{ "event": "task_failed", "taskNo": 2149837465201983489, "taskId": "task_abc123def456", "taskName": "每日构建检查", "logId": 2149837465201984001, "status": "failed", "errorMsg": "executor endpoint returned status 500", "durationMs": 45210, "timestamp": 1761120000000}
| 字段 | 类型 | 是否必有 | 说明 |
| event | string | 是 | 事件类型:task_success / task_failed / task_timeout |
| taskNo | uint64 | 是 | 任务主键 ID(雪花 ID) |
| taskId | string | 是 | 任务唯一标识(创建任务时指定的 key,账号内唯一) |
| taskName | string | 是 | 任务名称 |
| logId | uint64 | 是 | 本次执行日志 ID,可用于在控制台定位执行详情 |
| status | string | 是 | 执行终态:success / failed / timeout |
| result | string | 否 | 执行结果文本,成功且有产出时有值 |
| errorMsg | string | 否 | 错误信息,失败/超时有值 |
| durationMs | uint64 | 否 | 本次执行耗时(毫秒) |
| timestamp | int64 | 是 | 投递时间戳,Unix 毫秒 |
注意:说明:
四、响应要求
| HTTP 状态码 | 含义 |
| 2xx | 投递成功 |
| 非 2xx | 投递失败 |
·平台只读取状态码,不解析响应体。
·有超时限制(默认 10 秒,服务端可配置),超时计为失败。
·不做自动重试;失败原因会记录在本次执行日志中,可在控制台排查。
·配置多个投递目标时,聚合结果可能为 success(全部成功)/ partial(部分成功)/ failed(全部失败)/ skipped(全部未订阅或未配置 URL)。
五、签名验证
投递目标配置了 secret 时,平台会对请求的原始请求体字节做 HMAC-SHA256 签名,放入 X-Webhook-Signature 头,接收端可据此确认请求来自平台且内容未被篡改。
| 项 | 值 |
| 算法 | HMAC-SHA256 |
| 密钥 | 你配置的 secret |
| 签名内容 | POST 请求的原始 JSON body(字节流,不做任何规范化) |
| 编码 | hex(小写) |
GoPythonfunc verifyWebhookSignature(secret string, body []byte, signature string) bool { mac := hmac.New(sha256.New, []byte(secret)) mac.Write(body) expected := hex.EncodeToString(mac.Sum(nil)) return hmac.Equal([]byte(signature), []byte(expected))}// sig := r.Header.Get("X-Webhook-Signature")// body, _ := io.ReadAll(r.Body)// ok := verifyWebhookSignature("your-secret", body, sig)import hmac, hashlibdef verify_webhook_signature(secret: str, body: bytes, signature: str) -> bool: expected = hmac.new(secret.encode(), body, hashlib.sha256).hexdigest() return hmac.compare_digest(signature, expected)# signature = request.headers.get("X-Webhook-Signature")# ok = verify_webhook_signature("your-secret", request.body, signature)