Интеграция с CRM¶
REST API АТС позволяет реализовать интеграцию с CRM-системами, которых нет в МаркетПлейсе. Реализует следующие бизнес задачи:
обработка входящих вызовов и перевод на ответственных сотрудников;
сохранение истории вызовов по клиентам;
предоставление возможности прослушать ранее совершенные вызовы;
поднятие анкеты клиента;
совершение исходящих вызовов из CRM-системы;
управление статусами пользователей АТС.
Для корректной работы интеграцию необходимо выполнить в двухстороннем формате. В случае использования web_hook’а, его адрес должен быть статичным. Обмен происходит по протоколу HTTP и HTTPS.
Настройка первичных параметров выполняется в интерфейсе АТС, в разделе Пользовательская интеграция.
Авторизация¶
Все запросы между АТС и CRM выполняются с использованием ключей, указанных в параметрах интеграции. АТС отправляет запросы к CRM с API-ключом CRM. CRM отправляет запрос к АТС с API-ключом АТС. Ключи передаются в заголовках запроса в поле Authorization со значением вида «Bearer Значение ключа».
Ниже в примерах используются переменные:
crm_apikey - токен для доступа к методам CRM;
pbx_apikey - токен для доступа к методам АТС.
Запрос от АТС к CRM¶
Тестирование URL¶
В процессе настройки, необходимо проверить доступность URL, указанного в интеграции. Для этого АТС отправляет запрос:
POST {{crm_webhook}}
Content-Type: application/json
{
"action": "test",
"obj": "UserCRM",
"action_id": "123",
"params": {
}
}
Тестирование проходит успешно при ответе следующего вида:
{
"action": "test",
"obj": "UserCRM",
"code": 200,
"body": {
"success": true
}
}
Получение списка пользователей CRM¶
Для корректной работы интеграции необходимо реализовать запрос на получение списка пользователей от CRM. Работа интеграции невозможна без установки сопоставления пользователей АТС с пользователями CRM.
POST {{crm_webhook}}
Content-Type: application/json
Authorization: Bearer {{crm_apikey}}
{
"action": "get_users",
"obj": "UserCRM",
"action_id": "123",
"params": {
}
}
Пример ответа на запрос:
{
"action": "get_users",
"obj": "UserCRM",
"code": 200,
"body":[
{"id": "1", "name": "Менеджер Рита"},
{"id": "2", "name": "Менеджер Иван"}
]
}
Поиск ответственного сотрудника¶
Для обработки входящих запросов и закрепления вызова за ответственным сотрудником необходимо реализовать механизм поиска по номеру телефона. Поиск осуществляется по формату E164 без кода страны. К примеру +74951343060 преобразуется в 4951343060. В случае, если в параметрах маршрутизации разрешен перевод на ответственного, будет выполнен поиск среди сопоставленных пользователей CRM и АТС. Если абонент в АТС найден и он зарегистрирован, будет выполнен перевод.
POST {{crm_webhook}}
Content-Type: application/json
Authorization: Bearer {{crm_apikey}}
{
"action": "get_contact",
"obj": "UserCRM",
"action_id": "123",
"params": {
"phone": "4951343060"
"e164_phone": "74951343060"
}
}
Пример ответа на запрос:
{
"obj": "UserCRM", "action": "get_contact",
"code": 200,
"list": [
{
"name": "Компания",
"id": 1, <- ID компании
"type": "company",
"owner_id": 1004 - номер телефона абонента или ID абонента из CRM
},
{
"name": "Петров АА",
"id": 2, <- ID контакта
"type": "contact",
"company_id": "Компания",
"company_name": "1",
"owner_id": 1004 - номер телефона абонента или ID абонента из CRM
},
]
}
События¶
В процессе работы АТС генерирует события. Например: о статусе вызова, статусе регистрации абонента и так далее. Эти события в виде запрос АТС отправляет CRM. На стороне CRM необходимо реализовать ответные действия. К примеру при входящем звонке открыть карточку клиента или отобразить статусы абонентов в CRM.
Если CRM-система поддерживает работу с websocket, то запросы можно отправлять сразу в клиентское приложение. Каждое сообщение, отправляемое по вебсокету проверяется на принадлежность события пользователю, подключенному к АТС.
Сообщение о регистрации абонента¶
Поля status и protocol соответствуют описанию объекта DomainUser
{
'action': 'user_change',
'action_id': '73913ae3-3051-41bc-8bee-c2c689072a96',
'obj': 'UserCRM',
'code': 200,
'notifies': [],
'body': {
'user_uid': '9022',
'crm_user': '3',
'status': 1,
'protocol': 0
}
}
Сообщение о статусе сотрудника в коллценте¶
Поля base_status и extra_status соответствуют описанию объекта DomainAgent
{
'action': 'agent_change',
'action_id': '69dba658-a137-468b-be78-96d1965064c8',
'obj': 'UserCRM',
'code': 200,
'notifies': [],
'body': {
'user_uid': '1022',
'crm_user': '2',
'base_status': -1,
'extra_status': 1,
'status_name': 'В работе'
}
}
Сообщение о совершении вызова до ответа абонента¶
{
'action': 'call_ringing',
'action_id': '1b9b58c9-1787-4f80-8e39-8d2affac90d3',
'obj': 'UserCRM',
'code': 200,
'notifies': [],
'body': {
'call_id': '7c97ce9e-97aa-4549-9a92-e0d63f570db8',
'session_id': '93758923-1664-44eb-ae6c-59b27c53b805',
'crm_user': '3',
'domain_user': '9022',
'other_leg': '+74952523060',
'rt_vars': {'gateway_number': '74951343060'},
'direction': 0}
}
Сообщение о совершении вызова. Ответ абонента¶
{
'action': 'call_answer',
'action_id': '1b9b58c9-1787-4f80-8e39-8d2affac90d3',
'obj': 'UserCRM',
'code': 200,
'notifies': [],
'body': {
'call_id': '7c97ce9e-97aa-4549-9a92-e0d63f570db8',
'session_id': '93758923-1664-44eb-ae6c-59b27c53b805',
'crm_user': '3',
'domain_user': '9022',
'other_leg': '+74952523060',
'rt_vars': {'gateway_number': '74951343060'},
'direction': 0}
}
Сообщение о завершении вызова¶
{
'action': 'call_hangup',
'action_id': '1b9b58c9-1787-4f80-8e39-8d2affac90d3',
'obj': 'UserCRM',
'code': 200,
'notifies': [],
'body': {
'call_id': '7c97ce9e-97aa-4549-9a92-e0d63f570db8',
'session_id': '93758923-1664-44eb-ae6c-59b27c53b805',
'crm_user': '3',
'domain_user': '9022',
'other_leg': '+74952523060',
'rt_vars': {'hangup_cause': 'NORMAL_CLEARING'},
'direction': 0,
'variable_answersec': '9'}
}
Сообщение о формировании CDR¶
{
'action': 'cdr_append',
'action_id': '6ce285e6-c704-4857-a64a-510aa8c3cb40',
'obj': 'UserCRM',
'code': 200,
'notifies': [],
'body': {
'id': 112666,
'uniqueid': '5548f6ab-efab-4dd9-843b-c53f50a5506a',
'dt': 1633333012.0,
'src': '9022',
'dst': '+74952523060',
'duration': 14,
'billsec': 3,
'cc_queue_waiting_time': 0,
'lastapp': 'bind_digit_action',
'lastdata': 'office.runtel.org,~%5C*1,exec%3Aexecute_extension,*1%20XML%20office.runtel.org,a',
'rec_path': 'office.runtel.org/2021-10-04/',
'gateway': 'Test1',
'gateway_number': '+74951343060',
'dial_status': 0,
'direction': 0,
'project_id': 0,
'project_name': '',
'bridge_hangup_cause': 'NORMAL_CLEARING',
'hold_accum_seconds': 0,
'geo_ids': '...',
'geo_names': '...',
'link': 'https://pbx.runtel.org/get_file?file=onWde...'
}
}
Сообщение о переводе вызова в hold¶
{
'action': 'call_held',
'action_id': '4a9e14e4-cc87-4ec0-958d-4a36230ecd52',
'obj': 'UserCRM',
'code': 200,
'notifies': [],
'body': {
'user_uid': '9022',
'crm_user': '3',
'call_id': 'd319b916-e987-4c0f-9b08-b915a72526fb',
'session_id': 'd319b916-e987-4c0f-9b08-b915a72526fb',
'other_leg': '+79066800404',
'direction': 0
}
}
Сообщение о выходе из режими hold¶
{
'action': 'call_active',
'action_id': '4a9e14e4-cc87-4ec0-958d-4a36230ecd52',
'obj': 'UserCRM',
'code': 200,
'notifies': [],
'body': {
'user_uid': '9022',
'crm_user': '3',
'call_id': 'd319b916-e987-4c0f-9b08-b915a72526fb',
'session_id': 'd319b916-e987-4c0f-9b08-b915a72526fb',
'other_leg': '+79066800404',
'direction': 0
}
}
Запрос от CRM к АТС¶
Получение истории вызовов¶
Получение истории вызовов необходимо для отображения в карточке клиента. Возможна фильтрация по номеру телефона, направлению и дате совершения вызова.
POST {{v2_host}}/integration/usercrm/
Content-Type: application/json
Authorization: Bearer {{pbx_apikey}}
{
"action": "get_cdr",
"obj": "UserCRM",
"action_id": "123",
"sort": {"dt": "+"},
"limit": 10,
"offset": 0,
"params": {
"start_dt": "1633074025",
"end_dt": "1633074725",
"src_or_dst_list": ["+74951343060", "+74952523060"]
}
}
Параметры отбора значений идентичны тем, что используется при получении истории вызовов в объекте ReportCallsHistory.
Совершение исходящего вызова¶
Если CRM-система позволяет интегрировать WEB-телефон, то обычно используется такое решение как более функциональное. Если используются учетные записи с протоколом SIP, для вызова из CRM необходимо реализовать инициализацию вызова. При отправке запроса вызов сначала поступает на пользователя и как только он отвечает, вызов совершается клиенту. Этот метод работает только для пользователей, которые добавлены в интеграцию.
POST {{v2_host}}/integration/usercrm/
Content-Type: application/json
Authorization: Bearer {{pbx_apikey}}
{
"action": "make_call",
"obj": "UserCRM",
"action_id": "123",
"params": {
"crm_user_id": "user_crm_30",
"dst": "89066800404"
}
}
Установка вызова на удержание¶
Метод позволяет поставить вызов на удержание или снять с него.
POST {{v2_host}}/integration/usercrm/
Content-Type: application/json
Authorization: Bearer {{pbx_apikey}}
{
"action": "switch_call_hold",
"obj": "UserCRM",
"action_id": "123",
"params": {
"crm_user_id": "user_crm_30",
"call_id": "725d2f5b-34e3-48df-96f4-8fa729da1098"
}
}
Параметры запроса
Name |
Type |
Description |
---|---|---|
crm_user_id |
StringType |
ID пользователя из CRM |
call_id |
StringType |
ID вызова |
Ответ на запрос
POST {{v2_host}}/integration/usercrm/
Content-Type: application/json
Authorization: Bearer {{pbx_apikey}}
{
"action": "switch_call_hold",
"obj": "UserCRM",
"action_id": "123",
"params": {
"crm_user_id": "user_crm_30",
"call_id": "725d2f5b-34e3-48df-96f4-8fa729da1098"
}
}
Метод получения списка пользователей¶
Метод позволяет получить список пользователей, так как некоторые интеграции сохраняют списки пользователей на своей стороне.
{
"action": "get_domain_user_list",
"obj": "UserCRM",
"params": {}
}
Ответ на запрос
{
"action": "get_domain_user_list",
"action_id": "999f1bf8-1032-467f-94ad-875dc72ec26a",
"obj": "UserCRM",
"code": 200,
"notifies": [],
"body": [
{
"user_name": "Иванов",
"user_surname": "",
"uid": "777",
"id": 3103,
"proto": 0
},
{
"user_name": "Петров",
"user_surname": "",
"uid": "1111",
"id": 1937,
"proto": 0
}
]
}