Как Vetmanager обрабатывает события Asterisk: настройка voip_json_config

Как Vetmanager обрабатывает события AMI и историю CDR, и почему конфигурацию нужно адаптировать под конкретную АТС

Что такое voip_json_config

voip_json_config — это конфигурация, которая объясняет Vetmanager, как интерпретировать события и данные конкретной АТС.

Vetmanager подключается к Asterisk Manager Interface (AMI) и получает поток технических событий, например:

  • создание телефонного канала;
  • поступление входящего звонка;
  • начало дозвона;
  • ответ сотрудника;
  • завершение звонка;
  • постановка звонка на удержание;
  • перевод звонка или прохождение через очередь.

Названия, последовательность и набор полей этих событий могут различаться в зависимости от:

  • версии Asterisk;
  • версии и конфигурации FreePBX;
  • использования PJSIP или chan_sip;
  • настроенных очередей и групп вызова;
  • dialplan;
  • маршрутизации входящих и исходящих звонков;
  • дополнительных модулей АТС.

Поэтому Vetmanager не привязан к одной жёсткой последовательности событий. Правила их обработки задаются в voip_json_config.

voip_json_config не настраивает SIP-транки, маршруты или пользователей АТС. Он описывает только преобразование событий и данных Asterisk во внутреннюю модель звонка Vetmanager.

Общая структура

Конфигурация может содержать два раздела:

{
  "AMI": {},
  "CDR": {}
}
  • AMI отвечает за события в реальном времени и всплывающие уведомления о звонках.
  • CDR отвечает за чтение истории звонков из базы Asterisk.

Для стандартного FreePBX раздел CDR часто работает без индивидуальной конфигурации. Чаще всего под конкретную АТС адаптируется раздел AMI.

Как Vetmanager обрабатывает звонок

В упрощённом виде жизненный цикл выглядит так:

Asterisk
   │
   │ AMI-события
   ▼
Правила voip_json_config
   │
   ├── новый звонок
   ├── ответ на звонок
   └── завершение звонка
   │
   ▼
Vetmanager
   ├── показывает уведомление
   ├── ищет клиента по номеру
   ├── определяет внутреннего абонента
   └── сохраняет итоговую историю звонка

Один реальный разговор может создать несколько каналов и десятки AMI-событий. Конфигурация должна отфильтровать технический шум, объединить нужные события в один звонок и определить его состояния.

Раздел AMI

Упрощённый пример:

{
  "AMI": {
    "callId": "floor({Uniqueid})",
    "allowEvents": [
      "Newchannel",
      "NewCallerid",
      "DialBegin",
      "DialEnd",
      "Hangup"
    ],
    "rules": {
      "incoming": [
        {
          "event": "NewCallerid",
          "state": "newCall",
          "next": [1],
          "condition": "length({CallerIDNum}) > 6",
          "variables": {
            "callerNo": "{CallerIDNum}",
            "receiver": "{Exten}",
            "realId": "{Uniqueid}",
            "TYPE": "INCOMING"
          }
        },
        {
          "event": "DialEnd",
          "state": "answerCall",
          "next": [2]
        },
        {
          "event": "Hangup",
          "state": "endCall",
          "next": "finish"
        }
      ]
    }
  }
}

Это только пример структуры. Окончательные события и условия определяются после получения фактического потока AMI от конкретной АТС.

callId

Пример:

"callId": "floor({Uniqueid})"

callId определяет идентификатор, по которому события объединяются в один звонок.

Один звонок может создать несколько каналов с разными Uniqueid. В зависимости от конфигурации АТС может потребоваться использовать:

  • Uniqueid;
  • Linkedid;
  • первое доступное значение из нескольких полей;
  • дополнительное преобразование идентификатора.

Неправильно выбранный callId может привести к следующим симптомам:

  • одно уведомление создаётся несколько раз;
  • событие ответа не находит начатый звонок;
  • уведомление не закрывается после завершения;
  • события двух каналов ошибочно объединяются.

allowEvents

Пример:

"allowEvents": [
  "Newchannel",
  "DialBegin",
  "DialEnd",
  "Hangup"
]

Это список событий, которые Vetmanager должен обрабатывать. Asterisk отправляет большое количество технических событий, большинство из которых для интеграции не требуется.

Все события, используемые в rules, должны также присутствовать в allowEvents. Если событие есть в правиле, но отсутствует в allowEvents, оно не будет обработано.

rules

Правила обычно разделяются на два направления:

"rules": {
  "incoming": [],
  "outgoing": []
}
  • incoming — правила входящих звонков;
  • outgoing — правила исходящих звонков.

Каждый массив описывает ожидаемую последовательность событий. Порядок правил важен: очередное событие должно соответствовать одному из допустимых следующих шагов.

event

Пример:

"event": "NewCallerid"

Это название AMI-события, которое должно быть обработано на данном этапе.

В разных конфигурациях одну и ту же стадию звонка могут обозначать разные события. Например, ответ сотрудника может определяться через:

  • DialEnd;
  • BridgeEnter;
  • AgentConnect;
  • Newstate;
  • другое событие, создаваемое dialplan или очередью.

Поэтому одной информации о версии FreePBX или Asterisk недостаточно для гарантированного выбора событий.

state

Пример:

"state": "newCall"

state определяет действие внутри Vetmanager. Основные состояния:

  • startCall — начать обработку звонка;
  • newCall — зарегистрировать новый звонок и показать уведомление;
  • answerCall — отметить, что на звонок ответили;
  • endCall — завершить звонок и закрыть уведомление.

В зависимости от сценария могут использоваться дополнительные промежуточные состояния, например для удержания.

condition

Пример:

"condition": "length({CallerIDNum}) > 6 & {ChannelState} = 4"

condition фильтрует события. Это помогает отличить:

  • внешний номер от внутреннего;
  • входящий звонок от исходящего;
  • нужный канал от служебного;
  • фактический ответ от промежуточного события;
  • событие очереди от события отдельного абонента;
  • звонок клиента от внутреннего звонка между сотрудниками.

Можно использовать сравнения и логические операции:

  • = — равно;
  • != — не равно;
  • > и < — сравнение;
  • & — логическое «И»;
  • | — логическое «ИЛИ».

Также доступны функции преобразования значений:

  • length() — длина строки;
  • floor() — округление числового идентификатора;
  • instr() — проверка вхождения подстроки;
  • substr() — получение части строки;
  • firstexists() — выбор первого непустого поля.

variables

Пример:

"variables": {
  "callerNo": "{CallerIDNum}",
  "receiver": "{Exten}",
  "realId": "{Uniqueid}",
  "TYPE": "INCOMING"
}

Здесь поля AMI преобразуются во внутренние поля звонка Vetmanager:

  • callerNo — внешний телефонный номер;
  • receiver — внутренний номер сотрудника;
  • realId — идентификатор звонка;
  • TYPE — направление звонка.

Поле receiver особенно важно, если в Vetmanager включена привязка внутренних номеров к пользователям. По нему система определяет, какому сотруднику показать уведомление.

next

Пример перехода к следующим правилам:

"next": [1, 2]

Пример завершения обработки:

"next": "finish"

Таким образом, правила образуют конечный автомат:

новый звонок → ответ → завершение

Ветвление позволяет учитывать пропущенный звонок, ответ другого сотрудника, очередь или разные варианты завершения.

Раздел CDR

Раздел CDR описывает чтение истории звонков из базы Asterisk.

Упрощённый пример:

{
  "CDR": {
    "callId": "floor({uniqueid})",
    "tableName": "cdr",
    "timestampField": "{calldate}",
    "map": {
      "uniqueid": "{uniqueid}",
      "start_datetime": "{calldate}",
      "start_timestamp": "{datetime_timestamp}",
      "destination": "{dst}",
      "source": "{src}",
      "length": "{billsec}",
      "disposition": "{disposition}",
      "filepath": "{recordingfile}",
      "line_number": "{did}"
    }
  }
}

Индивидуальная настройка CDR нужна, если:

  • используется нестандартное имя таблицы;
  • таблицы разделены по месяцам;
  • поля имеют другие названия;
  • один звонок записывается несколькими строками;
  • требуется дополнительная фильтрация;
  • путь к записи хранится нестандартно;
  • направление звонка нельзя определить стандартным способом.

Основные поля, которые Vetmanager должен получить:

  • uniqueid — идентификатор звонка;
  • start_datetime — дата и время начала;
  • start_timestamp — время начала в числовом формате;
  • source — номер, с которого звонили;
  • destination — номер назначения;
  • length — продолжительность разговора;
  • disposition — результат звонка;
  • filepath — путь к записи разговора;
  • direction — входящий или исходящий звонок;
  • line_number — внешний номер линии.

Для стандартного FreePBX обычно используется таблица cdr и поля calldate, src, dst, billsec, disposition, recordingfile, did и uniqueid.

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

Использование PJSIP допустимо и само по себе не мешает интеграции. Vetmanager не регистрируется как SIP-абонент и не подключается к транкам.

При этом PJSIP может влиять на:

  • значение Channel и DestChannel;
  • определение внутреннего номера;
  • значения Exten, CallerIDNum и ConnectedLineNum;
  • количество каналов одного звонка;
  • последовательность AMI-событий;
  • поведение очередей и переводов.

Например, имя канала может начинаться с PJSIP/, тогда как в старой конфигурации оно начиналось с SIP/. Если условия используют поле канала, их необходимо адаптировать.

Как выполняется первоначальная настройка

1. Открывается доступ к AMI

АТС должна разрешать TCP-подключение с диапазона Vetmanager:

84.38.177.144/28

Обычно AMI работает на TCP-порту 5038, но может использоваться другой внешний порт.

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

Проверяются:

  • доступность хоста и порта;
  • авторизация AMI-пользователя;
  • получение событий;
  • отсутствие блокировки со стороны firewall.

3. Устанавливается исходная конфигурация

Сначала можно использовать стандартный вариант для FreePBX. Он служит отправной точкой, а не гарантированно готовой конфигурацией для любой установки.

4. Выполняются тестовые звонки

Рекомендуемые сценарии:

  1. Входящий звонок с ответом.
  2. Входящий звонок без ответа.
  3. Исходящий звонок с ответом.
  4. Исходящий звонок без ответа.
  5. Звонок через очередь, если используются очереди.
  6. Перевод звонка, если он используется в работе.

5. Анализируются AMI-события

Для каждого сценария определяются:

  • первое стабильное событие нового звонка;
  • внешний номер клиента;
  • внутренний номер сотрудника;
  • общий идентификатор каналов звонка;
  • событие ответа;
  • событие завершения;
  • события пропущенного звонка;
  • лишние технические каналы, которые нужно отфильтровать.

6. Корректируется voip_json_config

Разработчик изменяет:

  • allowEvents;
  • последовательность rules;
  • условия condition;
  • соответствие полей в variables;
  • способ вычисления callId;
  • правила завершения звонка.

7. Проверяется история CDR

Отдельно проверяются:

  • появление звонка в таблице CDR;
  • корректность внешнего и внутреннего номеров;
  • длительность;
  • результат звонка;
  • направление;
  • имя файла записи.

8. Проверяется получение записи

Если требуется прослушивание, Vetmanager подключается к FTP/FTPS-серверу, получает файл записи и сохраняет его в своё файловое хранилище.

Путь к записи должен соответствовать значению recordingfile из CDR и структуре каталогов на сервере.

Почему нельзя подготовить конфигурацию только по версии

Версии FreePBX и Asterisk помогают выбрать исходный шаблон, но не определяют окончательное поведение.

На одинаковых версиях события могут различаться из-за:

  • индивидуального dialplan;
  • настроек очередей;
  • маршрутов входящих вызовов;
  • групп вызова;
  • правил переадресации;
  • дополнительных модулей;
  • настроек PJSIP endpoint;
  • схемы подключения оператора.

Поэтому используется следующий подход:

стандартный шаблон FreePBX
        ↓
фактические AMI-события тестовых звонков
        ↓
индивидуальная корректировка voip_json_config
        ↓
повторная проверка всех сценариев

Типовые симптомы неправильной конфигурации

Уведомление не появляется

Возможные причины:

  • начальное событие отсутствует в allowEvents;
  • не выполняется condition;
  • внешний номер берётся не из того поля;
  • событие не соответствует первому правилу incoming или outgoing;
  • неправильно определяется направление звонка.

Уведомление появляется несколько раз

Возможные причины:

  • разные каналы одного звонка получают разные callId;
  • не отфильтрованы Local- или служебные каналы;
  • несколько событий ошибочно обозначены как newCall.

Уведомление не закрывается

Возможные причины:

  • фактическое событие завершения отличается от указанного;
  • Hangup относится к другому каналу;
  • событие завершения не находит звонок из-за несовпадающего callId;
  • правило завершения недоступно через next.

Неправильно определяется сотрудник

Возможные причины:

  • внутренний номер находится не в Exten;
  • для очереди требуется ConnectedLineNum, DestCallerIDNum или другое поле;
  • в receiver сохраняется публичный номер линии;
  • внутренний номер не привязан к пользователю Vetmanager.

История есть, но уведомлений нет

CDR и AMI — независимые части интеграции. История может успешно загружаться из базы, даже если правила AMI ещё не настроены.

Уведомления есть, но история не загружается

AMI может работать при неправильном доступе к базе CDR или несовместимой структуре таблицы. В этом случае отдельно проверяются подключение к базе и раздел CDR.

Требования безопасности

Для подключения рекомендуется:

  • разрешить AMI только с диапазона Vetmanager;
  • создать отдельного AMI-пользователя;
  • предоставить только необходимые права;
  • не открывать AMI для всего интернета;
  • для CDR создать отдельного пользователя базы с правами только на чтение;
  • ограничить доступ к базе диапазоном Vetmanager;
  • использовать отдельного пользователя FTP/FTPS с доступом только к каталогу записей;
  • не отправлять логины, пароли и полные AMI payload в открытые чаты;
  • после диагностики удалить временные файлы с полными событиями, если они содержат номера телефонов.

Что необходимо предоставить для настройки

Для первоначального подключения потребуются:

  • публичный IP или DNS АТС;
  • внешний порт AMI;
  • логин и пароль отдельного AMI-пользователя;
  • внешний порт базы CDR;
  • имя базы CDR;
  • логин и пароль read-only пользователя базы;
  • имя таблицы CDR, если используется не cdr;
  • параметры FTP/FTPS, если нужны записи;
  • путь к каталогу записей;
  • информация об использовании очередей, групп вызова и переводов;
  • возможность выполнить серию тестовых звонков совместно с разработчиком.

Итог

voip_json_config позволяет подключать разные конфигурации Asterisk/FreePBX без жёсткой привязки Vetmanager к одной версии или одному набору событий.

Основной принцип работы:

  1. Vetmanager подключается к AMI.
  2. Asterisk отправляет события звонка.
  3. voip_json_config фильтрует и связывает события.
  4. События преобразуются в состояния Vetmanager.
  5. CDR используется для итоговой истории и записей.

Стандартный шаблон FreePBX является отправной точкой. Окончательная конфигурация проверяется и при необходимости корректируется разработчиком по фактическим событиям входящих и исходящих тестовых звонков.

Powered by