Webhook

최종 수정: 2026년 6월 22일

WebhookSpace에서 일이 일어났을 때(예: 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.id: Webhook의 고유 식별자입니다. 단일 조회·수정·삭제 경로의 {webhookId}에 들어갑니다.
  • url: 이벤트가 발생했을 때 호출할 외부 대상 URL입니다.
  • topics: 어떤 이벤트를 구독할지 정한 배열입니다. 아래 topics에서 형식을 설명합니다.
  • filters: 구독한 이벤트 중 실제로 트리거할 조건입니다. 아래 filters에서 설명합니다.
  • transformation: 나가는 요청의 모양(메서드·본문 등)을 바꾸는 설정입니다. 아래 transformation에서 설명합니다.
  • writeBacks: 외부 응답을 받아 ContentMedia에 도로 쓰는 작업의 배열입니다. 위 예시에는 없습니다. 아래 writeBacks에서 설명합니다.

시스템 속성 (sys)

모든 Webhook은 공통 시스템 속성을 sys 객체에 담습니다. space·createdBy·updatedByRefer 모양({ "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과 달리 publish·archive·status 같은 발행 상태 속성을 가지지 않고, 변경 추적용 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.Create, Content.Publish, Media.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.id·sys.contentType.sys.id·sys.createdBy.sys.id·sys.updatedBy.sys.id 중 하나입니다.
  • op: 비교 연산자. EQ·NE·IN·NOT_IN·REGEX·NOT_REGEX 중 하나입니다.
  • value: 비교 값. EQ·NE·REGEX·NOT_REGEX에는 문자열을, IN·NOT_IN에는 문자열 배열을 줍니다.

여러 필터를 두면 모두 만족해야 트리거합니다(AND). filters를 비우면 구독한 topics의 모든 이벤트가 트리거합니다.

transformation

transformation은 나가는 HTTP 요청의 모양을 바꿉니다. 지정하지 않으면 리소스 페이로드 전체가 기본 POST로 그대로 나갑니다.

타입설명
methodstringHTTP 메서드. GET·POST·PUT·DELETE·PATCH 중 하나.
contentTypestring요청 본문의 Content-Type.
bodyobject보낼 본문을 JSON Pointer 템플릿으로 구성하는 객체.
includeBodyboolean트리거 리소스의 본문을 함께 보낼지 여부.

writeBacks

writeBacksWebhook이 받은 외부 응답을 가지고 ContentMedia에 도로 쓰는 작업의 순서 있는 배열입니다. 외부 API가 2xx로 응답했을 때만 순서대로 실행됩니다. 각 항목은 $content(WriteBackContent) 또는 $media(WriteBackMedia)를 하나 가집니다.

WriteBackContent ($content)의 키:

타입설명
actionstringCreate·Update·Delete·Publish·Unpublish·Archive·Unarchive 중 하나.
contentTypeRefer<ContentType>Create 시 만들 Content Type. sys.id만 주면 됩니다.
targetstringUpdate·Delete 등에서 대상 Contentsys.id를 가리키는 JSON Pointer 템플릿(예: { /response/id }). { }로 감싸야 하며, 감싸지 않으면 리터럴로 취급합니다. 생략하면 Webhook을 트리거한 리소스를 대상으로 삼습니다.
localestringCreate·Update 시 값을 쓸 로케일. 로케일 코드나 포인터 템플릿. 생략하면 Space 기본 로케일.
fieldsobjectCreate·Update 시 대상 필드 키 → 소스 표현식 맵. 키는 대상 Content 필드의 apiName입니다.
publishbooleanCreate·Update 후 발행할지 여부. 기본값 true.
unpublishbooleanDelete 시 삭제 전 발행취소할지 여부. 기본값 true.

WriteBackMedia ($media)의 키:

타입설명
actionstringCreate·Delete·Publish·Unpublish·Archive·Unarchive 중 하나.
sourcestringCreateMedia로 가져올 값의 포인터 템플릿(예: { /response/data/0/url }). { }로 감싸야 합니다.
encodingstringCreatesource를 해석하는 방식. Url·Base64·Binary 중 하나.
localestringCreate 시 파일·제목·설명을 쓸 로케일. 생략하면 Space 기본 로케일.
titlestringCreateMedia 제목(소스 표현식 또는 리터럴).
descriptionstringCreateMedia 설명.
targetstringDelete 등에서 대상 Mediasys.id를 가리키는 포인터 템플릿. 생략하면 트리거 리소스가 대상.
publishbooleanCreate 시 처리 완료 후 발행할지 여부. 기본값 true.
unpublishbooleanDelete 시 삭제 전 발행취소할지 여부. 기본값 true.

다음은 외부 응답 JSON에서 값을 뽑아 Content 하나를 만드는 writeBacks 예시입니다.

"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의 키(productName·price)는 대상 Content 필드의 apiName입니다. 위 예시는 응답의 titleContentproductName에, priceprice에 채워 Content를 만든 뒤 발행합니다.

API

아래 모든 엔드포인트의 기준 URL은 https://cma.weegloo.com/v1이며, Authorization 헤더에 CMA를 인증하는 Bearer 토큰이 필요합니다. 수정(PUT)과 부분 수정(PATCH)은 낙관적 동시성 제어를 위해 X-Weegloo-Version 헤더(현재 리소스의 sys.version)를 함께 보내야 합니다.

  • Content: Webhook이 트리거되거나 WriteBack으로 쓰는 본문 데이터.
  • Media: WriteBack으로 만들 수 있는 파일 리소스.
  • SpaceRole: Webhook 작업 Content의 접근을 :self로 제한할 때.