Webhook

옷가게 쇼핑몰을 운영한다고 생각해 보세요. 새 상품을 등록할 때마다 매번 직접 챙겨야 하는 뒷일이 있습니다. 상품 설명을 다른 나라 말로 번역해 두거나, 등록 사실을 사내 메신저에 알리는 일 같은 것입니다. 이런 뒷일을 사람이 매번 손으로 하지 않고, 상품이 등록되는 순간 바깥에 있는 프로그램에 자동으로 알려서 대신 처리하게 만들 수 있습니다. 이 "어떤 일이 생기면 미리 정해 둔 곳에 자동으로 알려 주는 장치"가 Webhook입니다.

가게 문에 달아 둔 초인종에 비유할 수 있습니다. 손님이 문을 열고 들어오면(상품이 등록되면) 초인종이 저절로 울려서, 안쪽에 있는 직원(바깥 프로그램)이 "손님 오셨네" 하고 곧바로 움직이기 시작합니다. 누군가 계속 문 앞을 지켜보고 있을 필요가 없습니다. Webhook은 그 초인종처럼, 정해 둔 일이 일어나는 순간 정해 둔 동작을 자동으로 시작합니다.

이 페이지에서는 Webhook이 무엇이고 어떤 경우에 쓰는지 먼저 살펴본 뒤, 옷가게 SpaceWebhook을 직접 만들어 봅니다.

Webhook이 하는 일

Webhook은 세 가지를 미리 정해 두는 것으로 이루어집니다.

  • 언제: 어떤 일이 일어났을 때 반응할지 정합니다. 예를 들어 "상품(Content)이 새로 등록됐을 때"로 정할 수 있습니다.
  • 무엇을 할지: 둘 중 하나를 정합니다. 바깥 프로그램의 인터넷 주소(URL)로 요청을 보내거나, Space 안에 만들어 둔 Script를 실행합니다.
  • 켤지 끌지: 이 Webhook을 지금 켜 둘지(Active), 잠시 꺼 둘지(Inactive)를 정합니다. 꺼 두면 정해 둔 일이 일어나도 아무 동작도 하지 않습니다.

정해 둔 일이 실제로 일어나면, Webhook은 정해 둔 동작을 수행합니다. 바깥 주소로 보내는 경우, 요청에는 무슨 일이 일어났는지, 어떤 상품에서 일어났는지 같은 정보가 담겨 갑니다. 요청을 받은 바깥 프로그램은 그 정보를 보고 자기 할 일을 합니다.

어떤 변화에 요청을 보내나

요청을 부르는 "일"은 Space 안의 자원에 일어나는 변화입니다. 상품 같은 Content, 업로드한 파일인 Media, 양식인 Content Type에 무언가 일어났을 때를 고를 수 있습니다.

자원마다 고를 수 있는 변화는 다음과 같습니다.

변화언제 일어나나옷가게 예시
Create새로 만들어졌을 때새 상품을 등록함
Save내용을 고쳐 저장했을 때상품 설명을 고쳐 저장함
Delete삭제됐을 때단종된 상품을 지움
Publish발행해 외부에 공개했을 때상품을 사이트에 공개함
Unpublish발행을 취소했을 때품절 상품을 사이트에서 내림
Archive보관 처리했을 때지난 시즌 상품을 보관함
Unarchive보관을 풀었을 때보관했던 상품을 되살림

예를 들어 "상품이 새로 등록될 때마다 요청을 보내라"는 "상품(Content)의 Create"를 고르는 것입니다.

Webhook에 여러 가지 변화를 함께 고를 수도 있습니다. "상품이 등록될 때"와 "상품이 수정될 때"를 모두 고르면, 둘 중 어느 쪽이 일어나도 요청이 갑니다.

조건을 걸어 좁히기

고른 변화가 일어났다고 해서 항상 요청을 보내고 싶지 않을 때가 있습니다. 예를 들어 "모든 Content가 아니라 '상품' 양식으로 만든 Content가 등록됐을 때만" 받고 싶을 수 있습니다. 이럴 때는 필터를 걸어 요청을 보낼 경우를 좁힙니다.

필터 하나는 "무엇을 기준으로, 어떻게 비교할지" 한 줄로 이루어집니다. 무엇을 기준으로 거를지는 네 가지 중에서 고릅니다.

  • 어떤 양식으로 만든 항목인지: 예를 들어 "상품" Content Type으로 만든 Content에만 요청을 보냅니다. 가장 자주 쓰는 조건입니다.
  • 특정 항목 하나인지: 정해 둔 그 항목 하나에서 일어난 변화에만 요청을 보냅니다.
  • 누가 만든 항목인지: 특정 사람이 만든 항목에만 요청을 보냅니다.
  • 누가 마지막으로 고친 항목인지: 특정 사람이 마지막으로 수정한 항목에만 요청을 보냅니다.

비교하는 방식도 함께 고릅니다. 정한 값과 같을 때만, 다를 때만, 정해 둔 여러 값 중 하나에 해당할 때만, 그 어느 것에도 해당하지 않을 때만, 또는 정한 형식(패턴)에 맞거나 맞지 않을 때만으로 좁힐 수 있습니다.

콘텐츠 스튜디오의 트리거 설정에서 필터 추가로 조건을 한 줄씩 더합니다. 필터를 여러 개 걸면 그 조건을 모두 만족하는 경우에만 요청이 가고, 하나도 걸지 않으면 고른 변화가 일어날 때마다 요청이 갑니다.

외부 프로그램이 원하는 모양으로 보내기

따로 정하지 않으면, 요청에는 변화가 일어난 항목의 정보가 통째로 담겨 갑니다. 예를 들어 상품 "스테인리스 텀블러 500ml"이 등록되면, 요청에 담겨 가는 내용은 대략 이런 모양입니다.

{
  "sys": { "id": "3trmXRM3RqbgSnifyg7OGhwhlqvAvq", "type": "Content" },
  "fields": {
    "productName": { "ko-KR": "스테인리스 텀블러 500ml" }
  }
}

(실제로는 더 많은 정보가 담기며, 위는 일부만 추린 모양입니다.) 바깥 프로그램이 이 안에서 필요한 값을 골라 쓰면 됩니다. 하지만 "이런 모양으로만 받겠다"고 형식이 정해진 프로그램도 있습니다. 그럴 때는 콘텐츠 스튜디오의 페이로드에서 Webhook 페이로드 커스터마이즈를 골라, 보낼 모양을 직접 적어 둡니다.

Webhook 만들기 화면의 헤더·페이로드 영역. 요청 본문 포함을 켜고 Webhook 페이로드 커스터마이즈를 고른 상태로, 아래 JSON 에디터에 보낼 모양을 적는다

보낼 모양을 적되, 위 데이터에서 값을 끌어다 넣을 자리에는 자리표시자를 씁니다. 자리표시자는 { /payload/… } 모양입니다. 여기서 payload는 위에 보인 그 항목 전체를 가리키고, 그 뒤 경로로 원하는 값을 지정합니다.

  • { /payload/sys/id } → 위 데이터의 sysid(상품의 고유 번호)
  • { /payload/fields/productName/ko-KR }fieldsproductNameko-KR(한국어 상품명). fields/ 뒤에는 Field의 ID(상품명이면 productName)와 언어 코드(한국어면 ko-KR)를 차례로 붙입니다.

예를 들어 번역 프로그램이 "번역할 글과 상품 번호를 이 모양으로 달라"고 한다면, 페이로드를 이렇게 적습니다.

{
  "id": "{ /payload/sys/id }",
  "text": "{ /payload/fields/productName/ko-KR }"
}

그러면 텀블러 상품이 등록되는 순간, 자리표시자가 실제 값으로 바뀌어 이렇게 전달됩니다.

{
  "id": "3trmXRM3RqbgSnifyg7OGhwhlqvAvq",
  "text": "스테인리스 텀블러 500ml"
}

같은 자리표시자는 보내는 주소(URL)나 헤더 값에도 넣을 수 있고, 보내는 방식(method)과 형식(JSON 또는 폼 형식)도 함께 고를 수 있습니다. 가리킨 경로에 값이 없으면 그 자리는 빈 값이 됩니다.

외부 API 키처럼 남에게 보이면 안 되는 값은 헤더를 추가할 때 타입을 Secret으로 지정해 둡니다. 그러면 그 값은 가려져 저장되고 최종 사용자에게 노출되지 않습니다.

헤더를 추가할 때 타입 드롭다운을 연 모습. Secret · HTTP Basic Auth · Custom 중에서 고른다

URL 대신 Script 실행하기

지금까지는 Webhook이 바깥 주소(URL)로 요청을 보내는 경우였습니다. Webhook은 그 대신 Space 안에 만들어 둔 Script를 실행하게 할 수도 있습니다. Script는 바깥에 나가지 않고 Space 안에서 정해 둔 작업(자원 만들기·고치기 등)을 대신 수행하는 장치입니다. 바깥 프로그램을 거치지 않고 Space 안에서 뒷일을 마치고 싶을 때 이 방식을 씁니다.

Webhook 하나는 바깥 주소로 보내기Script 실행하기 중 정확히 하나만 합니다. 만들기 화면의 요청 대상에서 정합니다. URL 직접 입력을 고르면 앞에서처럼 주소로 요청을 보내고, 대신 목록에서 Script 하나를 고르면 그 Script를 실행합니다.

Script를 고르면 그 Script누구의 신원으로 실행될지를 정하는 실행 주체가 함께 나타납니다. 둘 중 하나를 고릅니다.

  • Webhook 생성자(기본): 실행 중 만들어지거나 바뀐 자원의 "만든 사람"이 Webhook을 만든 사람으로 남습니다.
  • 트리거 유발 사용자: 그 변화를 일으킨 사용자로 남습니다.

이 설정은 자원에 남는 "누가 했는지" 표시를 정할 뿐, Script가 할 수 있는 일을 넓히거나 좁히지는 않습니다. Script가 할 수 있는 일의 범위는 그 Script를 만들 때 이미 정해집니다.

실제로 골라 보는 순서는 다음과 같습니다.

  1. 만들기 화면에서 요청 대상을 누르세요.
  2. 목록에서 실행할 Script를 고르세요. URL 직접 입력 대신 Script를 고르는 것입니다.
  3. 실행 주체에서 신원을 고르세요. 기본은 Webhook 생성자입니다.

Webhook 만들기 화면에서 요청 대상으로 "상품 설명 채우기" Script를 고른 상태. 채워진 호출 URL과 함께 실행 주체가 Webhook 생성자·트리거 유발 사용자 두 선택지로 나타난 모습

Script가 무엇이고 어떻게 만드는지는 Script에서 다룹니다.

옷가게 Webhook 만들기

이제 옷가게 SpaceWebhook을 하나 만들어 봅니다. "새 상품이 등록되면, 미리 준비해 둔 바깥 번역 프로그램에 그 사실을 알린다"는 Webhook입니다. 요청을 받을 바깥 프로그램의 주소는 https://example.com/translate라고 하겠습니다.

  1. 옷가게 Space의 설정에서 Webhook 화면을 여세요.
  2. 오른쪽 위의 생성 버튼을 누르세요.
  3. 이름 칸에 새 상품 번역 알림을 입력하세요. 이 이름은 나중에 어떤 Webhook인지 알아보기 위한 것입니다.
  4. 요청을 보낼 변화를 정하세요. 특정 변화에만 보내려면 특정 트리거 이벤트 선택을 고른 뒤 원하는 변화(여기서는 상품(Content)의 Create)를 지정하고, 모든 변화에 보내려면 모든 이벤트에 대해 트리거를 고릅니다.
  5. URL 칸에 요청을 받을 바깥 프로그램의 주소 https://example.com/translate를 입력하세요.
  6. 활성화를 켜 두면 만든 즉시 요청을 보냅니다(Active). 잠시 시험만 하려면 꺼 두세요(Inactive).
  7. 생성 버튼을 눌러 Webhook을 만드세요.

새 Webhook 생성 화면. 이름·활성화·트리거 선택·URL을 채운 모습

목록에 새 상품 번역 알림Active 상태로 나타나면 Webhook이 만들어진 것입니다.

Webhook 목록에 "새 상품 번역 알림"이 Active 상태로 보이는 화면

만든 뒤에는 옷가게에 실제로 새 상품을 하나 등록해 보세요. 등록하는 순간 Webhook이 적어 둔 주소로 요청을 보냅니다. 요청이 잘 갔는지, 바깥 프로그램이 어떻게 응답했는지는 Webhook의 호출 기록에서 확인할 수 있습니다.

켜고 끄기와 수정

Webhook은 만든 뒤에도 언제든 켜고 끌 수 있습니다. 잠시 요청을 멈추고 싶을 때는 삭제하지 말고 Inactive로 꺼 두세요. 꺼 둔 동안에는 새 상품을 등록해도 요청이 가지 않습니다. 다시 Active로 켜면 그때부터 다시 요청을 보냅니다.

만든 Webhook을 다시 열면 활성화를 끄거나 다시 켤 수 있습니다. 이름, 요청을 보낼 주소, 요청을 부르는 변화 같은 내용도 나중에 수정할 수 있고, 더는 쓰지 않는 Webhook은 삭제하면 됩니다.

다음으로 할 일

  • Content 모델링: Webhook이 요청을 부르는 대상인 "상품" 같은 Content의 양식을 만드는 방법을 다룹니다.
  • Content 작성하기: 실제 상품을 등록해 Webhook이 동작하는지 확인해 볼 수 있습니다.
  • Script: Webhook이 URL 대신 실행할 수 있는, Space 안에서 도는 작업을 만드는 방법을 다룹니다.
  • API 레퍼런스: Webhook을 프로그램에서 직접 만들고 관리할 때 쓰는 요청·응답 형식과 필드 명세를 다룹니다.