Webhook 페이로드
헤더
- X-Retry-Count - 문자열
- X-Freshchat-Payload-Version - 문자열
- X-Freshchat-Signature - 문자열
이벤트
- message_create
- conversation_assignment
- conversation_resolution
- conversation_reopen
actor_type - 사용자, 에이전트, 시스템
Message_type - 일반, 비공개
1. message_create
{
"actor": {
"actor_type": "agent",
"actor_id": "1b8d2418-89a3-4de6-b93c-9f6557f13d04"
},
"action": "message_create",
"action_time": "2022-11-22T10:55:23.126Z",
"data": {
"message": {
"message_parts": [
{
"text": {
"content": "হাই সেখানে! আমি আজ তোমার জন্য কি করতে পারি?"
}
}
],
"app_id": "c6ec783e-4c89-490a-bbbc-32c97e2a8c3d",
"actor_id": "1b8d2418-89a3-4de6-b93c-9f6557f13d04",
"id": "a834cd45-c463-4644-b254-be920924a998",
"channel_id": "304d0a73-5135-4be6-9df3-7a4aa2a0d855",
"conversation_id": "35e80ec8-c697-42e4-8ce9-a47a050b1d1a",
"interaction_id": "681406910844650-1669114522220",
"actor_type": "agent",
"created_time": "2022-11-22T10:55:23.126Z",
"user_id": "9047e655-1e83-463e-b1b6-4a44beb1f07f",
"restrictResponse": false,
"botsPrivateNote": false
}
}
}
2. conversation_reopen
{
"actor": {
"actor_type": "user",
"actor_id": "9047e655-1e83-463e-b1b6-4a44beb1f07f"
},
"action": "conversation_reopen",
"action_time": "2022-11-22T10:55:22.272Z",
"data": {
"reopen": {
"reopener": "user",
"reopener_id": "9047e655-1e83-463e-b1b6-4a44beb1f07f",
"conversation": {
"conversation_id": "35e80ec8-c697-42e4-8ce9-a47a050b1d1a",
"app_id": "c6ec783e-4c89-490a-bbbc-32c97e2a8c3d",
"status": "reopened",
"channel_id": "304d0a73-5135-4be6-9df3-7a4aa2a0d855",
"skill_id": 0,
"sla_policy_id": 0,
"sla_breached": false
},
"interaction_id": "681406910844650-1669114522220"
}
}
}
3. conversation_resolution
{
"actor": {
"actor_type": "agent",
"actor_id": "fc2d90bc-688b-46bc-a5f0-bcd60b7c2370"
},
"action": "conversation_resolution",
"action_time": "2022-11-22T10:54:42.298Z",
"data": {
"resolve": {
"resolver": "agent",
"resolver_id": "fc2d90bc-688b-46bc-a5f0-bcd60b7c2370",
"conversation": {
"conversation_id": "35e80ec8-c697-42e4-8ce9-a47a050b1d1a",
"app_id": "c6ec783e-4c89-490a-bbbc-32c97e2a8c3d",
"status": "resolved",
"channel_id": "304d0a73-5135-4be6-9df3-7a4aa2a0d855",
"skill_id": 0,
"sla_policy_id": 0,
"sla_breached": false
},
"interaction_id": "681406910844650-1669114480262",
"user": {
"properties": [
{
"name": "fc_user_timezone",
"value": "Asia/Calcutta"
}
],
"created_time": "2022-11-22T10:51:48.696Z",
"updated_time": "2022-11-22T10:52:01.119Z",
"id": "9047e655-1e83-463e-b1b6-4a44beb1f07f",
"first_name": "Friendly Pizza",
"avatar": {
"url": "https://s3.amazonaws.com/fresh-chat-names/img/pizza.png"
},
"login_status": false
}
}
}
}
4. conversation_assignment
{
"actor": {
"actor_type": "agent",
"actor_id": "fc2d90bc-688b-46bc-a5f0-bcd60b7c2370"
},
"action": "conversation_assignment",
"action_time": "2022-11-23T10:33:32.836Z",
"data": {
"assignment": {
"assignor": "agent",
"assignor_id": "fc2d90bc-688b-46bc-a5f0-bcd60b7c2370",
"to_agent_id": "fc2d90bc-688b-46bc-a5f0-bcd60b7c2370",
"to_group_id": "bea0f66b-0961-4aee-af1d-19a069f96467",
"from_agent_id": "",
"from_group_id": "bea0f66b-0961-4aee-af1d-19a069f96467",
"conversation": {
"conversation_id": "4424a18a-f624-4a1f-8800-c36356a64e5c",
"app_id": "c6ec783e-4c89-490a-bbbc-32c97e2a8c3d",
"status": "assigned",
"channel_id": "cde9ec2b-c462-45db-a873-1975cac7b1f2",
"assigned_agent_id": "fc2d90bc-688b-46bc-a5f0-bcd60b7c2370",
"assigned_org_agent_id": "380337516777740852",
"assigned_group_id": "bea0f66b-0961-4aee-af1d-19a069f96467",
"skill_id": 0,
"sla_policy_id": 0,
"sla_breached": false
},
"interaction_id": "677057091615181-1668052341499"
}
}
}
참고: from_agent_id와 to_agent_id가 채워지거나, from_group_id와 to_group_id가 채워집니다.
에이전트의 일반 메시지:
{
"actor": {
"actor_type": "agent",
"actor_id": "ae72b467-a0d2-43a6-a1c7-8cf33d68c7c4"
},
"action": "message_create",
"action_time": "2020-04-06T15:59:44.725Z",
"data": {
"message": {
"message_parts": [
{
"text": {
"content": "Hi!!! Agent this side"
}
}
],
"app_id": "87f6d88a-3921-4515-8acf-18fe4d2b4149",
"actor_id": "ae72b467-a0d2-43a6-a1c7-8cf33d68c7c4",
"id": "35814612-97f6-43bb-9266-cf6cd7cf6a0e",
"channel_id": "c5456f9e-9131-43aa-b3ec-29535bc7691d",
"conversation_id": "aecf3cc7-138a-4b40-9723-5bf4d1abb97b",
"message_type": "normal",
"actor_type": "agent",
"created_time": "2020-04-06T15:59:44.709Z",
"user_id": "5cac723a-13aa-473e-846b-9cdb7d2c41a5",
"message_source": "web"
}
}
}
에이전트의 비공개 노트:
{
"actor": {
"actor_type": "agent",
"actor_id": "999abdc6-e4b1-4944-a246-86f63109df7e"
},
"action": "message_create",
"action_time": "2020-04-07T13:26:27.646Z",
"data": {
"message": {
"message_parts": [
{
"text": {
"content": "This customer is also reaching out through email, follow up on both the ends."
}
}
],
"app_id": "c2bf4b15-38c5-49d1-b0d5-a2b86caac2b7",
"actor_id": "999abdc6-e4b1-4944-a246-86f63109df7e",
"id": "2c22af23-41bb-431d-a906-efe33a7294c6",
"channel_id": "8dfdec10-1c12-48d6-9889-40fba30daefa",
"conversation_id": "40c15ddf-74e0-41e5-870e-69187d085778",
"message_type": "private",
"actor_type": "agent",
"created_time": "2020-04-07T13:26:27.625Z",
"user_id": "a6ef2b6b-3fda-497e-bf3e-560b6f9612cd",
"message_source": "web"
}
}
}
사용자의 메시지:
{
"actor": {
"actor_type": "user",
"actor_id": "5cac723a-13aa-473e-846b-9cdb7d2c41a5"
},
"action": "message_create",
"action_time": "2020-04-06T15:59:29.981Z",
"data": {
"message": {
"message_parts": [
{
"text": {
"content": "User here, I am going"
}
}
],
"app_id": "87f6d88a-3921-4515-8acf-18fe4d2b4149",
"actor_id": "5cac723a-13aa-473e-846b-9cdb7d2c41a5",
"id": "ae46748d-daea-44ae-bd41-11eb4797853d",
"channel_id": "c5456f9e-9131-43aa-b3ec-29535bc7691d",
"conversation_id": "aecf3cc7-138a-4b40-9723-5bf4d1abb97b",
"message_type": "normal",
"actor_type": "user",
"created_time": "2020-04-06T15:59:29.971Z",
"message_source": "web"
}
}
}
시스템 메시지 (영업시간 외 메시지):
{
"actor": {
"actor_type": "agent",
"actor_id": "999abdc6-e4b1-4944-a246-86f63109df7e"
},
"action": "message_create",
"action_time": "2020-04-07T13:23:05.351Z",
"data": {
"message": {
"message_parts": [
{
"text": {
"content": "We are away now"
}
}
],
"app_id": "c2bf4b15-38c5-49d1-b0d5-a2b86caac2b7",
"actor_id": "999abdc6-e4b1-4944-a246-86f63109df7e",
"id": "5ea7ea3d-5bb3-4f78-8e11-15cad506b213",
"channel_id": "8dfdec10-1c12-48d6-9889-40fba30daefa",
"conversation_id": "40c15ddf-74e0-41e5-870e-69187d085778",
"actor_type": "agent",
"created_time": "2020-04-07T13:23:05.328Z",
"user_id": "a6ef2b6b-3fda-497e-bf3e-560b6f9612cd",
"message_source": "system"
}
}
}
에이전트에게 대화 할당:
{
"actor": {
"actor_type": "agent",
"actor_id": "999abdc6-e4b1-4944-a246-86f63109df7e"
},
"action": "conversation_assignment",
"action_time": "2020-04-07T13:35:18.622Z",
"data": {
"assignment": {
"assignor": "agent",
"assignor_id": "999abdc6-e4b1-4944-a246-86f63109df7e",
"to_agent_id": "999abdc6-e4b1-4944-a246-86f63109df7e",
"to_group_id": "f8552a49-e96d-400f-bea0-add54b5ba6fc",
"from_agent_id": "",
"from_group_id": "f8552a49-e96d-400f-bea0-add54b5ba6fc",
"conversation": {
"conversation_id": "40c15ddf-74e0-41e5-870e-69187d085778",
"app_id": "c2bf4b15-38c5-49d1-b0d5-a2b86caac2b7",
"status": "assigned",
"channel_id": "8dfdec10-1c12-48d6-9889-40fba30daefa",
"assigned_agent_id": "999abdc6-e4b1-4944-a246-86f63109df7e",
"assigned_group_id": "f8552a49-e96d-400f-bea0-add54b5ba6fc"
}
}
}
}
그룹에 대화 할당:
{
"actor": {
"actor_type": "agent",
"actor_id": "999abdc6-e4b1-4944-a246-86f63109df7e"
},
"action": "conversation_assignment",
"action_time": "2020-04-07T13:35:16.800Z",
"data": {
"assignment": {
"assignor": "agent",
"assignor_id": "999abdc6-e4b1-4944-a246-86f63109df7e",
"to_agent_id": "",
"to_group_id": "f8552a49-e96d-400f-bea0-add54b5ba6fc",
"from_agent_id": "",
"from_group_id": "",
"conversation": {
"conversation_id": "40c15ddf-74e0-41e5-870e-69187d085778",
"app_id": "c2bf4b15-38c5-49d1-b0d5-a2b86caac2b7",
"status": "new",
"channel_id": "8dfdec10-1c12-48d6-9889-40fba30daefa",
"assigned_group_id": "f8552a49-e96d-400f-bea0-add54b5ba6fc"
}
}
}
}
에이전트가 대화를 해결:
{
"actor": {
"actor_type": "agent",
"actor_id": "ae72b467-a0d2-43a6-a1c7-8cf33d68c7c4"
},
"action": "conversation_resolution",
"action_time": "2020-04-06T15:59:46.407Z",
"data": {
"resolve": {
"resolver": "agent",
"resolver_id": "ae72b467-a0d2-43a6-a1c7-8cf33d68c7c4",
"conversation": {
"conversation_id": "aecf3cc7-138a-4b40-9723-5bf4d1abb97b",
"app_id": "87f6d88a-3921-4515-8acf-18fe4d2b4149",
"status": "resolved",
"channel_id": "c5456f9e-9131-43aa-b3ec-29535bc7691d"
}
}
}
}
에이전트가 대화를 다시 엶:
{
"actor": {
"actor_type": "agent",
"actor_id": "999abdc6-e4b1-4944-a246-86f63109df7e"
},
"action": "conversation_reopen",
"action_time": "2020-04-07T13:28:49.194Z",
"data": {
"reopen": {
"reopener": "agent",
"reopener_id": "999abdc6-e4b1-4944-a246-86f63109df7e",
"conversation": {
"conversation_id": "40c15ddf-74e0-41e5-870e-69187d085778",
"app_id": "c2bf4b15-38c5-49d1-b0d5-a2b86caac2b7",
"status": "reopened",
"channel_id": "8dfdec10-1c12-48d6-9889-40fba30daefa"
}
}
}
}
사용자가 대화를 다시 엶:
{
"actor": {
"actor_type": "user",
"actor_id": "5cac723a-13aa-473e-846b-9cdb7d2c41a5"
},
"action": "conversation_reopen",
"action_time": "2020-04-06T15:59:50.314Z",
"data": {
"reopen": {
"reopener": "user",
"reopener_id": "5cac723a-13aa-473e-846b-9cdb7d2c41a5",
"conversation": {
"conversation_id": "aecf3cc7-138a-4b40-9723-5bf4d1abb97b",
"app_id": "87f6d88a-3921-4515-8acf-18fe4d2b4149",
"status": "reopened",
"channel_id": "c5456f9e-9131-43aa-b3ec-29535bc7691d"
}
}
}
}
인증
모든 웹훅 호출에는 X-Freshchat-Signature 헤더가 포함됩니다. 제공된 공개 키를 사용하여 서명을 검증하여 웹훅 호출을 인증할 수 있습니다.
아래는 Java로 구현된 웹훅 호출을 인증하는 예제 코드 스니펫입니다:
// 일부 언어에서는 "--BEGIN PRIVATE KEY--" 및 "--END PRIVATE KEY--" 부분을 잘라내야 합니다.
public static PublicKey loadPublicKey(String publicKeyString) throws Exception {
byte[] data = Base64.getDecoder().decode(publicKeyString);
X509EncodedKeySpec spec = new X509EncodedKeySpec(data);
KeyFactory fact = KeyFactory.getInstance(RSA);
return fact.generatePublic(spec);
}
// 위의 publicKey를 이 메서드에 전달하고, 서명과 평문은 웹훅 페이로드입니다.
// 페이로드와 서명이 일치하는지 확인합니다.
public static boolean verify(String plainText, String signature, PublicKey publicKey)
throws Exception {
Signature publicSignature = Signature.getInstance("SHA256withRSA");
publicSignature.initVerify(publicKey);
publicSignature.update(plainText.getBytes(UTF_8));
byte[] signatureBytes = Base64.getDecoder().decode(signature);
return publicSignature.verify(signatureBytes);
아래는 Ruby로 구현된 웹훅 호출을 인증하는 예제 코드 스니펫입니다:
key_from_settings = <설정 페이지의 웹훅 타일에서 가져온 공개 키>
@rsa = OpenSSL::PKey::RSA.new(key_from_settings)
signature = Base64.decode64(@header['HTTP_X_FRESHCHAT_SIGNATURE']) # 웹훅에서 전달됨
algorithm = OpenSSL::Digest::SHA256.new
# payload는 수신된 웹훅 JSON 페이로드입니다.
payload_verification = @rsa.verify(algorithm, signature, @payload.to_json.to_s)
expect(payload_verification).to be(true) 서명 및 암호화 로직에 대한 자세한 설명은 https://niels.nu/blog/2016/java-rsa.html을 참조하세요.