Skip to content

Webhook 模式篇

目标:让集成方创建事件订阅、看懂推送请求的 payload 信封与请求头、按事件类型路由处理、用幂等键去重、理解平台的自动重试与失败排障,端到端接住内容变更回调。

不在本篇范围:订阅各端点的逐字段参数(见接口参考);资源详情字段(payload 只给资源引用,详情凭 ID 回调对应资源端点取,见领域模型);错误码完整码表(见错误码参考)。

Webhook 让 ATKONBASE 在内容发生变更时主动回调你的接收端点,免去你轮询查询。你创建一个订阅、声明关心的事件类型与接收 URL;之后对应业务操作提交后,平台异步向该 URL POST 一条轻量引用信封,你据此回调相应资源端点取详情。

关键事实

  • 推送在业务操作提交后异步发出(通常数十秒内送达),不与触发操作同步、不保证即时。
  • 推送请求体是轻量引用信封——只含事件元信息 + 资源类型/ID,不含资源完整内容;你凭 resource.id 回调对应资源端点取详情。
  • 投递为至少一次(at-least-once):失败会重试,同一事件可能被推送多次;用幂等键 eventId 去重
  • 同一订阅的多个事件不保证到达顺序,按 best-effort 投递。
  • ⚠️ 当前版本推送不带 payload 签名,请求体为明文 JSON。来源校验首选在订阅上配置出站投递授权 token(deliveryToken)、核对推送携带的 Authorization: Bearer 头;并辅以接收端点走 HTTPS、URL 保持不可猜测 / 不公开、以 eventId 幂等处理(见下文来源校验与安全)。
  • 只有 ACTIVE 状态的订阅会产生并接收推送;PAUSED / DISABLED 不推送。

一、创建订阅

bash
curl -X POST 'https://api.atkonbase.example.com/v1/webhooks/save' \
  -H 'Authorization: Bearer ${accessToken}' \
  -H 'Content-Type: application/json' \
  -d '{
    "url": "https://your-app.example.com/atk/webhook",
    "eventTypes": "document.created,document.updated",
    "description": "文档变更通知",
    "deliveryToken": "a-long-random-shared-secret"
  }'
字段说明
url接收推送的目标 URL,须可公网访问、建议 HTTPS
eventTypes订阅的事件类型,逗号分隔* 表示订阅全部
description描述(可选)
deliveryToken出站投递授权 token(可选,只写):配置后平台投递本订阅的事件时以 Authorization: Bearer <token> 携带,供你校验推送来源(见来源校验与安全)。不在 get / 列表 / 保存响应中回显;保存时显式传值即覆盖、传空字符串即清除、不传则保持原值
  • 创建后订阅状态固定为 ACTIVE,立即生效。
  • 改状态走 updateStatus、删除走 delete(见下);完整参数见接口参考 · 创建订阅

其它订阅管理端点

bash
# 分页查订阅
curl -X GET 'https://api.atkonbase.example.com/v1/webhooks/getPage?page=1&pageSize=20' \
  -H 'Authorization: Bearer ${accessToken}'

# 查订阅详情
curl -X GET 'https://api.atkonbase.example.com/v1/webhooks/get?webhookId=${webhookId}' \
  -H 'Authorization: Bearer ${accessToken}'

# 改状态(ACTIVE / PAUSED / DISABLED)
curl -X GET 'https://api.atkonbase.example.com/v1/webhooks/updateStatus?webhookId=${webhookId}&status=PAUSED' \
  -H 'Authorization: Bearer ${accessToken}'

# 删订阅
curl -X GET 'https://api.atkonbase.example.com/v1/webhooks/delete?webhookId=${webhookId}' \
  -H 'Authorization: Bearer ${accessToken}'

# 查可订阅事件类型清单
curl -X GET 'https://api.atkonbase.example.com/v1/webhooks/event-types' \
  -H 'Authorization: Bearer ${accessToken}'
  • PAUSED 期间不推送、也不积压补投;恢复 ACTIVE 后仅对其后发生的事件推送。

二、可订阅事件类型

event-types 返回以下 8 类事件,均已接真实发布点——订阅后对应业务操作提交即会产生推送:

事件类型触发时机
document.created文档创建
document.updated文档更新(元数据 / 内容 / 属性更新均归并到此)
document.deleted文档删除(移入回收站)
document.archived文档归档(独立于更新,归档只触发本事件、不再触发 document.updated
container.created容器创建
container.updated容器更新
container.deleted容器删除(移入回收站)
acl.changed权限变更(授权、撤销、策略调整)
  • 删除语义为「移入回收站」(trash)document.deleted / container.deleted 在资源被移入回收站时触发;彻底清除(purge)不对外推送为 webhook 事件。
  • document.updated 归并多种更新来源(元数据 / 内容 / 属性),你收到后凭 resource.id 回调取最新状态即可,无需区分更新子类。

三、推送请求结构

平台向你的 url 发起一个 POSTContent-Type: application/json

请求头

请求头含义
X-Webhook-Event-Id事件唯一 ID,即幂等键,与请求体 eventId 一致
X-Webhook-Event-Type事件类型(如 document.created),便于路由分发
X-Webhook-Id触发本次推送的订阅 ID

请求体(轻量引用信封)

json
{
  "eventId": "9f1c2e7a-5b3d-4e8a-9c10-2b6f4d8e1a3c",
  "eventType": "document.created",
  "occurredAt": "2026-05-25T07:00:00Z",
  "resource": {
    "type": "document",
    "id": "D1000001"
  }
}
字段含义
eventId事件唯一 ID,幂等去重键;同一事件的重复推送携带相同值
eventType事件类型,取值同上表 8 类
occurredAt事件发生时间,ISO-8601 UTC(如 2026-05-25T07:00:00Z
resource.type资源类型,如 document / container
resource.id资源业务 ID,凭此回调对应资源端点取完整详情
  • 信封不内嵌资源快照:避免推送内容与资源当前状态不一致、避免敏感字段随推送外泄。需要详情时用 resource.id 回调对应资源端点(如文档详情)。
  • 你的接收端点应在成功处理后返回 2xx;非 2xx 会被判为失败并进入重试。

四、确认接收与重试

平台按下游响应判定单次投递结果:

下游响应判定后续
2xx成功该投递终态 SUCCESS,不再推送
非 2xx失败进入重试,直至达上限
超时 / 连接失败失败进入重试,直至达上限

重试为指数退避。默认最多尝试 5 次(含首次投递)——即首投失败后,依次在 +30 秒、+2 分钟、+10 分钟、+1 小时 各重试一次;4 次重试仍失败,则该投递置为终态 FAILED、不再推送。

首投 ──(失败)──> +30秒 ──> +2分钟 ──> +10分钟 ──> +1小时 ──(仍失败)──> FAILED
  • 退避档位按 30 秒 → 2 分钟 → 10 分钟 → 1 小时 阶梯递增;默认策略最多重试到 +1 小时档;退避节奏可能随版本调整。
  • 上述为平台默认重试策略,由平台统一调度、不可在订阅上配置,可能随版本调整。
  • ⚠️ 因为重试存在,同一事件可能被多次推送——你的接收端点必须幂等:用 eventId(= X-Webhook-Event-Id)记录「已处理事件」,重复到达时直接确认 2xx、不重复执行业务。

五、来源校验与安全

当前版本推送为明文 JSON、不带 payload 签名头。在你的接收端点上建议:

  • 校验投递授权 token(首选):创建 / 更新订阅时配置一个足够随机的 deliveryToken;平台投递本订阅的事件时会以 Authorization: Bearer <token> 携带该值,你的接收端点逐请求比对该头是否等于你配置的 token,不匹配即拒绝。该 token 为只写凭据、不在任何读路径回显,请妥善保存。
  • 限定接收 URL 不公开:使用足够随机、不可猜测的路径,不对外宣传该 URL。
  • 走 HTTPS:接收端点使用 HTTPS,避免明文传输被中间人窜改、以及 deliveryToken 在传输中泄露。
  • 幂等处理:以 eventId 去重(见上),重复推送不产生副作用。
  • 凭 ID 回查权威状态:信封只给资源引用;以你的访问凭证回调资源端点取详情,即等于用一次已鉴权的查询确认事件所述资源的真实当前状态,不把信封内容当作终值。

deliveryToken 是一个共享密钥式的承载凭据(校验「推送是否来自本平台」);基于密钥对每条 payload 做请求签名(防篡改)的能力仍在后续版本规划中。在其提供前,按上述方式承载来源校验。

六、投递记录与手动重投

每次投递都会落一条可查询的记录,用于排障:

bash
# 查某订阅的投递记录
curl -X GET 'https://api.atkonbase.example.com/v1/webhooks/getDeliveries?webhookId=${webhookId}&page=1&pageSize=20' \
  -H 'Authorization: Bearer ${accessToken}'

投递记录关键字段:

字段含义
statusPENDING(待投递)/ RETRYING(重试中)/ SUCCESS(成功)/ FAILED(达上限失败)
attemptCount已尝试次数
lastResponseCode最近一次下游响应码(超时/连接失败时为空)
lastResponseBody最近一次下游响应体片段(截断保存,便于定位下游报错)
lastError最近一次失败的错误信息
nextRetryAt下次重试时间(终态时为空)

手动重投

下游修复后,可对某条投递记录触发重新投递——重置为待投递并清零尝试计数,随后被重新推送:

bash
curl -X POST 'https://api.atkonbase.example.com/v1/webhooks/redeliver?deliveryId=${deliveryId}' \
  -H 'Authorization: Bearer ${accessToken}'
  • 重投携带与原推送相同的 eventId——若该事件此前已被你成功处理,幂等去重应让重投不产生重复副作用。

常见坑

  • ⚠️ 接收端点不幂等:未按 eventId 去重,重试 / 重投导致同一事件被处理多次。规避:先查 eventId 是否已处理,已处理直接返回 2xx。
  • ⚠️ 把信封当详情用:信封只有资源 ID,不含内容;漏了回调取详情会拿不到业务字段。规避:收到事件后用 resource.id 回查资源端点。
  • ⚠️ 接收端点慢:处理耗时超过下游读取超时会被判失败并重试。规避:接收端点快速入队后立即返回 2xx,业务处理异步做。
  • ⚠️ 误期望顺序:同一订阅多事件不保证到达顺序。规避:以资源当前状态为准(回查),不依赖事件先后。
  • ⚠️ 订阅 PAUSED 期间的事件不会补投:暂停期间发生的事件不积压、恢复后不补发。规避:需要不漏接时改用 DISABLED/ACTIVE 切换前评估,或暂停后用查询补齐。
  • ⚠️ 删除是「移入回收站」语义*.deleted 对应 trash,不是彻底清除;彻底清除不推送。规避:按 trash 语义处理删除事件。

下一步