投递协议
了解 WebHook 的 HTTP 请求头、统一请求体、成功判定、超时、重试与退避规则。
Poco 使用 HTTP POST 投递 UTF-8 JSON。每个目标都会收到相同业务事件,但请求体中的 webhook 会替换为当前目标配置的信息。
请求头
| 请求头 | 示例 | 说明 |
|---|---|---|
Content-Type | application/json | 请求体类型 |
User-Agent | Poco-Webhook/1.0 | Poco WebHook 客户端标识 |
X-Poco-Event | session.completed | 事件类型 |
X-Poco-Event-Id | UUID | 事件唯一 ID |
X-Poco-Timestamp | ISO 8601 时间 | 本次投递尝试的 UTC 时间 |
X-Poco-Signature | sha256=<hex> | 仅配置密钥时发送 |
接收端应校验请求头中的事件类型和 ID 与请求体的 event_type、event_id 一致。
统一请求体
所有事件都包含下面的外层字段:
| 字段 | 类型 | 说明 |
|---|---|---|
schema_version | string | 当前事件的载荷版本 |
event_type | string | 事件类型 |
event_id | string | 事件唯一 ID;重试时保持不变 |
occurred_at | string | 业务事件发生时间 |
is_test | boolean | 是否由测试推送生成 |
user | object | 事件归属用户 |
webhook | object | 当前投递目标的 id 和 owner_scope |
meta | object | 触发来源、幂等键和事件相关元数据 |
不同事件会增加 session、run、publish_page、workspace_export 等业务对象,详见事件总览。
scheduled_task.run_status_changed 的正式推送和测试推送使用 v2,其他事件仍使用 v1。接收端应结合 event_type 和 schema_version 解析对应事件的字段。
成功判定
任何 HTTP 200-299 都视为投递成功,Poco 不检查响应 JSON。建议接收端在完成验签、基本字段检查和可靠入队后立即返回:
{ "ok": true }不要先执行长时间的数据库聚合、第三方 API 调用或文件处理,否则容易触发超时和重复投递。
重试规则
Poco 会重试:
- HTTP
429 - HTTP
500及以上状态码 - DNS、连接、TLS、超时等网络错误
- 投递客户端发生的异常
Poco 不会重试其他 4xx。如果验签失败或请求格式不符合接收端要求,应返回明确的 4xx,避免无意义重试。
总尝试次数为 1 + retry_count。退避时间按指数增长:
retry_backoff_ms × 2^attempt默认 retry_backoff_ms=800、retry_count=2 时,首次失败后约等待 800 ms,第二次失败后约等待 1600 ms。
重试时保持和变化的内容
event_id、event_type和业务请求体保持不变。X-Poco-Timestamp每次尝试重新生成。X-Poco-Signature使用新的时间戳和同一原始请求体重新计算。
因此接收端应按 event_id 幂等,不能按时间戳识别同一业务事件。
投递保障边界
当前使用进程内 ThreadPoolExecutor,不是持久投递队列。进程退出可能影响待投递任务;重试耗尽只记录日志,当前没有投递记录查询或重放 API。业务需要可靠恢复时,应持久化已收到事件,并结合查询接口对账,不能仅把 WebHook 当作保证送达的队列。
投递顺序
WebHook 由后台线程投递,不阻塞产生事件的主业务请求。不能把不同事件或不同目标的到达顺序当作稳定契约;接收端应使用事件时间、业务状态和 ID 处理乱序或重复。
如果后续业务必须按状态推进,例如 session.completed 后等待文件,应显式等待 workspace_export.completed,不要依赖固定延迟。