Freeswitch: mod_dptools: IVR menu

Модуль IVR позволяет легко создавать интерактивные голосовые меню.

Параметры меню

  • name: Название меню.
    • greet_long: Стартовое сообщение, воспроизводится при входе в меню.,
    • greet_short: Короткая версия приветствия, которая будет воспроизведена, если меню зациклено.
    • invalid_sound: Проигрывается, когда набрана не назначенная в вводе цифра или не набрано ничего.
    • exit_sound: Воспрозводится при выходе из меню.
      • Любое приветствие может быть относительным или абсолютным путем к файлу (wav,mp3,ogg,flac), командой 'say:Мой Текст' для Text-To-Speech или фразой 'phrase:phrase_macro_name' для воспроизведения макроса фразы. Если используется 'phrase:my_phrase' вы можете передать шаблоны совпадения назначеные макросу, опционально: 'phrase:my_phrase:options|option2'. mod_phrase
      • Также, приветствие может быть стримом, вызваным при помощи модулей: mod_shout, или mod_http_cache
  • timeout: Время ожидания ввода в миллисекундах, после основного сообщения.
  • inter_digit_timeout: Число в миллисекундах - время ожидания ввода следующей цифры (если не достигнут порог максимальной длины ввода), по истечении которого, начинается сравнение с данными меню.
  • digit_len: Максимальная длина набора, по достижению которой, сразу начинается сопоставление.
  • max_failures: Максимальное кол-во неудачных попыток. По умолчанию '3' если не задано другое или задано некорректное значение (меньше 1).
  • max_timeouts: Максимальное кол-во повторов, перед завершением (по умолчанию число 'Неудачных попыток' или '3', если оба поля не заполнены или содержат некорректные данные (меньше 1)).
  • exec_on_max_failures: Вызвать приложение диалплана Freeswitch, если достигнут максимальный предел неудачных попыток.
  • exec_on_max_timeouts: Вызвать приложение диалплана Freeswitch, если достигнут максимальный предел таймаутов.
  • confirm_macro: Атрибут 'confirm-macro' указывает, какой макрос фразы следует воспроизводить, ожидая нажатия клавиши 'confirm-key'. Если установлено, макрос воспроизводится после того, как вызывающий абонент вводит добавочный номер адресата в IVR. Синтаксис аргумента: любой допустимый макрос фразы.
  • confirm_key: Переназначить ключ подтверждения ввода. По умолчанию '#', даже, если не заполнено.
  • confirm_attempts:
  • tts_engine: имя TTS движка для синеза текста (ie. cepstral). (опция).
  • tts_voice: имя TTS голоса (ie. david). (необходимо, если tts_engine задан).
  • Чтобы переопределить #, как встроенный терминатор и изменить его на * задайте в диалплане перед запуском ivr:
  <action application="set" data="ivr_menu_terminator=*"/>
Каждое меню может быть связано с несколькими типовыми действиями, привязанными к набираемой цифре:
  • menu-exit - Выход из IVR меню.
  • menu-sub - Вход в под-меню.
  • menu-exec-app - Выполнить приложение диалплана Freeswitch.
  • menu-play-sound - Проиграть аудио файл или произнести текст.
            <entry action="menu-play-sound" digits="3" param="say: You pressed 3"/>
            <entry action="menu-play-sound" digits="6" param="voicemail/vm-goodbye.wav"/>
  • menu-back - Вернуться на уровень выше.
  • menu-top - Вернуться на верхний уровень.
  • menu-exec-api - ранее документирована, но в данный момент не поддерживается ( v1.10.х).
Меню настраивается в конфигурационном файле autoload_configs/ivr.conf.xml.
 <configuration name="ivr.conf" description="IVR menus">
   <menus>
     <!-- demo IVR setup -->
     <!-- demo IVR, Main Menu -->
     <menu name="demo_ivr"
           greet-long="phrase:demo_ivr_main_menu"
           greet-short="phrase:demo_ivr_main_menu_short"
           invalid-sound="ivr/ivr-that_was_an_invalid_entry.wav"
           exit-sound="voicemail/vm-goodbye.wav"
           timeout="10000"
       inter-digit-timeout="2000"
       max-failures="3"
       digit-len="4">
       <entry action="menu-exec-app" digits="1" param="bridge sofia/$${domain}/888@conference.freeswitch.org"/>
       <entry action="menu-exec-app" digits="2" param="transfer 9996 XML default"/>    <!-- FS echo -->
       <entry action="menu-exec-app" digits="3" param="transfer 9999 XML default"/>    <!-- MOH -->
       <entry action="menu-sub" digits="4" param="demo_ivr_submenu"/>  <!-- demo sub menu -->
       <entry action="menu-exec-app" digits="5" param="transfer 1234*256 enum"/>    <!-- Screaming monkeys -->
       <entry action="menu-exec-app" digits="/^(10[01][0-9])$/" param="transfer $1 XML default"/> <!-- dial ext & x-fer -->
       <entry action="menu-top" digits="9"/>    <!-- Repeat this menu -->
     </menu>
     <!-- Demo IVR, Sub Menu -->
     <menu name="demo_ivr_submenu"
         greet-long="phrase:demo_ivr_sub_menu"
         greet-short="phrase:demo_ivr_sub_menu_short"
         invalid-sound="ivr/ivr-that_was_an_invalid_entry.wav"
         exit-sound="voicemail/vm-goodbye.wav"
         timeout="15000"
         max-failures="3">
       <entry action="menu-top" digits="*"/>
      </menu>
   </menus>
 </configuration>

IVR поддерживает подсказки при помощи макро фраз: mod_phrase,
как покзано ниже:

 <menu name="main"
     greet-long="phrase:mainmenu_phrase_macro"
     greet-short="phrase:short_mainmenu_phrase_macro"
     invalid-sound="phrase:invalid_entry_macro"
     exit-sound="phrase:goodbye_macro"
     timeout="10000"
     max-failures="3"
     tts-engine="cepstral"
     tts-voice="david"
     phrase_lang="en">
         <entry action="menu-exit" digits="*"/>
         <entry action="menu-sub" digits="2" param="menu2"/>
             <entry action="menu-say-phrase" digits="4" param="enteraccount"/>
         <entry action="menu-back" digits="5"/>
         <entry action="menu-exec-app" digits="7" param="transfer 888 XML default"/>
         <entry action="menu-sub" digits="8" param="menu8"/>
 </menu>

Использование в диалплане

 ivr
Пример:
 <action application="ivr" data="main"/>

Для работы IVR требуется предварительно ответить на вызов:

 <action application="answer"/>

Воспроизведение удаленных файлов и стримов

Есть два способа вопроизвести аудио из удаленных источников: mod_shout и mod_http_cache
mod_http_cache - является предпочтительным методом, причины описаны ниже:

 

Основная информация в описании модуля: mod_http_cache
 greet-short="http_cache://http://127.0.0.1/audio.mp3"
Используя вышеописанный метод, вы можете избежать обращения к удаленному серверу, каждый раз при воспроизведении аудио.
Однако, вы должны учесть некоторые накладные издержки:
  • Период хранения кэша не должен быть очень большим, на случай, если удаленный источник аудио будет изменен.
  • Начальное кэширование файла вызывает задержку в воспроизведении около 2 секунд. Возможно вы захотите использовать метод API - http_prefetch во избежание этого.

Если же,наоборот, аудио из кэша воспроизводится слишком рано, и съедает начало фразы, используйте команду sleep(ms), для внесения задержки:

 <action application="answer"/>
 <action application="sleep" data="500"/>
 <action application="ivr" data="my_ivr"/>
 greet-short="shout://127.0.0.1/audio.mp3"
По стравнению с mod_http_cache, mod_shout проигрывает из-за того, что:
  • Каждый раз при воспроизведении аудио, новый HTTP запрос производится к удаленному сервреру.
  • Любая задержка в сети может полвлиять на своевременное воспроизведение, даже если удаленный сервер это, тот же самый сервер.

Примеры

Сначала создайте меню, типа этого:
  <menu name="ivr-test"
   greet-long="/usr/local/freeswitch/sounds/greetings.wav"
   timeout="10000"
   inter-digit-timeout="2000"
   max-failures="1"
   max-timeouts="2"
   digit-len="1">
       <entry action="menu-exec-app" digits="1" param="bridge sofia/internal/1001%10.10.10.10"/>
       <entry action="menu-exec-app" digits="2" param="bridge sofia/internal/1002%10.10.10.10"/>
       <entry action="menu-exec-app" digits="3" param="bridge sofia/internal/1003%10.10.10.10"/>
 </menu>

И затем такой диалплан:

 <extension name="from_carrier_to_ivr-test">
     <condition field="destination_number" expression="^15559876543$">
         <action application="set" data="hangup_after_bridge=true"/>
         <action application="ivr" data="ivr-test"/>
         <action application="bridge" data="sofia/internal/1000%10.10.10.10"/>
     </condition>
 </extension>
Если абонент введет одну из цифр, назначеных в меню, вызов перейдет по назначению.
Если же нет, то по истечении таймаута, вызов вернется в диалплан и выполнит следующую за ivr команду.
Нужно использовать приложение execute_extension, с параметром - inline.

Например:

 <include>
     <menu name="ivr-test"
           greet-long="ivr/ivr-menu.wav"
           confirm-macro=""
           confirm-key=""
           confirm-attempts="3"
           timeout="5000"
           inter-digit-timeout="2000"
           max-failures="3"
           max-timeouts="2"
           digit-len="1">
         <entry action="menu-exec-app" 
                digits="1" 
                param="execute_extension limit:'hash ivr in',
 set:call_timeout=15,export:absolute_codec_string=G729,set:sip_cid_type=none,
 bridge:sofia/internal/1001%10.10.10.10,playback:ivr/ivr-busy.wav,hangup inline"/>
         <entry action="menu-exec-app" 
                digits="2" 
                param="execute_extension limit:'hash ivr in',
 set:call_timeout=15,export:absolute_codec_string=G729,set:sip_cid_type=none,
 bridge:sofia/internal/1002%10.10.10.10,playback:ivr/ivr-busy.wav,hangup inline"/>
     </menu>
 </include>
С execute_extension, вы можете доабавить последовательно любое приложение, как в обычном XML расширении диалплана, но строка не должна содержать пробелов.
Вы можете заменить их символом пробела \s или заключить подстроку с пробелами в одинарные кавычки ' ':
 limit:'hash ivr in'
Обратите внимание на приложения playback и hangup после bridge.

По умолчанию в IVR congtinue_on_fail=true, это значит, что если bridge потерпит неудачу, в примере выше, будет проигнано сообщение и соединение разорвано.
Если не разорвать вызов здесь, IVR снова проиграет приветственное сообщение. Для завершения вызова после удачного bridge,
вы должны назначить:

 <action application="set" data="hangup_after_bridge=true"/>
В диалплане до вызвова IVR или в каждом execute_extension меню ввода IVR, по схеме показанной выше.
Просто перечислив одну и ту же цифру несколько раз с разными приложениями, можно добиться такого же эффекта.
Например, если вы имеете несколько назначенных цифр "1", после ввода "1", каждое назначенное приложение будет вызвано последовательно.
Предполагается, что приложения будут вызваны в порядке перечисления.

Данный скриншот иллюстрирует вышеописанный способ и представляет собой, нашу реализацию (asterisk-pbx.ru) модуля IVR для реалтайм веб-интрефейса Freeswitch.
Структура модуля полностью идентична стандартному XML конфигу, просто данные хранятся в БД, а уже по ним Freeswitch создает XML инструкцию для ядра.

Используйте абсолютные пути к аудио файлам приветствий.
Когда вы используете относительный путь (без слэш вначале), тогда вы ссылаетесь на объект в директории аудио заданной в FS по умолчанию. (vars.xml)

Относительный: greet-short="ivr/ivr-menu.wav"

Абсолютный: greet-short="/full/path/to/file/ivr-menu.wav"

Также наш интерфейс предоставляет удобную форму для загрузки аудио файлов, с проверкой существования и прослушиванием.

Переменные

Переменная канала variable_ivr_menu_status может принимать значения: success, failure или timeout.
 variable_ivr_menu_status: [success]
 variable_ivr_menu_status: [failure]
 variable_ivr_menu_status: [timeout]

Events

IVR Menu events начиная с версии FreeSWITCH 1.6 .

Event-NameEvent-Subclassdesc
Custom menu::enter  
Custom menu::exit  

См. также

  • freeswitch/mod/mod_dptools/ivr_menu.txt
  • Последние изменения: 2020/08/08