CLOSER Webhook 연동 가이드

CLOSER에서 전송하는 webhook의 자료 형태와 설정 방법등을 안내합니다.

CLOSER에서는 메시지 수신/발신, 고객 추가/삭제에 대한 이벤트들을 전달하는 webhook을 제공합니다.

Webhook 연동에 도움이 필요하시다면 support@closer.ai로 문의해주세요.

Webhook 설정 단계

  1. 본 문서에서는 Webhook의 포맷에 따라 목적에 맞는 API를 개발하세요.

  2. CLOSER Bot에서 개발하신 API의 URL을 등록합니다.

  3. CLOSER의 Bot을 사용시 발생하는 이벤트를 개발하신 API로 전송합니다.

Web Builder 에서 Webhook 전송 설정

  • Builder > 봇 설정 > Webhook 관리에서 Webhook URL을 등록/수정/삭제 하실 수 있습니다

  • 등록하신 Webhook URL이 동작하지 않는 경우 Builder에서 Webhook 전송이 자동으로 비활성화 됩니다

CLOSER에서 전송하는 Webhook 포맷

Webhook HTTP Headers

Key

Value

user-agent

CLOSER/webhook

content-type

application/json

Webhook POST body Example

일반

{
     "id": "00000000-0000-0000-0000-000000000000",
     "webhookId": "00000000-0000-0000-0000-000000000000",
     "webhookUrl": "http://your.webhook.com",
     "messages": [{
         "id": "00000000-0000-0000-0000-000000000000",
         "sourceId": "Bxxxxx",
         "sourceType": "bot",
         "event": "bot.end_user.updated",
         "data": {
             "endUser": {
                 "createdAt": "2018-09-04T07:06:53.047Z",
                 "deletedAt": null,
                 "id": "00000000-0000-0000-0000-000000000000",
                 "botId": "Bxxxxx",
                 "lastMessageId": "00000000-0000-0000-0000-000000000000",
                 "params": {
                 },
                 "platform": "web",
                 "userKey": "userKey",
                 "lastConversationId": "00000000-0000-0000-0000-000000000000",
                 "updatedAt": "2018-09-05T06:45:19.087Z"
             }
         },
         "timestamp": 1536129919092
     }, {
         "id": "00000000-0000-0000-0000-000000000001",
         "sourceId": "Bxxxxx",
         "sourceType": "bot",
         "event": "bot.conversation.created",
         "data": {
             "conversation": {
                 "endUserId": "00000000-0000-0000-0000-000000000000",
                 "createdAt": "2018-09-05T06:45:19.102Z",
                 "navigation": {},
                 "context": {
                     "navigation": {},
                     "conversationId": "00000000-0000-0000-0000-000000000000",
                     "botId": "Bxxxxx",
                     "params": {
                     },
                     "platform": "web",
                     "userKey": "userKey"
                 },
                 "id": "00000000-0000-0000-0000-000000000000",
                 "botId": "Bxxxxx",
                 "params": {
                 },
                 "userKey": "userKey",
                 "platform": "web",
                 "updatedAt": "2018-09-05T06:45:19.102Z"
             }
         },
         "timestamp": 1536129919116
     }]
 }

상담원 메시지

{
    "id": "00000000-0000-0000-0000-000000000000",
    "webhookId": "00000000-0000-0000-0000-000000000000",
    "webhookUrl": "http://your.webhook.com",
    "messages": [{
        "id": "00000000-0000-0000-0000-000000000000",
        "sourceId": "Bxxxxx",
        "sourceType": "bot",
        "event": "bot.message.sent",
        "data": {
            "message": {
                "endUserId": "00000000-0000-0000-0000-000000000000",
                "data": {
                    "text": "상담원 메시지",
                    "type": "text"
                },
                "requestId": "00000000-0000-0000-0000-000000000000",
                "meta": {
                    "sender": {
                        "userKey": "Uxxxxx",
                        "platform": "closer-chat"
                    }
                },
                "conversationId": "00000000-0000-0000-0000-000000000000",
                "id": "00000000-0000-0000-0000-000000000000",
                "isUser": false,
                "timestamp": 1536130434645
            }
        },
        "timestamp": 1536130434656
    }]
}

봇 메시지

{
     "id": "00000000-0000-0000-0000-000000000000",
     "webhookId": "00000000-0000-0000-0000-000000000000",
     "webhookUrl": "http://your.webhook.com",
     "messages": [{
         "id": "00000000-0000-0000-0000-000000000000",
         "sourceId": "Bxxxxx",
         "sourceType": "bot",
         "event": "bot.message.sent",
         "data": {
             "message": {
                 "endUserId": "00000000-0000-0000-0000-000000000000",
                 "data": {
                     "text": "테스트용 봇 메시지",
                     "type": "text"
                 },
                 "conversationId": "00000000-0000-0000-0000-000000000000",
                 "meta": null,
                 "id": "00000000-0000-0000-0000-000000000000",
                 "isUser": false,
                 "timestamp": 1536129919339
             }
         },
         "timestamp": 1536129919373
     }]
 }

고객 메시지

{
     "id": "00000000-0000-0000-0000-000000000000",
     "webhookId": "00000000-0000-0000-0000-000000000000",
     "webhookUrl": "http://your.webhook.com",
     "messages": [{
         "id": "00000000-0000-0000-0000-000000000000",
         "sourceId": "Bxxxxx",
         "sourceType": "bot",
         "event": "bot.message.received",
         "data": {
             "message": {
                 "endUserId": "00000000-0000-0000-0000-000000000000",
                 "data": {
                     "text": "고객 메시지",
                     "type": "text"
                 },
                 "requestId": "00000000-0000-0000-0000-000000000000",
                 "conversationId": "00000000-0000-0000-0000-000000000000",
                 "meta": null,
                 "id": "00000000-0000-0000-0000-000000000000",
                 "isUser": true,
                 "timestamp": 1536130242636
             }
         },
         "timestamp": 1536130243609
     }]
 }

Objects

DELIVERY

타입

필수

id

UUID

Y

Delivery ID

webhookId

UUID

Y

Webhook ID

webhookUrl

String

Y

Webhook URL

messages

Array(Object(EVENT))

Y

Event 오브젝트의 배열. 일정 시간동안 발생한 이벤트를 배열로 묶어 전달합니다.

EVENT

타입

필수

설명

id

UUID

Y

Event ID

event

String(EVENT_TYPE)

Y

Event 구분

sourceType

String('bot')

Y

Event를 발행한 소스

sourceId

String(BOT.id)

Y

Event 발행한 타입의 아이디. 'bot'인 경 Bot ID

timestamp

UNIX Timestamp with milliseconds

Y

Event 발생 시간

data

Object(EVENT.DATA)

Y

Event의 데이터

EVENT.DATA

타입

필수

설명

bot

Object(BOT)

C

event가 bot인 경우 필수

endUser

Object(ENDUSER)

C

event가 bot.end_user인 경우 필수

conversation

Object(CONVERSATION)

C

event가 bot.conversation인 경우 필

message

Object(MESSAGE)

C

event가 bot.message인 경우 필수

BOT

타입

필수

설명

id

String

Y

Bot의 ID

title

String(30)

Y

Bot의 이름

description

String(100)

N

Bot의 설명

integration

Object(BOT.INTEGRATION)

N

Bot의 연동 정보

preference

Object(BOT.PREFERENCE)

N

Bot의 설정 정보

data

Object(BOT.DATA)

N

Bot 동작에 필요한 데이터

createdAt

String(DateTime)

Y

생성 날짜

updatedAt

String(DateTime)

Y

업데이트 날짜

deletedAt

String(DateTime)

N

삭제 날짜

ENDUSER

타입

필수

설명

id

UUID

Y

EndUser의 ID

botId

String(BOT.id)

Y

Bot의 ID

platform

Y

메신저 타입

userKey

String(90)

Y

사용자 고유 키값

params

Object(Dictionary)

N

대화에서 사용하는 파라미터

lastMessageId

UUID(MESSAGE.id)

N

마지막 메시지의 ID

lastConversationId

UUID(CONVERSATION.id)

N

마지막 대화의 ID

lastConversation

Object(CONVERSATION)

N

마지막 대화 Object

createdAt

String(DateTime)

Y

생성 날짜

updatedAt

String(DateTime)

Y

업데이트 날짜

deletedAt

String(DateTime)

N

삭제 날짜

CONVERSATION

타입

필수

설명

id

UUID

Y

Conversation의 ID

botId

String(BOT.id)

Y

Bot의 ID

endUserId

UUID(ENDUSER.id)

Y

EndUser의 ID

platform

Y

메신저 타입

userKey

String(90)

Y

사용자의 고유 키값

params

Object(Dictionary)

N

대화에서 사용하는 파라미터

context

Object(CONTEXT)

N

대화의 정보

navigation

N

대화의 위치

createdAt

String(DateTime)

Y

생성 날짜

updatedAt

String(DateTime)

Y

업데이트 날짜

MESSAGE

타입

필수

설명

id

UUID

Y

Message의 ID

endUserId

UUID(ENDUSER.id)

Y

EndUser의 ID

conversationId

UUID(CONVERSATION.id)

Y

Conversation의 ID

isUser

Boolean

Y

true인 경우 고객, false인 경우 봇이나 상담원

meta

Object(MESSAGE.META)

N

상담원이 경우 meta에 상담원 정보가 포함됨

data

Object(MESSAGE.DATA)

Y

메시지의 데이터

timestamp

UNIX Timestamp with milliseconds

Y

메시지 발행 시간

MESSAGE.DATA

타입

필수

설명

type

String(MESSAGE_TYPE)

Y

MESSAGE의 타입

text

String(1000)

C

text 타입인 경우 필수

media

C

media 타입인 경우 필수

cards

Array(Object(MESSAGE.DATA.CARD))

C

cards 타입인 경우 필수

location

C

location 타입인 경우 필수

button

N

메시지에 포함된 버튼으로 KEYBOARD.BUTTON과는 형식과 동작이 다름. 링크 삽입 가능

MESSAGE.META

타입

필수

설명

sender

N

메시지를 전송한 전송자의 정보

MESSAGE.DATA.MEDIA

타입

필수

설명

contentType

'image', 'video', 'audio', 'link'

Y

이미지, 동영상, 오디오, 링크

uri

String

Y

이미지, 동영상, 오디오, 링크의 URL

MESSAGE.DATA.BUTTON

타입

필수

설명

label

String(255)

Y

버튼 인터페이스에 노출할 이름

uri

String

N

버튼이 링크로 동작 시 URL, 없으면 키보드 입력 동작

MESSAGE.DATA.CARD

타입

필수

설명

title

String(50)

Y

카드의 제목

description

String(500)

N

카드의 설명

media

N

카드에 포함될 미디어

uri

String

N

카드 선택시 이동할 링크 URL

buttons

Array(Object(MESSAGE.DATA.BUTTON))

N

카드에 포함된 버튼 리스트

MESSAGE.DATA.LOCATION

타입

필수

설명

title

String(50)

N

위치의 이름

latitude

Number

Y

GPS Latitude

longitude

Number

Y

GPS longitude

MESSAGE.META.SENDER

타입

필수

설명

userKey

String(90)

Y

SENDER 사용 시 필수. 전송자의 ID

platform

String(100)

Y

SENDER 사용 시 필수. 전송자의 플랫폼

KEYBOARD

  • CLOSER의 입력 Object로, 사용자의 입력 타입을 표현합니다.

  • text인 경우 사용자는 text를 입력할 수 있고, number인 경우 제약조건을 포함합니다.

  • buttons는 사용자의 입력을 button으로 받을 수 있도록 필요한 데이터를 포함합니다.

KEYBOARD의 사용자 입력 전송 방식

  • text : 사용자가 입력한 텍스트를 그대로 메시지에 전송합니다.

  • buttons : 사용자가 선택한 button의 label의 텍스트를 메시지에 전송합니다.

  • number : text와 동일하지만, 조건을 Front에서 검증하도록 개발할 수 있습니다.

타입

필수

설명

type

'text', 'number', 'buttons'

Y

텍스트, 숫자, 버튼 입력

min

Number

C

number 타입인 경우에 필수, 최소값

max

Number

C

number 타입인 경우에 필수, 최대값

parse

Boolean

N

false인 경우 숫자만 입력 가능, true인 경우 주어진 문자열에서 숫자만 읽어들임

integer

Boolean

N

false인 경우 Integer만 입력 가능

buttons

Array(Object(KEYBOARD.BUTTON))

C

buttons 타입인 경우에 필수

KEYBOARD.BUTTON

타입

필수

설명

label

String(255)

Y

버튼 인터페이스에 노출할 이름

params

Object(Dictionary)

N

버튼 선택 시 저장되는 파라미터. key - value dictionary 타입

CONTEXT

CLOSER에서 대화를 진행하는데 필요한 정보입니다. SDK의 WebChatClient가 Open되면 Context를 message listener에 전송합니다.

타입

필수

설명

botId

String

Y

Bot의 ID

conversationId

UUID

Y

대화의 ID. CLOSER에서 자동으로 생성됨

endUserId

UUID

Y

최종사용자의 ID. CLOSER에서 자동으로 생성됨

navigation

N

현재 대화의 위치를 표현하는 오브젝트

params

Object(Dictionary)

N

현재 대화에서 사용하고 있는 파라미터

platform

Y

플랫폼 타입

userKey

String(90)

Y

최종사용자 식별 키. SDK Open시 주입한 값

CONTEXT.NAVIGATION

타입

필수

설명

current

Y

현 노드의 정보

prev

N

이전 노드의 정보

CONTEXT.NAVIGATION.NODE

타입

필수

설명

flowId

Number

Y

현재 노드의 플로우 ID

nodeId

Number

Y

현재 노드의 ID

visitCount

Number

N

최종사용자가 노드에 방문한 수

AGENT

타입

필수

설명

id

String

Y

상담원의 User ID

profile

N

상담원의 profile 정보

AGENT.PROFILE

타입

필수

설명

displayName

String(30)

N

상담원의 DisplayName

picture

URL

N

상담원의 프로필 이미지 URL

Types

EVENT_TYPE

타입

설명

bot.updated

Bot의 정보 업데이트

bot.deleted

Bot이 삭제됨

bot.end_user.created

새로운 EndUser 생성

bot.end_user.updated

EndUser의 정보 업데이트

bot.end_user.deleted

EndUser가 삭제됨(친구삭제 등)

bot.conversation.created

새로운 Conversation 생성

bot.conversation.updated

Conversation의 정보 업데이트

bot.conversation.deleted

Conversation이 삭제됨(대화 만료)

bot.conversation.agent_call_requested

상담원에게 상담 요청

bot.conversation.agent_call_connected

상담 시작

bot.conversation.agent_call_cancelled

상담원에게 상담요청을 고객이 취소

bot.conversation.agent_call_disconnected

상담 종료

bot.message.sent

메시지 전송(봇, 상담원)

bot.message.received

메시지 수신(사용자)

PLATFORM_TYPE

타입

설명

kakao

카카오톡 스마트 API

kakaobiz

카카오 상담톡

facebook

페이스북 메신저

line

라인

navertalk

네이버톡톡

bizchat

SMS 문자 메시지 채팅 BizChat

wechat

위챗

web

웹챗

test

테스트용 챗

MESSAGE_TYPE

타입

설명

text

텍스트 메시지

media

이미지, 동영상, 오디오 등의 미디어

cards

카드 타입 리스트 (Carousel로 사용)

location

위치 정보 (latitude, longitude)

Last updated