Использование GotoIf и ExecIf для сложных сценариев
Мы уже освоили работу с переменными, которые позволяют хранить и передавать данные внутри системы. Однако линейный диалплан, где команды выполняются строго по порядку, не подходит для серьезных задач. Чтобы Asterisk принимал решения на основе времени, номера звонящего или статуса сотрудника, нам нужна логика в диалплане.
Как Asterisk понимает условия
Основа логики — условный переход. Asterisk вычисляет выражения внутри конструкции $[ ... ]. Если результат не равен нулю и не является пустой строкой, условие считается истинным (True).
Для сравнения используйте стандартные операторы: == (равно), != (не равно), > (больше), < (меньше).
⚠️ Синтаксис — это всё. Вокруг операторов сравнения обязательно ставьте пробелы. Без них Asterisk склеит выражение в одну строку, и логика сломается. Правильно:
$["${EXTEN}" == "100"]Ошибка:$["${EXTEN}"=="100"]
Схема 1 демонстрирует, как поток вызова разделяется на ветви в зависимости от результата проверки.
Приложение GotoIf: развилка
GotoIf — это классический «прыжок» по условию. Синтаксис работает как тернарный оператор:
GotoIf($[условие]?метка_если_истина:метка_если_ложь)
Если условие верно, Asterisk переходит к первой метке. Если ложно — ко второй. Если оставить одну из частей пустой, система просто перейдет к следующей строке диалплана.
Кейс: VIP-звонок
Направим звонок директора сразу на личного ассистента.
[from-internal-custom]
exten => 100,1,NoOp(Проверка входящего номера)
; Если номер совпадает, идем на метку vip, иначе — дальше по списку
exten => 100,n,GotoIf($["${CALLERID(num)}" = "79991234567"]?vip-manager:normal-flow)
exten => 100,n(vip-manager),Dial(PJSIP/201,20)
exten => 100,n,Hangup()
exten => 100,n(normal-flow),Dial(PJSIP/200,20)
exten => 100,n,Hangup()
Совет профи: Всегда берите переменные в кавычки:
"${CALLERID(num)}". Если номер окажется пустым (скрытым), кавычки спасут диалплан от синтаксической ошибки.
Приложение ExecIf: точечное действие
В отличие от переходов, ExecIf не меняет маршрут вызова, а выполняет конкретную команду «на месте», если условие истинно. Это лаконичный способ сделать разовое действие.
Синтаксис: ExecIf($[условие]?Приложение(аргументы))
Кейс: Черный список
Мгновенно сбрасываем вызов от нежелательного номера:
[incoming-filter]
exten => s,1,NoOp(Фильтрация)
; Если номер в черном списке, кладем трубку
exten => s,n,ExecIf($["${CALLERID(num)}" = "74950000000"]?Hangup())
exten => s,n,Dial(PJSIP/101)
Три ловушки для новичка
- Отсутствие пробелов:
$["${VAR}"=="1"]— гарантированный провал. - Эффект «проваливания» (fall-through): Если в
GotoIfуказана только истинная метка?label, а условие не сработало, Asterisk выполнит следующую строку. Убедитесь, что эта строка описывает логику для «лжи». - Устаревшие Macro: Забудьте про макросы. В современной разработке используем только
GoSubи прямые переходы.
Диагностика через CLI
Если логика ведет себя странно, идите в консоль Asterisk. Команда dialplan set debug on покажет пошаговое вычисление каждого выражения.
В логах ищите строку:
-- Executing [100@from-internal:2] GotoIf("PJSIP/101-0000001", "1?vip-manager:normal-flow")
Цифра 1 перед вопросом означает, что условие выполнено (True).
Мы научились создавать простые развилки. Но в реальных АТС условия часто бывают комплексными: нужно учитывать время, статус оператора и приоритет одновременно.
В следующей теме мы объединим эти инструменты, чтобы строить сложные логические цепочки для профессиональных IVR-систем.
Понравился урок?
Сохраните прогресс и получите персональный курс по любой теме — без форм и паролей
Продолжить в Telegram