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

Для этих целей в Asterisk существуют переменные диалплана. Это именованные контейнеры для хранения и извлечения информации. Без них невозможно представить современную АТС, где каждый звонок передает метаданные в CRM или системы аналитики.

Синтаксис и базовые принципы

Работа с переменными строится на двух операциях:

  1. Запись: используем приложение Set().
  2. Чтение: заключаем имя переменной в конструкцию ${}.

Важно различать имя переменной и её содержимое. Если написать MYVAR, Asterisk воспримет это как обычную строку. Если ${MYVAR} — система подставит значение, которое хранится внутри.

; Плохо: жесткая привязка данных
exten => 100,1,Playback(welcome-manager-ivan)

; Профессионально: использование переменной
exten => 100,1,Set(MANAGER_NAME=ivan)
same => n,Playback(welcome-manager-${MANAGER_NAME})

Иерархия и типы переменных

В Asterisk существует строгая иерархия видимости. Понимание того, где «живет» и когда «умирает» переменная, критично для стабильной работы логики. Как показано на Схеме 1, переменные делятся на три уровня.

1. Глобальные переменные

Глобальные переменные доступны для всех каналов и вызовов. В них хранят статические настройки: префиксы выхода в город или IP-адреса шлюзов.

Их объявляют в секции [globals] файла extensions.conf или через CLI:

[globals]
OFFICE_PREFIX=9

2. Канально-зависимые переменные

Система создает их автоматически в момент звонка. Канально-зависимые переменные содержат данные о текущем соединении:

  • ${EXTEN} — номер, на который пришел вызов.
  • ${CONTEXT} — текущий контекст.
  • ${CALLERID(num)} — номер звонящего.

3. Пользовательские переменные

Это переменные, которые вы создаете сами для решения бизнес-задач. Мы называем их пользовательские переменные. Например: Set(IS_VIP=1) или Set(TICKET_ID=5543).

Наследование: магия подчеркиваний

По умолчанию пользовательская переменная принадлежит только тому каналу, в котором она создана. Если вы используете Dial(), в «дочернем» канале (у вызываемого абонента) эти переменные будут пустыми.

Чтобы передать данные дальше, используйте префиксы:

  • _VAR — наследуется один раз (в один дочерний канал).
  • __VAR — наследуется бесконечно во все последующие каналы.

💡 Важно: При чтении переменной подчеркивания указывать не нужно. Пишем Set(__MYID=123), но читаем как ${MYID}.

Практикум: передача данных между контекстами

Задача: пометить звонок с рекламного номера, чтобы оператор видел источник трафика.

[from-pstn-custom]
; Помечаем звонок как рекламный для всех переходов
exten => _X.,1,Set(__SOURCE=YANDEX_ADS)
same => n,Goto(internal-logic,s,1)

[internal-logic]
exten => s,1,NoOp(Источник звонка: ${SOURCE})
same => n,Dial(PJSIP/101)

Для отладки используйте приложение DumpChan(). Оно выводит в консоль (CLI) список всех переменных канала. Это лучший способ понять, что происходит внутри «черного ящика» диалплана 🛰️

same => n,DumpChan() ; Выведет все переменные в CLI

Теперь ваша АТС умеет запоминать данные. В следующей теме мы научим Asterisk принимать самостоятельные решения и менять маршрут звонка с помощью GotoIf и ExecIf.

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

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

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