Приложения для обработки вызовов: Dial, Answer, Hangup
Мы уже разобрались, как FreePBX генерирует конфигурации Asterisk и как устроен диалплан. Теперь пора познакомиться с базовыми приложениями, которые позволяют Asterisk управлять звонками. Эти приложения — фундамент, из которого собираются даже самые сложные сценарии.
Приложение Dial: соединяем абонентов
Dial (от англ. "набрать") — самое используемое приложение в Asterisk. Его задача — попытаться соединить текущий канал с одним или несколькими пунктами назначения. Это может быть внутренний абонент, внешний номер через транк или группа абонентов.
Синтаксис и параметры
Базовый синтаксис Dial выглядит так:
Dial(Технология/Ресурс[&Технология2/Ресурс2][,...][,Таймаут][,Опции][,URL])
Разберём основные части:
Технология/Ресурс: Куда звонить.Технология: Тип канала. Например,SIP,PJSIP,DAHDI,Local.Ресурс: Адрес или идентификатор в рамках технологии. Например,SIP/201(внутренний SIP-абонент 201),PJSIP/trunk_provider_name/123456789(внешний номер через PJSIP-транк),DAHDI/g1/123(номер 123 через группу DAHDI-каналов g1).
Таймаут: Максимальное время ожидания ответа в секундах. Если абонент не ответит,Dialзавершится. По умолчанию — бесконечно.Опции: Однобуквенные флаги, меняющие поведениеDial. Некоторые из них:t: Разрешить вызываемому абоненту переводить вызов.T: Разрешить вызывающему абоненту переводить вызов.r: Генерировать гудки (ringback tone) вызывающему, пока вызываемый не ответит.L(x[:y][:z]): Установить максимальную длительность вызоваxсекунд. Опционально можно задатьy(время предупреждения) иz(время повторного предупреждения).g: Продолжить выполнение диалплана в текущем контексте для вызывающего, даже если вызываемый повесил трубку. Полезно для голосовой почты или других сценариев после завершения звонка.h: Разрешить вызывающему повесить трубку, нажав#.C: Скрыть CallerID вызывающего от вызываемого.
Примеры использования Dial
-
Звонок на внутренний SIP-телефон:
exten => 101,1,Dial(PJSIP/101,20,tr)- Звоним на PJSIP-экстеншен 101.
- Ждём 20 секунд.
t: Разрешаем 101 переводить вызов.r: Отправляем вызывающему гудки.
-
Звонок на несколько абонентов одновременно (ringall):
exten => 200,1,Dial(PJSIP/201&PJSIP/202&PJSIP/203,30,tr)- Звоним одновременно на 201, 202 и 203. Кто первый ответит, с тем и соединим.
- Ждём 30 секунд.
-
Звонок через внешний транк:
exten => _9XXXXXXXXXX,1,Dial(PJSIP/MyProvider/${EXTEN:1},60,T)- Если набран номер, начинающийся с 9 и далее 10 цифр (например, 98001234567).
- Звоним через PJSIP-транк
MyProvider. ${EXTEN:1}: Передаём номер без первой цифры "9".- Ждём 60 секунд.
T: Разрешаем вызывающему переводить вызов.
Важно: После завершения
Dial(успешного соединения, таймаута, занятости и т.д.) Asterisk устанавливает переменнуюDIALSTATUS. Она содержит результат попытки вызова (например,ANSWER,NOANSWER,BUSY,CHANUNAVAIL). Это очень полезно для построения сложной логики диалплана.
Приложение Answer: отвечаем на звонок
Answer (от англ. "ответить") — простое, но важное приложение, которое отвечает на входящий вызов. До его выполнения канал находится в состоянии "звонит" (ringing). После Answer канал переходит в состояние "отвечен" (answered), и Asterisk начинает обрабатывать медиа-трафик.
Синтаксис
Answer()
Answer не принимает никаких параметров.
Примеры использования Answer
-
Простой ответ и воспроизведение приветствия:
exten => s,1,Answer() exten => s,2,Playback(welcome) ; Воспроизвести файл welcome.gsm- Сначала отвечаем на вызов.
- Затем проигрываем приветствие.
-
Входящий вызов на IVR:
exten => _X.,1,Answer() exten => _X.,2,Wait(1) ; Небольшая пауза для стабилизации канала exten => _X.,3,AGI(agi-bin/ivr_script.agi)- Отвечаем на входящий вызов.
- Делаем небольшую паузу.
- Передаём управление AGI-скрипту для обработки IVR.
Совет: Всегда используйте
Answer()перед воспроизведением голосовых сообщений или использованием приложений, которые требуют активного соединения. Если вызов не будет отвечен, абонент не услышит ничего, кроме гудков (если они генерируются).
Приложение Hangup: завершаем вызов
Hangup (от англ. "повесить трубку") — используется для завершения текущего вызова. Оно закрывает канал и освобождает ресурсы.
Синтаксис и параметры
Hangup([КодОтбоя])
КодОтбоя: Необязательный параметр, указывающий причину завершения вызова в виде SIP-кода отбоя (например, 16 для "Normal Call Clearing", 17 для "User Busy"). Это полезно для отладки и анализа CDR (Call Detail Records).
Примеры использования Hangup
-
Простое завершение вызова:
exten => h,1,Hangup()- Это стандартный экстеншен
h, который вызывается при отбое любого из участников вызова.
- Это стандартный экстеншен
-
Завершение вызова после ошибки:
exten => 123,1,NoOp(Попытка звонка на несуществующий номер) exten => 123,2,Playback(vm-nobodyavail) ; "Абонент недоступен" exten => 123,3,Hangup(17) ; Завершить с кодом "User Busy"- После сообщения об ошибке завершаем вызов с указанием причины.
Практическое задание: строим свой сценарий звонка 🚀
Давайте закрепим полученные знания.
Задача: Создайте в файле /etc/asterisk/extensions_custom.conf (или в другом, если вы используете свой контекст) следующий сценарий:
- Создайте контекст
[custom-internal-calls]. - В этом контексте:
- При наборе номера
800Asterisk должен ответить на вызов. - Затем воспроизвести голосовое сообщение "Добро пожаловать в наш учебный центр!" (используйте
Playback(welcome)или любой другой доступный файл, например,demo-welcome)). - После этого вызов должен быть перенаправлен на внутренний номер
101(предположим, что у вас есть PJSIP-экстеншен 101). - Если абонент 101 не ответит в течение 15 секунд, вызов должен быть завершен с кодом отбоя 17 (User Busy).
- Если абонент 101 ответит, вызов должен быть разрешен для перевода (для обоих участников).
- При наборе номера
Подсказка: Используйте переменную DIALSTATUS для проверки результата Dial.
После сохранения изменений не забудьте применить их в Asterisk CLI:
asterisk -rx "dialplan reload"
Попробуйте позвонить на номер 800 с любого внутреннего телефона и проверьте, как работает ваш сценарий.
Теперь, когда мы освоили базовые приложения для обработки вызовов, мы готовы перейти к приложениям, которые позволяют взаимодействовать с пользователем и управлять звуком. Это откроет нам путь к созданию более интерактивных и функциональных голосовых меню и систем.