Приложения для обработки вызовов: Dial, Answer, Hangup - Asterisk и FreePBX: От GUI к Глубокому Администрированию и Оптимизации - Qpel.AI

Приложения для обработки вызовов: 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

  1. Звонок на внутренний SIP-телефон:

    exten => 101,1,Dial(PJSIP/101,20,tr)
    
    • Звоним на PJSIP-экстеншен 101.
    • Ждём 20 секунд.
    • t: Разрешаем 101 переводить вызов.
    • r: Отправляем вызывающему гудки.
  2. Звонок на несколько абонентов одновременно (ringall):

    exten => 200,1,Dial(PJSIP/201&PJSIP/202&PJSIP/203,30,tr)
    
    • Звоним одновременно на 201, 202 и 203. Кто первый ответит, с тем и соединим.
    • Ждём 30 секунд.
  3. Звонок через внешний транк:

    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

  1. Простой ответ и воспроизведение приветствия:

    exten => s,1,Answer()
    exten => s,2,Playback(welcome) ; Воспроизвести файл welcome.gsm
    
    • Сначала отвечаем на вызов.
    • Затем проигрываем приветствие.
  2. Входящий вызов на 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

  1. Простое завершение вызова:

    exten => h,1,Hangup()
    
    • Это стандартный экстеншен h, который вызывается при отбое любого из участников вызова.
  2. Завершение вызова после ошибки:

    exten => 123,1,NoOp(Попытка звонка на несуществующий номер)
    exten => 123,2,Playback(vm-nobodyavail) ; "Абонент недоступен"
    exten => 123,3,Hangup(17) ; Завершить с кодом "User Busy"
    
    • После сообщения об ошибке завершаем вызов с указанием причины.

Практическое задание: строим свой сценарий звонка 🚀

Давайте закрепим полученные знания.

Задача: Создайте в файле /etc/asterisk/extensions_custom.conf (или в другом, если вы используете свой контекст) следующий сценарий:

  1. Создайте контекст [custom-internal-calls].
  2. В этом контексте:
    • При наборе номера 800 Asterisk должен ответить на вызов.
    • Затем воспроизвести голосовое сообщение "Добро пожаловать в наш учебный центр!" (используйте Playback(welcome) или любой другой доступный файл, например, demo-welcome)).
    • После этого вызов должен быть перенаправлен на внутренний номер 101 (предположим, что у вас есть PJSIP-экстеншен 101).
    • Если абонент 101 не ответит в течение 15 секунд, вызов должен быть завершен с кодом отбоя 17 (User Busy).
    • Если абонент 101 ответит, вызов должен быть разрешен для перевода (для обоих участников).

Подсказка: Используйте переменную DIALSTATUS для проверки результата Dial.

После сохранения изменений не забудьте применить их в Asterisk CLI: asterisk -rx "dialplan reload"

Попробуйте позвонить на номер 800 с любого внутреннего телефона и проверьте, как работает ваш сценарий.


Теперь, когда мы освоили базовые приложения для обработки вызовов, мы готовы перейти к приложениям, которые позволяют взаимодействовать с пользователем и управлять звуком. Это откроет нам путь к созданию более интерактивных и функциональных голосовых меню и систем.