Установка вебхука в кабинет
Для того, чтобы прикрепить адрес вебхука к кабинету нужно:
- Получить авторизационный токен (используя логин и пароль)
curl --location 'https://iam.twin24.ai/api/v1/auth/login' \
--header 'Content-Type: application/json' \
--data '{
"email": "{{login}}",
"password": "{{password}}",
"ttl": 43200
}'
- Выполнить метод для привязки вебхука (вместо {{cabinet}} указать номер личного кабинета, вместо {{url}} — адрес вашего вебхука, для авторизации использовать токен из прошлого шага)
curl --location --request PATCH 'https://tcl.twin24.ai/api/iam/v1/companies/{{cabinet}}/settings' \
--header 'Authorization: Bearer {{auth_token}}' \
--header 'Content-Type: application/json' \
--data '{
"settings": {
"cis.webhooks.incomingCall": "https://webhook.site/d0513eed-9be8-4bcb-b1e7-c3dcb077d601"
}
}'
Формат вебхука
Пример вебхуков
Хука будет два на каждый звонок (из-за особенностей реализации внутри системы):
Как завершит работать бот
Как завершит работать "оболочка" над ботом
Разница между хуками в наличии во втором хука пути до аудизаписи диалога и биллинга по звонку.
- Пример первого хука
{
"callId": "88556d65-9bc1-46cf-ba2d-306842b238f7",
"startedAt": "2023-04-05 20:01",
"number": "79309990580",
"duration": 8,
"robotCallDuration": 8,
"robotCallTotalCost": "0.27",
"externalId": "005112a5-2633-47e7-89ee-0f0bddb3ac2e",
"currentStatusName": "ANSWERED",
"additional": null,
"recordPath": null,
"mainCallCost": "0",
"mainCallDiscount": "0",
"mainCallDuration": 0,
"mainCallTotalCost": "0",
"autoCallCost": "0",
"autoCallDiscount": "0",
"autoCallDuration": "0",
"autoCallTotalCost": "0",
"robotCallCost": "2.00",
"robotCallDiscount": "0",
"transferCallCost": "0",
"transferCallDiscount": "0",
"transferCallDuration": "0",
"transferCallTotalCost": 0,
"totalCost": "0.27",
"companyId": 1758,
"method": "callEnded",
"id": {
"identity": "88556d65-9bc1-46cf-ba2d-306842b238f7"
},
"createdAt": null,
"updatedAt": null,
"callerId": "79992082892",
"data": {
"flow": [
{
"botId": "11b17988-7e83-445a-ad3d-ec30f619edee",
"start": "2023-04-05 11:20:01.667647+03",
"end": "2023-04-05 11:20:07.709039+03",
"messages": [
{
"text": "Назови число",
"author": "BOT",
"time": "2023-04-05 11:20:01.667647+03"
},
{
"text": "11",
"author": "CLIENT",
"time": "2023-04-05 11:20:06.023713+03"
},
{
"text": "Ты назвал 11",
"author": "BOT",
"time": "2023-04-05 11:20:07.709039+03"
}
]
}
],
"duration": 8,
"totalCost": 0.27,
"result": {
"initialVariables": {
"phone": "79992082892"
},
"markers": [
"Вопрос",
"Ответ",
"Результат 1"
],
"confirmation": "Поле подтверждение",
"nps": "Поле нпс",
"Переменная_1": "Ее значение",
"Переменная_2": "Ее значение"
}
},
"taskName": null,
"taskCreatedAt": null,
"botId": "11b17988-7e83-445a-ad3d-ec30f619edee",
"callingNumber": "79992082892",
"timezone": 10800,
"messagesAsString": "BOT: Назови число\nCLIENT: 11\nBOT: Ты назвал 11",
"resultsString": {
"initialVariables": {
"phone": "79992082892"
},
"markers": [
"Вопрос",
"Ответ",
"Результат 1"
],
"confirmation": "Поле подтверждение",
"nps": "Поле нпс",
"Переменная_1": "Ее значение",
"Переменная_2": "Ее значение"
},
"emotion": null,
"hungUpBy": null,
"gender": null,
"nps": "Поле нпс",
"isAssistantRequest": null,
"markers": null,
"callbackData": []
}
- Пример второго хука по этому же диалогу
{
"callId": "88556d65-9bc1-46cf-ba2d-306842b238f7",
"startedAt": "2023-04-05 20:01",
"number": "79309990580",
"duration": 10,
"robotCallDuration": 8,
"robotCallTotalCost": "0.27",
"externalId": "005112a5-2633-47e7-89ee-0f0bddb3ac2e",
"currentStatusName": "ANSWERED",
"additional": null,
"recordPath": "/1672/2023/4/5/1680682799.7442646_79309990580_79992082892.mp3",
"mainCallCost": "1.30",
"mainCallDiscount": "0",
"mainCallDuration": 10,
"mainCallTotalCost": "0.22",
"autoCallCost": "0",
"autoCallDiscount": "0",
"autoCallDuration": "0",
"autoCallTotalCost": "0",
"robotCallCost": "2.00",
"robotCallDiscount": "0",
"transferCallCost": "0",
"transferCallDiscount": "0",
"transferCallDuration": "0",
"transferCallTotalCost": "0.22",
"totalCost": "0.49",
"companyId": 1758,
"method": "callEnded",
"id": {
"identity": "88556d65-9bc1-46cf-ba2d-306842b238f7"
},
"createdAt": null,
"updatedAt": null,
"callerId": "79992082892",
"data": {
"flow": [
{
"botId": "11b17988-7e83-445a-ad3d-ec30f619edee",
"start": "2023-04-05 11:20:01.667647+03",
"end": "2023-04-05 11:20:07.709039+03",
"messages": [
{
"text": "Назови число",
"author": "BOT",
"time": "2023-04-05 11:20:01.667647+03"
},
{
"text": "11",
"author": "CLIENT",
"time": "2023-04-05 11:20:06.023713+03"
},
{
"text": "Ты назвал 11",
"author": "BOT",
"time": "2023-04-05 11:20:07.709039+03"
}
]
}
],
"duration": 10,
"totalCost": 0.49,
"result": {
"initialVariables": {
"phone": "79992082892"
},
"markers": [
"Вопрос",
"Ответ",
"Результат 1"
],
"confirmation": "Поле подтверждение",
"nps": "Поле нпс",
"Переменная_1": "Ее значение",
"Переменная_2": "Ее значение"
}
},
"taskName": null,
"taskCreatedAt": null,
"botId": "11b17988-7e83-445a-ad3d-ec30f619edee",
"callingNumber": "79992082892",
"timezone": 10800,
"messagesAsString": "BOT: Назови число\nCLIENT: 11\nBOT: Ты назвал 11",
"resultsString": {
"initialVariables": {
"phone": "79992082892"
},
"markers": [
"Вопрос",
"Ответ",
"Результат 1"
],
"confirmation": "Поле подтверждение",
"nps": "Поле нпс",
"Переменная_1": "Ее значение",
"Переменная_2": "Ее значение"
},
"emotion": null,
"hungUpBy": null,
"gender": null,
"nps": "Поле нпс",
"isAssistantRequest": null,
"markers": null,
"callbackData": []
}
Описание полей вебхука
Поле | Описание |
---|---|
callId | Идентификатор звонка в системе TWIN |
startedAt | Дата начала звонка |
number | Номер на который пришел звонок |
duration | Длительность звонка |
robotCallDuration | Длительность работы робота в звонке |
robotCallTotalCost | Стоимость работы робота в звонке |
externalId | НЕ АКТУАЛЬНО ДЛЯ ВХОДЯЩЕЙ |
currentStatusName | Статус звонка |
additional | НЕ АКТУАЛЬНО ДЛЯ ВХОДЯЩЕЙ |
recordPath | Путь до записи (запись расположена на хосте https://minio.twin24.ai/twin-cis-production/records по этому пути) |
mainCallCost | Тариф для основного звонка |
mainCallDiscount | Скидка для основного звонка |
mainCallDuration | Длительность основного звонка |
mainCallTotalCost | Стоимость основного звонка |
autoCallCost | НЕ АКТУАЛЬНО ДЛЯ ВХОДЯЩЕЙ |
autoCallDiscount | НЕ АКТУАЛЬНО ДЛЯ ВХОДЯЩЕЙ |
autoCallDuration | НЕ АКТУАЛЬНО ДЛЯ ВХОДЯЩЕЙ |
autoCallTotalCost | НЕ АКТУАЛЬНО ДЛЯ ВХОДЯЩЕЙ |
robotCallCost | Тариф работы робота в звонке |
robotCallDiscount | Скидка работы робота в звонке |
transferCallCost | Тариф переадрессации звонка |
transferCallDuration | Длительность переадрессованного звонка |
transferCallTotalCost | Стоимость переадрессованного звонка |
totalCost | Общая стоимость звонка |
companyId | Номер личного кабинета компании |
method | Метод, вызвавший отправку вебхука |
id.identity | == callId |
createdAt | НЕ АКТУАЛЬНО ДЛЯ ВХОДЯЩЕЙ |
updatedAt | НЕ АКТУАЛЬНО ДЛЯ ВХОДЯЩЕЙ |
callerId | Номер, позвонивший на входящую |
data | Массив данных по диалогу |
data.flow | Данные по работе каждого сценария (в звонке может быть несколько сценариев. Они отличаются по botId) |
data.flow.botId | Идентификатор сценария |
data.flow.start | Дата и время начала работы сценария |
data.flow.end | Дата и время конца работы сценария |
data.flow.messages | Сообщения в сценарии (Разделенные по Автору: Бот или Клиент) |
data.duration | == duration |
data.totalCost | == totalCost |
data.result | Массив результатов диалога |
data.result.initialVariables | НЕ АКТУАЛЬНО ДЛЯ ВХОДЯЩЕЙ |
data.result.markers | Массив маркеров (Опциональны для сценария) |
data.result.confirmation | Данные из поля “Подтверждение результата” |
data.result.nps | Данные из поля “NPS” |
data.result.переменная_1 | Данные из пользовательских полей, заданных в сценарии |
taskName | НЕ АКТУАЛЬНО ДЛЯ ВХОДЯЩЕЙ |
taskCreatedAt | НЕ АКТУАЛЬНО ДЛЯ ВХОДЯЩЕЙ |
botId | Идентификатор сценарий, который принял звонок |
callingNumber | == callerId |
timezone | таймзона |
messagesAsString | Весь диалог бота и клиента одной строкой |
resultsString | == data.result |
emotion | Определенная эмоция (при наличии блока в сценарии) |
hungUpBy | НЕ АКТУАЛЬНО ДЛЯ ВХОДЯЩЕЙ |
gender | Определенный пол (при наличии блока в сценарии) |
nps | == data.result.nps |
isAssistantRequest | Запросил ли бот “помощь” - перевод на оператора |
markers | НЕ АКТУАЛЬНО ДЛЯ ВХОДЯЩЕЙ |
callbackData | НЕ АКТУАЛЬНО ДЛЯ ВХОДЯЩЕЙ |