Создание логических цепочек в диалплане

Мы освоили синтаксис одиночных проверок GotoIf, но в корпоративных АТС логика редко бывает линейной. Чтобы звонок дошел до нужного оператора, нам предстоит строить логические цепочки — последовательности фильтров, учитывающие время, статус клиента и состояние системы.

Проектирование диалплана — это не просто написание строк кода в extensions_custom.conf, а создание алгоритма. Прежде чем кодить, нарисуйте дерево решений: где вход, какие условия проверяем и куда уходит вызов при ошибке.

От «спагетти» к модулям

Когда условий больше двух, легко запутаться в переходах Goto. Чтобы диалплан оставался читаемым, используйте модульный подход.

Логические цепочки работают как сито: если условие «А» верно, идем к проверке «Б», если нет — отправляем вызов на ветку исключений. Для визуализации таких процессов идеально подходят блок-схемы. Как показано на Схеме 1, профессиональный диалплан всегда имеет точку входа, этапы валидации и безопасный выход.

Вложенные условия без хаоса

В Asterisk нет привычных if-else с фигурными скобками. Вложенные условия создаются с помощью меток (labels) и переходов.

Задача: «Если звонит VIP, соединяем с менеджером даже ночью. Остальных в нерабочее время — на автоответчик».

Плохой пример (трудно читать и расширять):

exten => s,1,GotoIf($["${IS_VIP}"="1"]?vip_path:check_time)
exten => s,n(check_time),GotoIfTime(9:00-18:00,mon-fri,*,*?work_hours:closed)

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

[incoming-logic-custom]
exten => s,1,NoOp(--- Обработка входящего ---)
    ; 1. Валидация: проверяем, не пуста ли переменная
    same => n,GotoIf($[${ISNULL(${VIP_STATUS})}]?check_time)
    
    ; 2. Проверка VIP-статуса
    same => n,GotoIf($["${VIP_STATUS}"="1"]?vip_route)

    ; 3. Проверка времени для обычных звонков
    same => n(check_time),GotoIfTime(9:00-18:00,mon-fri,*,*?open:closed)

    ; Ветки маршрутизации
    same => n(vip_route),NoOp(Маршрут для VIP)
    same => n,Dial(PJSIP/101,30)
    same => n,Hangup()

    same => n(open),Dial(PJSIP/200,30)
    same => n,Hangup()

    same => n(closed),Playback(vm-goodbye)
    same => n,Hangup()

Обработка ошибок: страховка для вызова

Глубокое администрирование — это умение предугадать сбой. Обработка ошибок гарантирует, что вызов не «зависнет» в пустоте.

Проверяйте три сценария:

  1. Пустые значения: переменная не пришла из базы или скрипта.
  2. Мусор в данных: ожидали ID из цифр, получили буквы.
  3. Таймауты: внешняя система (например, CRM) не ответила вовремя.

Золотое правило

Всегда используйте функции ISNULL() или EXISTS() перед сравнением. Если сравнить пустую строку с числом, Asterisk выдаст ошибку и оборвет звонок 🧱

Связка с FreePBX

Чтобы внедрить свой код из extensions_custom.conf в логику FreePBX, используйте Custom Destinations:

  1. Опишите контекст в файле.
  2. Зарегистрируйте его в GUI FreePBX как «Custom Destination».
  3. Направьте входящий маршрут (Inbound Route) на эту точку.

Так вы сохраняете мощь «чистого» Asterisk и удобство управления через веб-интерфейс.

Практика

Добавьте в ваш диалплан «предохранитель»: проверку флага MAINTENANCE. Если он равен 1, система должна сразу проиграть сообщение о техработах и положить трубку, игнорируя остальные логические цепочки.

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

В следующем уроке разберем, как подключить Asterisk к базе данных через ODBC, чтобы система принимала решения на основе информации из вашей CRM или ERP 🛰

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

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

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