Webhook

最后更新:2026年6月22日

Webhook 是当 Space 中发生某件事时(例如 Content 创建、发布),向预先指定的外部 URL 发送 HTTP 请求的配置。用于外部系统集成或自动化。例如,可以配置为在每次商品 Content 发布时调用公司内部的通知服务器,或调用外部 API。

Webhook 不止于发送请求,还可以接收响应并将其回写到 ContentMedia,即配置 WriteBack。通过这种方式构建将外部 API 结果吸收为 Space 内数据的异步作业流程。Webhook 在 CMA 中是 Space 的下级资源,路径以 /spaces/{spaceId}/webhooks 为基准。

资源结构

下面是 Webhook “商品变更通知” 的单条查询响应。它在 sys(系统属性)之外,还拥有发送目标、订阅事件、触发条件等配置字段。

{
  "sys": {
    "id": "3trmXRM3RqbgSnifyg7PWhk01Examp",
    "type": "Webhook",
    "space": { "sys": { "id": "HnQ32YiH", "type": "Refer", "targetType": "Space" } },
    "createdBy": { "sys": { "id": "3p4tcFbQRwz503VXdtHXNI5dZH5TVB", "type": "Refer", "targetType": "User" } },
    "createdAt": "2026-06-18T11:30:00.000Z",
    "updatedBy": { "sys": { "id": "3p4tcFbQRwz503VXdtHXNI5dZH5TVB", "type": "Refer", "targetType": "User" } },
    "updatedAt": "2026-06-18T11:30:00.000Z",
    "version": 1
  },
  "name": "商品变更通知",
  "filters": [
    { "doc": "sys.contentType.sys.id", "op": "EQ", "value": "3trmXRLdJF4GBlAjtcuoZ7Pnxj8dlA" }
  ],
  "headers": [
    { "key": "X-Source", "value": "weegloo", "secret": false }
  ],
  "httpBasicUsername": "dailywear",
  "topics": ["Content.Create", "Content.Publish"],
  "transformation": { "method": "POST", "contentType": "application/json", "includeBody": true },
  "url": "https://api.dailywear.example/webhooks/products",
  "activate": true
}

主要键:

  • sys.idWebhook 的唯一标识符。用于单条查询、修改、删除路径中的 {webhookId}
  • url:事件发生时调用的外部目标 URL。
  • topics:定义订阅哪些事件的数组。格式在下文 topics 中说明。
  • filters:在已订阅的事件中实际触发的条件。在下文 filters 中说明。
  • transformation:改变出站请求形态(方法、正文等)的配置。在下文 transformation 中说明。
  • writeBacks:接收外部响应并回写到 ContentMedia 的作业数组。上面的示例中没有。在下文 writeBacks 中说明。

系统属性 (sys)

每个 Webhook 都在 sys 对象中包含公共系统属性。spacecreatedByupdatedByRefer 形态({ "sys": { "id", "type": "Refer", "targetType" } })出现。

属性类型说明
idstring资源唯一标识符。
typestring资源类型。Webhook 始终为 "Webhook"
spaceRefer<Space>Webhook 所属的 Space
createdByRefer<User>创建该资源的用户。
createdAtstring (date-time)创建时间。
updatedByRefer<User>最后修改该资源的用户。
updatedAtstring (date-time)最后修改时间。
versioninteger (≥1)资源版本。每次修改递增 1。

Webhook 是配置型资源,因此没有发布这一概念。与 ContentContent Type 不同,它不具备 publisharchivestatus 等发布状态属性,只有用于变更追踪的 version。开启与关闭不是通过发布,而是通过正文字段 activate 控制。

正文属性

Webhook 的正文(创建、修改时发送,并作为响应返回的配置值)由以下字段构成。

字段类型必填说明
namestring (1~64)Webhook 名称。
urlstring (url)事件发生时调用的外部目标 URL。
activateboolean是否开启。为 false 时即使事件发生也不发送请求。
topicsstring[]订阅的事件数组。参见下文 topics
filtersFilter[]触发条件数组。留空则所有已订阅的事件都会触发。参见下文 filters
headersWebhookHeader[] (0~30)随请求一起发送的 HTTP 头数组。
httpBasicUsernamestring (1~32)HTTP Basic 认证用户名。
httpBasicPasswordstring (1~32)HTTP Basic 认证密码。仅写入。不会出现在响应中。
transformationTransformation自定义出站请求。参见下文 transformation
writeBacksWriteBack[]接收响应后执行的写入作业数组。参见下文 writeBacks

headers 的每个项目由 key(必填)、value(必填)、secret(可选,boolean)构成。secrettrue 的头,其值在响应中会被遮蔽。 像 API 密钥这类不应暴露的值,放在 secret: true 的头中。

topics

topics 的每个项目为 {资源}.{动作} 格式。例如:Content.CreateContent.PublishMedia.Create

动作为以下之一,或表示资源全部动作的 *(例如 Content.*)。

动作含义
All全部动作。
Create创建。
Read查询。
Edit编辑。
Save保存(修改)。修改事件是 Save,不是 Update
Delete删除。
Publish发布。
Unpublish取消发布。
Archive归档。
Unarchive取消归档。

filters

filters 是在已订阅的 topics 中缩小实际触发 Webhook 条件的数组。每个过滤器为以下形态。

{ "doc": "sys.contentType.sys.id", "op": "EQ", "value": "3trmXRLdJF4GBlAjtcuoZ7Pnxj8dlA" }
  • doc:要比较的字段路径。为 sys.idsys.contentType.sys.idsys.createdBy.sys.idsys.updatedBy.sys.id 之一。
  • op:比较运算符。为 EQNEINNOT_INREGEXNOT_REGEX 之一。
  • value:比较值。EQNEREGEXNOT_REGEX 使用字符串,INNOT_IN 使用字符串数组。

设置多个过滤器时,必须全部满足才会触发(AND)。将 filters 留空时,已订阅 topics 的所有事件都会触发。

transformation

transformation 改变出站 HTTP 请求的形态。不指定时,资源载荷整体以默认的 POST 原样发送。

类型说明
methodstringHTTP 方法。为 GETPOSTPUTDELETEPATCH 之一。
contentTypestring请求正文的 Content-Type。
bodyobject用 JSON Pointer 模板构成所发送正文的对象。
includeBodyboolean是否一并发送触发资源的正文。

writeBacks

writeBacksWebhook 用接收到的外部响应回写到 ContentMedia 的有序作业数组。仅当外部 API 以 2xx 响应时才按顺序执行。每个项目拥有一个 $content(WriteBackContent)或 $media(WriteBackMedia)。

WriteBackContent$content)的键:

类型说明
actionstringCreateUpdateDeletePublishUnpublishArchiveUnarchive 之一。
contentTypeRefer<ContentType>Create 时要创建的 Content Type。只需给出 sys.id
targetstringUpdateDelete 等中指向目标 Contentsys.id 的 JSON Pointer 模板(例如 { /response/id })。必须用 { } 包裹,不包裹则视为字面量。省略时以触发 Webhook 的资源为目标。
localestringCreateUpdate 时写入值的语言区域。为语言区域代码或指针模板。省略时为 Space 默认语言区域。
fieldsobjectCreateUpdate 时目标字段键 → 源表达式的映射。键为目标 Content 字段的 apiName
publishbooleanCreateUpdate 后是否发布。默认值 true
unpublishbooleanDelete 时删除前是否取消发布。默认值 true

WriteBackMedia$media)的键:

类型说明
actionstringCreateDeletePublishUnpublishArchiveUnarchive 之一。
sourcestringCreate 时要导入到 Media 的值的指针模板(例如 { /response/data/0/url })。必须用 { } 包裹。
encodingstringCreate 时解释 source 的方式。为 UrlBase64Binary 之一。
localestringCreate 时写入文件、标题、说明的语言区域。省略时为 Space 默认语言区域。
titlestringCreate 时的 Media 标题(源表达式或字面量)。
descriptionstringCreate 时的 Media 说明。
targetstringDelete 等中指向目标 Mediasys.id 的指针模板。省略时以触发资源为目标。
publishbooleanCreate 时处理完成后是否发布。默认值 true
unpublishbooleanDelete 时删除前是否取消发布。默认值 true

下面是从外部响应 JSON 中提取值创建一个 ContentwriteBacks 示例。

"writeBacks": [
  {
    "$content": {
      "action": "Create",
      "contentType": { "sys": { "id": "3trmXRLdJF4GBlAjtcuoZ7Pnxj8dlA" } },
      "locale": "ko-KR",
      "fields": {
        "productName": "{ /response/title }",
        "price": "{ /response/price }"
      },
      "publish": true,
      "unpublish": true
    }
  }
]

{ /response/... } 是从 Webhook 接收到的响应 JSON 中提取值的 JSON Pointer 模板。fields 的键(productNameprice)是目标 Content 字段的 apiName。上面的示例将响应中的 title 填入 ContentproductName,将 price 填入 price,创建 Content 后发布。

API

下面所有端点的基准 URL 为 https://cma.weegloo.com/v1,并且 Authorization 头中需要认证 CMA 的 Bearer 令牌。修改(PUT)和部分修改(PATCH)为实现乐观并发控制,需一并发送 X-Weegloo-Version 头(当前资源的 sys.version)。

  • ContentWebhook 触发时或通过 WriteBack 写入的正文数据。
  • Media:可通过 WriteBack 创建的文件资源。
  • SpaceRole:当用 :self 限制 Webhook 作业 Content 的访问时。