Интеграция с CRM

REST API АТС позволяет реализовать интеграцию с CRM-системами, которых нет в МаркетПлейсе. Он решает следующие бизнес-задачи:

  • обработка входящих вызовов и перевод на ответственных сотрудников;

  • сохранение истории вызовов по клиентам;

  • предоставление возможности прослушать ранее совершенные вызовы;

  • поднятие анкеты клиента;

  • совершение исходящих вызовов из CRM-системы;

  • управление статусами пользователей АТС.

Для корректной работы интеграция должна быть двусторонней. В случае использования вебхука его адрес должен быть статичным. Обмен происходит по протоколу 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": {
    }
}

В params АТС может передавать один из вариантов отбора:

  • search (строка) — поиск пользователя по тексту;

  • id_list (список) — выборка по списку ID пользователей CRM;

  • limit (число, по умолчанию 100) и offset (число) — постраничная выборка.

Пример ответа на запрос:

{
    "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": 1,
            "company_name": "Компания",
            "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
    }
}

Сообщение о статусе сотрудника в колл-центре

АТС отправляет два отдельных события: об изменении состояния агента (domain_user_agent_agent_change) и об изменении его статуса (domain_user_agent_status_change). Значения полей см. в описании объекта DomainAgent.

{
    'action': 'domain_user_agent_agent_change',
    'action_id': '69dba658-a137-468b-be78-96d1965064c8',
    'obj': 'UserCRM',
    'code': 200,
    'notifies': [],
    'body': {
        'user_uid': '1022',
        'crm_user': '2',
        'state_id': 1,
        'state_name': 'В работе'
    }
}

Событие domain_user_agent_status_change устроено так же, но содержит поля status_id и 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"]
  }
}

Конверт запроса, помимо params, содержит: sort — сортировка (например {"dt": "+"}), limit — число записей на страницу (по умолчанию 10), offset — смещение (по умолчанию 0).

Фильтры запроса

Все фильтры передаются в params и необязательны:

Параметр

Тип

Описание

start_dt

unix-время

Начало периода. По умолчанию — последние 30 дней.

end_dt

unix-время

Конец периода.

range_dt

число

Готовый диапазон вместо start_dt/end_dt: 1 — час, 2 — сутки, 3 — сегодня, 4 — вчера, 5 — 7 дней, 6 — 30 дней, 7 — год, 8 — текущая неделя, 9 — текущий месяц, 10 — текущий год.

src_or_dst_list

список

Поиск по номеру звонящего ИЛИ принимающего.

src_list

список

Строго по звонящему (src).

dst_list

список

Строго по принимающему (dst).

direction_list

список чисел

Направление: 0 — исходящий, 1 — входящий, 2 — внутренний.

status_list

список чисел

Статус: 0 — отвечен, 1 — нет ответа, 2 — занято, 3 — трансфер, 4 — переадресация, 5 — автоответчик.

duration

строка

Длительность вызова, сек. Операторы >=N, <=N, >N, <N, =N; несколько условий через «;».

billsec

строка

Время разговора, сек. Операторы как у duration.

project_list

список

По ID проектов.

gw_number_list

список

По номеру шлюза.

gw_name_list

список

По названию шлюза.

pbx_user_list

список

По ID операторов.

org_list

список

По ID подразделений оргструктуры.

uniqueid_list

список

По конкретным UUID вызовов.

region_list

список

По региону.

geo_type_list

список

По типу гео-объекта.

recall_list

список

Перезвон: «0» — пропущенный, «1» — входящий, «2» — исходящий.

hangup_initiator

список чисел

Кто завершил: 0 — неизвестно, 1 — звонящий, 2 — принимающий, 3 — звонящий до соединения.

queue_quality

строка

Оценка качества. Операторы как у duration.

lastapp_list

список

По приложению FreeSWITCH (например callcenter).

custom_phrase_list

список

Полнотекстовый поиск по транскрипту вызова.

phrase_list

список

По ID групп фраз.

search

список

Быстрый поиск по номерам, шлюзу, uniqueid и имени пользователя.

seconds_to_time

логический

По умолчанию true. Выдавать длительности в формате ЧЧ:ММ:СС.

visible_fields

список

Какие поля вернуть в ответе. По умолчанию — все.

Поля ответа

Ответ — массив записей. Каждая запись содержит:

Поле

Тип

Описание

id

UUID

Уникальный идентификатор вызова.

f0

строка

Дата и время вызова (в часовом поясе домена).

f1

строка

Направление: outbound / inbound / internal.

f2 / f3

строка

Звонящий / принимающий.

f4 / f5

строка

Название / номер шлюза.

f6 / f7

строка/число

Длительность вызова / время разговора.

holds

строка/число

Суммарное время удержания.

f8

строка

Статус: answered / not answered / busy / transfer / forward / answer machine.

f9

строка

Название проекта.

f10 / f11

строка

Регион / тип номера.

f12

строка

Оценка качества звонка (CSI).

f13

URL

Ссылка на запись разговора.

f14

число/null

Перезвон: null — не применялся, 0 — пропущенный, 1 — входящий, 2 — исходящий.

f15

строка/число

Время ожидания в очереди.

f16

строка

Название последней очереди.

comment_cnt

число

Число замечаний к вызову.

hangup_initiator

число

Кто завершил: 0 — неизвестно, 1 — звонящий, 2 — принимающий, 3 — звонящий до соединения.

src_name / dst_name

строка

Имена операторов (звонящего / принимающего).

marks

строка

Метки вызова через «;».

org_name / org_head

строка

Отдел и его руководитель.

links

словарь

Служебное поле (всегда {}).

Примечание

Поля f6, f7, f15 и holds возвращаются в формате ЧЧ:ММ:СС при seconds_to_time: true (по умолчанию), иначе — целым числом секунд.

Совершение исходящего вызова

Если 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"
  }
}

Необязательный параметр call_id (UUID) позволяет задать идентификатор вызова самостоятельно; если он не передан, АТС сгенерирует его автоматически. В ответе возвращается call_id созданного вызова:

{
  "action": "make_call",
  "obj": "UserCRM",
  "action_id": "123",
  "code": 200,
  "body": {
    "call_id": "725d2f5b-34e3-48df-96f4-8fa729da1098"
  }
}

Установка вызова на удержание

Метод позволяет поставить вызов на удержание или снять с него.

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 вызова

Ответ на запрос

{
  "action": "switch_call_hold",
  "obj": "UserCRM",
  "action_id": "123",
  "code": 200
}

Метод получения списка пользователей

Метод позволяет получить список пользователей, так как некоторые интеграции сохраняют списки пользователей на своей стороне.

{
    "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
        }
    ]
}

В ответе каждого пользователя также присутствует поле secret — MD5-хеш md5("{id}|{apikey}"), который используется для получения токена CTI-панели (метод get_cti_token).

Прочие методы CRM → АТС

Ниже перечислены остальные методы, которые CRM вызывает у АТС (эндпоинт POST {{v2_host}}/integration/usercrm/ с заголовком Authorization: Bearer {{pbx_apikey}}). Часть методов доступна только по WebSocket — это отмечено.

Коллбэк (make_callback)

АТС сначала дозванивается до клиента, затем соединяет его с агентом.

Параметры params:

Параметр

Тип

Обяз.

Описание

dst

строка

да

Номер клиента для коллбэка

crm_entities

список

нет

Связанные CRM-сущности

gateway_number

строка

нет

Номер шлюза

is_callback

логический

нет

Признак коллбэка

Ответ: тело с call_id инициирующего вызова.

Перевод вызова (transfer_call)

Переводит активный вызов на другой номер или внутренний.

Параметры params:

Параметр

Тип

Обяз.

Описание

crm_user_id

строка

да

ID пользователя в CRM

call_id

UUID

да

ID вызова

dst

строка

да

Номер назначения

leg

строка

нет

Плечо: -aleg, -bleg (по умолчанию) или -both

Ответ: пустой (code: 200 без тела).

Завершение вызова (hangup_call)

Завершает вызов по его UUID.

Параметры params:

Параметр

Тип

Обяз.

Описание

crm_user_id

строка

да

ID пользователя в CRM

call_id

UUID

да

ID вызова

Ответ: пустой (code: 200 без тела).

Отправка DTMF (send_dtmf)

Отправляет DTMF-сигнал в активный вызов.

Параметры params:

Параметр

Тип

Обяз.

Описание

crm_user_id

строка

да

ID пользователя в CRM

session

UUID

да

UUID сессии вызова

dtmf

строка

да

Символы для отправки

Ответ: пустой (code: 200 без тела).

Список активных очередей (get_cc_queues)

Возвращает включённые очереди домена.

Параметры: нет.

Ответ: тело — словарь вида {queue_id: queue_name}.

Проверка вызова (check_call_exists)

Проверяет, существует ли активный вызов с указанным UUID.

Параметры params:

Параметр

Тип

Обяз.

Описание

crm_user_id

строка

да

ID пользователя в CRM

call_id

UUID

да

UUID вызова

Ответ: code: 200 если вызов существует, иначе ошибка.

Статус пользователя (get_domain_user_status)

Возвращает статус регистрации и статус агента пользователя АТС.

Параметры params:

Параметр

Тип

Обяз.

Описание

domain_user_uid

строка

нет

uid пользователя АТС

crm_user_id

строка

нет

ID пользователя в CRM (альтернатива uid)

Ответ: тело с полями register (протокол или null) и agent_base_status (число или null).

Обновление сопоставления (update_crm_users)

Обновляет соответствие пользователей CRM и АТС.

Параметры: params — словарь вида {"<crm_user_id>": <domain_user_id>}.

Ответ: пустой (code: 200 без тела).

Обновление данных вызова (update_call_info)

Привязывает к вызову CRM-сущность и дополнительные данные.

Параметры params:

Параметр

Тип

Обяз.

Описание

crm_user_id

строка

да

ID пользователя в CRM

call_id

UUID

да

UUID вызова

element_type

строка

нет

Тип сущности: company / contact / lead

element_id

нет

ID сущности

element_name

строка

нет

Название сущности

extra_data

нет

Произвольные данные

Ответ: пустой (code: 200 без тела).

Данные активного вызова (get_call_info)

Возвращает текущее состояние вызова (только WebSocket).

Параметры params:

Параметр

Тип

Обяз.

Описание

crm_user_id

строка

да

ID пользователя в CRM

call_id

UUID

да

UUID вызова

Ответ: тело: call_id, session_id, crm_user, domain_user, other_leg, rt_vars, direction и др.

Свой пользователь (get_my_domain_user)

Возвращает данные пользователя АТС, привязанного к WS-сессии (только WebSocket).

Параметры: нет.

Ответ: тело: uid, id, proto.

Свой статус (get_my_status)

Возвращает статус регистрации и агента текущего WS-пользователя (только WebSocket).

Параметры: нет.

Ответ: как у get_domain_user_status (register, agent_base_status).

Установка статуса агента (set_my_domain_user_agent_status)

Устанавливает статус агента текущего WS-пользователя (только WebSocket).

Параметры params:

Параметр

Тип

Обяз.

Описание

status_id

число

да

ID статуса агента

Ответ: пустой (code: 200 без тела).

Добавление в конференцию (add_conference_member)

Добавляет участника в конференцию вызова; если её нет — создаёт.

Параметры params:

Параметр

Тип

Обяз.

Описание

call_id

UUID

да

UUID вызова

member

строка

да

Номер участника

moderator

да

Признак модератора

Ответ: пустой (code: 200 без тела).

Произвольная задача (push_pm_action)

Отправляет произвольную задачу в очередь обработки модуля.

Параметры: params — произвольный словарь (передаётся в задачу целиком).

Ответ: пустой (code: 200 без тела).

Токен CTI-панели (get_cti_token)

Возвращает токен авторизации для CTI-панели по секрету пользователя.

Параметры params:

Параметр

Тип

Обяз.

Описание

secret

строка

да

Хеш из поля secret ответа get_domain_user_list

Ответ: полное тело авторизации пользователя (как crm_auth при mode=2).

Синхронизация по номерам (sync_users_by_phones)

Сопоставляет пользователей CRM и АТС по номерам телефонов.

Параметры: params — список объектов {"user_id": <id CRM>, "phone_number": <номер>}.

Ответ: тело с полями matched (сопоставленные) и not_found (не найденные в АТС).

Пример получения событий по WebSocket

// Константы для подключения к веб-сокету
var HOST = '{HOST}' // Хост сервера
var API_KEY = '{API_KEY}' // API ключ для аутентификации
var CRM_USER_ID = '{USER_ID}'; // ID пользователя CRM

// Запуск создания сокета с небольшой задержкой
setTimeout(createSocket, 500);

// Глобальные переменные для управления сокетом
var check_socket_timer, // Таймер для проверки состояния сокета
    proto,
    socket, // Объект веб-сокета
    socket_connect_trying = 0, // Счетчик попыток подключения
    last_call_id = null,
    not_matching_to_pbx_user = false // Флаг сопоставления пользователя

var self = this;

/**
 * Генерирует уникальный идентификатор (GUID)
 * @returns {string} Сгенерированный GUID
 */
function generateGUID() {
    return 'xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx'.replace(/[xy]/g, function(c) {
        let r = Math.random() * 16 | 0,
            v = c == 'x' ? r : (r & 0x3 | 0x8)
        return v.toString(16)
    })
}

/**
 * Создает WebSocket соединение
 */
function createSocket() {
    // Установка соединения с WebSocket
    socket = new WebSocket("wss://" + HOST + "/integration/usercrm/ws/");
    window.api_socket = socket;

    // Запуск таймера проверки сокета, если он еще не запущен
    if (!check_socket_timer) {
        check_socket_timer = setInterval(check_socket, 60000);
    }

    // Обработчик закрытия соединения
    socket.onclose = function (event) {
        if (socket_connect_trying < 5) {
            reconnect_socket(); // Попытка переподключения
        } else {
            proto = null;
            console.log('Сокет закрыт');
        }
    };

    // Обработчик входящих сообщений
    socket.onmessage = function (event) {
        console.log(event)
        var data = JSON.parse(event.data);

        // Обработка различных типов сообщений
        switch (data.action) {
            case 'connect':
                // Аутентификация при установлении соединения
                var auth_data = {
                    obj: 'WebSocketMember',
                    action: 'crm_auth',
                    action_id: generateGUID(),
                    params: {apikey: API_KEY, crm_user_id: CRM_USER_ID}
                };
                socket.send(JSON.stringify(auth_data));
                break;
            case 'crm_auth':
                // Обработка результатов аутентификации
                if (data.code == 200) {
                    socket_connect_trying = 0;
                    not_matching_to_pbx_user = false;
                    console.log(data.body);
                } if (data.code == 407) { // пользователь не сопоставлен
                    socket_connect_trying = 5;
                    not_matching_to_pbx_user = true;
                } else {
                    reconnect_socket();
                }
                break;
            // Обработчики для различных событий звонка
            case 'make_call':
            case 'ringing':
            case 'answer':
            case 'hangup':
                if (data.code == 200) {
                    console.log(data.body);
                }
                break;
        }
    };

    // Обработчик ошибок сокета
    socket.onerror = function (error) {
        reconnect_socket();
    };
};

/**
 * Попытка переподключения сокета
 */
function reconnect_socket() {
    socket_connect_trying++;
    if (socket_connect_trying < 5) {
        setTimeout(function () {
            check_socket();
        }, 1000);
    } else {
        socket.close();
    }
};

/**
 * Проверка состояния сокета и его восстановление
 */
function check_socket() {
    // Пересоздание сокета, если он закрыт и пользователь сопоставлен
    if ((!socket || socket.readyState == 3) && !not_matching_to_pbx_user) {
        createSocket();
    }
};

В данном примере:

  1. Реализуется WebSocket соединение с возможностью автоматического переподключения

  2. Применяется механизм аутентификации через API ключ

  3. Обрабатываются различные события, связанные с телефонией (звонки, рингование и т.д.)

  4. Происходит ограничение количества попыток переподключения (до 5 раз)

  5. Логируются основные события в консоль (в этом месте необходимо реализовать свою логику)

Ответ на crm_auth

После кадра crm_auth сервер отвечает с тем же action. Состав тела зависит от параметра mode:

  • mode = 1 (по умолчанию) — параметры для регистрации: pbx_user_protocol, login, ws_id; для WebRTC дополнительно password и wss;

  • mode = 2 — полное тело авторизации пользователя (как при обычном входе): token, user_id, domain_id, параметры роли и др.

Имена событий: WebSocket и HTTP

Одни и те же события по WebSocket и по HTTP (webhook) приходят с разными значениями action:

  • звонок: ringing / answer / hangup / held / active (WS) — против call_ringing / call_answer / call_hangup / call_held / call_active (HTTP);

  • регистрация абонента: reg_change (WS) — против user_change (HTTP);

  • состояние агента: agent_state_change (WS) — против domain_user_agent_agent_change (HTTP);

  • статус агента: agent_status_change (WS) — против domain_user_agent_status_change (HTTP).

Модуль WebSocket соединения

createSocket()

Создает WebSocket соединение с сервером.

Параметры: Нет

Возвращает: Объект WebSocket

Пример использования:

// Инициализация WebSocket соединения
setTimeout(createSocket, 500);

Особенности:

  • Автоматическая аутентификация

  • Повторное подключение при потере соединения

  • Обработка различных событий звонков

Константы:

  • HOST - адрес сервера

  • API_KEY - ключ API

  • CRM_USER_ID - идентификатор пользователя CRM

Основные методы

generateGUID()

Генерирует уникальный идентификатор (GUID).

Результат:

Случайный GUID

Тип результата:

string

Пример:

let guid = generateGUID();
// Пример результата: "f47ac10b-58cc-4372-a567-0e02b2c3d479"
reconnect_socket()

Обработчик переподключения WebSocket.

Особенности:

  • Количество попыток ограничено 5

  • Интервал между попытками 1 секунда

Обработка событий

Модуль поддерживает следующие события:

  • connect - первичное подключение

  • crm_auth - аутентификация в CRM

  • make_call - исходящий звонок

  • ringing - входящий звонок

  • answer - ответ на звонок

  • hangup - завершение звонка

Пример обработки события:

socket.onmessage = function (event) {
    var data = JSON.parse(event.data);
    switch (data.action) {
        case 'ringing':
            console.log('Входящий звонок', data.body);
            break;
    }
};

Конфигурация

Перед использованием необходимо установить:

  1. HOST - адрес сервера

  2. API_KEY - ключ доступа

  3. CRM_USER_ID - идентификатор пользователя

Пример настройки:

var HOST = 'example.websocket.com';
var API_KEY = 'your_secret_api_key';
var CRM_USER_ID = '12345';

Обработка ошибок

  • При 5 неудачных попытках соединение закрывается

  • Поддерживается автоматическое восстановление соединения

  • В случае несопоставления пользователя (код 407) подключение блокируется

Предупреждение

Убедитесь в корректности API ключа и идентификатора пользователя.