Динамическое управление диалпланом

Мы уже освоили интеграцию Asterisk с CRM и автоматизацию рутинных задач. Однако в крупных АТС часто нужно менять логику обработки звонков мгновенно, не дожидаясь перезагрузки конфигурации.

Динамическое управление — это подход, при котором диалплан перестает быть статичным набором инструкций в файлах .conf. Маршрут вызова определяется в реальном времени на основе данных из внешних источников: баз данных, кэш-хранилищ или команд от сторонних приложений.

Почему dialplan reload — это риск

В высоконагруженных системах команда dialplan reload может быть опасной. При большом количестве контекстов и активных вызовов она создает резкую нагрузку на процессор, что иногда приводит к задержкам в обработке медиа-трафика или непредсказуемому поведению системы.

Изменение диалплана в реальном времени позволяет:

  1. Переключать режимы «День/Ночь» или «Авария» одной кнопкой в интерфейсе.
  2. Управлять черными списками без правки конфигов.
  3. Реализовать умную маршрутизацию: например, направлять VIP-клиента на персонального менеджера, даже если тот сменил внутренний номер минуту назад.

Метод 1: Переменные и ASTDB

Самый простой способ добавить динамики — использовать внутреннюю базу данных Asterisk (ASTDB) или внешнюю БД через func_odbc. Диалплан остается неизменным, но его логика зависит от значений переменных.

Схема 1. Логика принятия решения на основе динамических данных

Пример переключателя режима работы офиса в extensions_custom.conf:

[from-internal-custom]
exten => *99,1,NoOp(Switch Office Mode)
 same => n,Set(CURRENT_STATUS=${DB(OFFICE/MODE)})
 same => n,GotoIf($["${CURRENT_STATUS}" = "night"]?set_day:set_night)
 same => n(set_day),Set(DB(OFFICE/MODE)=day)
 same => n,Playback(activated&day-mode)
 same => n,Hangup()
 same => n(set_night),Set(DB(OFFICE/MODE)=night)
 same => n,Playback(activated&night-mode)
 same => n,Hangup()

[from-pstn-custom]
exten => s,1,NoOp(Incoming Call)
 same => n,GotoIf($["${DB(OFFICE/MODE)}" = "night"]?night_route:day_route)
 same => n(day_route),Dial(PJSIP/100,30)
 same => n(night_route),Voicemail(100@default,u)

Метод 2: Управление через AMI (Action: Setvar и Redirect)

Чтобы вмешаться в активный вызов, используйте AMI (Asterisk Manager Interface). Это позволяет внешнему скрипту (Python, Node.js) перехватить управление каналом.

  1. Action: Setvar — меняет переменную в активном канале. Если диалплан дальше проверяет эту переменную через GotoIf, вызов сменит направление.
  2. Action: Redirect — мгновенно перебрасывает канал в другой контекст или на другой приоритет.

Метод 3: ARI и приложение Stasis

Для сложных задач, где логика полностью диктуется внешним кодом, используют ARI (Asterisk REST Interface). Вы направляете вызов в приложение Stasis(), после чего Asterisk «замораживает» выполнение диалплана и ждет команд по HTTP.

Это дает полный контроль: вы можете проигрывать звуки, собирать DTMF и динамически соединять каналы в мосты (Bridges), не описывая это в extensions.conf.

Задание: Создание динамического черного списка

  1. В extensions_custom.conf создайте проверку номера в ASTDB перед соединением: same => n,GotoIf($[${DB_EXISTS(blacklist/${CALLERID(num)})}]?blocked).
  2. Добавьте номер в базу через CLI: asterisk -rx "database put blacklist 79991234567 1".
  3. Совершите вызов и убедитесь, что диалплан отработал блокировку мгновенно без команды reload.

Безопасность и производительность

  • Валидация: Если вы получаете данные для редиректа из CRM, проверяйте их. Ошибка в логике может позволить злоумышленникам совершить платный вызов через вашу систему. 🛡️
  • Отказоустойчивость: Если диалплан зависит от внешнего микросервиса (ARI), всегда делайте «запасной выход» (fallback) в обычном диалплане на случай недоступности сервиса.

Мы научились делать систему гибкой. Теперь важно понять, как эти изменения влияют на нагрузку и стабильность. В следующем уроке мы разберем профессиональный мониторинг и визуализацию состояния Asterisk с помощью Prometheus и Grafana.

Понравился урок?

Сохраните прогресс и получите персональный курс по любой теме — без форм и паролей

Продолжить в Telegram