Открыть меню
Toggle preferences menu
Открыть персональное меню
Вы не представились системе
Your IP address will be publicly visible if you make any edits.

8. Сценарии IVR

Материал из Платформа Эра. Документации
Версия от 15:32, 9 декабря 2024; Oagapov (обсуждение | вклад) (Новая страница: «Вопросы для разбора: * Назначение и принцип работы. * Компоненты и переходы между ними. * Переменные, выражения и функции. * Голосовые компоненты. Распознавание и синтез речи. * Файловые операции. Типы системных папок с учетом многосерверной архитектуры. *...»)
(разн.) ← Предыдущая версия | Текущая версия (разн.) | Следующая версия → (разн.)

Вопросы для разбора:

  • Назначение и принцип работы.
  • Компоненты и переходы между ними.
  • Переменные, выражения и функции.
  • Голосовые компоненты. Распознавание и синтез речи.
  • Файловые операции. Типы системных папок с учетом многосерверной архитектуры.
  • Доступ к данным объектной модели платформы.
  • Обращение к внешним данным и сервисам. Парсер.
  • Запуск подсценариев и передача параметров.
  • Метки и переходы.
  • Несколько компонентов Старт в одном сценарии.
  • Внешнее управление: передача звонка в контакт-центр и произвольные интеграции.
  • Кейс: сервис DISA с голосовой почтой для входящих звонков.
  • Отладка сценариев: уведомления, логирование.
  • Сходства и различия сценариев IVR и служебных.

Сценарии IVR (Interactive Voice Response) служат для автоматического обслуживания звонков. Обработчик сценариев является SIP-UA (user-agent), одной из сторон диалога. То есть для каждого подлежащего автоматическому обслуживанию звонка запускается отдельный обработчик сценария IVR.

Запуск производится:

  • при поступления звонка, смаршрутизированного на featurecode с типами ivr, parking, voicemail, hunt;
  • при инициации звонка компонентом Исходящий звонок;
  • сервисом управления звонками (API callsconferences);
  • сервисом селекторных совещаний в режиме предварительного воспроизведения после ответа абонента (сущность selector);
  • сервисом очередей после ответа оператора перед соединением с абонентом в режиме предварительного воспроизведения (сущность hunt-групп с типом user);

Алгоритм работы каждого сценария описываются сущностью ivrscript. Создаются в веб-приложении "Редактор сценариев" или могут управляться через API.

Сценарий IVR имеет основную ветвь и ветви пост-обработки. Основная ветвь активна только одновременно с активностью обслуживаемого диалога, а при завершении диалога выполнение основной ветви сценария прерывается. При этом его работа может быть продолжена на ветке пост-обработки.

Сценарий IVR, обслуживающий поступивший вызов, должен производить ответ (удачный 2xx или неудачный 3xx-6xx) на поступивший входящий SIP-запрос INVITE. Также может отправлять предварительные ответы 1xx.

Исполняется микросервисом ivr на одном из сайтов, обслуживающих домен.

Задания этой темы позволят освоить основные принципы работы сценариев, получить практику их создания, познакомиться с основными регулярно используемыми компонентами сценариев, опробовать работу с выражениями, функциями, переменными. Решить несколько часто встречающихся задач/кейсов и записать их себе в навыки.

Задание 8.1. Производительность сценариев.

=== Тест производительности сценариев.
Фоновое воспроизведение. ===

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

Вы можете синтезировать файл на странице Yandex SpeechKit и преобразовать его 

1. Реализуйте следующий сценарий:

  • Запустить фоновое воспроизведение мелодии из любого файла mp3.
  • Переменной i присвоить 0,
  • В переменную ts присвоить nowtick().
  • Если переменная i меньше 100, то i = i+1.
  • После инкремента разместить 100 компонентов "пауза" с нулевым таймаутом и замкнуть их на компонент сравнения.   

 Паузы можно копировать пачками, управление на них можно передать с помощью компонента "Функция".

  • Добавить в сценарий ветку пост-обработки, и вывести в ней уведомление текущему пользователю с информацией о длительности исполнения сценария.

2. ⁠Совершите звонок в сценарий. Он воспроизведет часть мелодии и завершится.

  • Сколько времени это заняло?
  • Что отобразилось в уведомлении?
  • Какое среднее время исполнения одного условно пустого компонента?   

3. ⁠Включите для сценария логирование в режиме TRACE.

  • Насколько увеличилось время выполнения?

4. Добавьте перед завершением сценария компонент синхронного воспроизведения речи. 

Вы можете синтезировать речь на странице Yandex SpeechKit, сохранить файл и преобразовать его к wav/mp3 формату с помощью приложений аудио-редактора, например audacity. 

  •  Исполните сценарий. Что произошло с воспроизведением фоновой мелодии?

5. Настройте компоненты воспроизведения так, чтобы фоновая мелодия и речь наложились друг на друга.

Задание 8.2. Вложенный сценарий

Вложенный сценарий. Передача контекстной информации.

В ходе выполнения задания будет получен опыт передачи управления и контекста вложенному сценарию. В дополнение к предыдущему заданию будет произведена актуализация оценки производительности сценариев.

   1. Создайте новый сценарий IVR "sub": 

  • Переменной i присвоить 0
  • Вставьте цикл из сравнения i<20, присвоения i=i+1, и трех пауз с нулевым таймаутом. 
  • Добавьте при выходе из цикла компонент уведомление с отправкой текущему пользователю номера итерации, переданного из вышестоящего сценария.
  • В конце поставьте компонент стоп с возратом управления.   

2. Добавьте к предыдущему тесту запуск вложенного сценария с возвратом управления на каждой 10-й итерации цикла.   

3. ⁠Совершите звонок в сценарий. 

    Количество запусков вложенного сценария 10. В процесс добавлено немногим более 1000 компонентов. 
    Насколько дольше стал выполняться сценарий, почему?   

4. ⁠Скачайте лог-журнал с трейсами сценариев текущего домена, проанализируйте залогированный процесс выполнения.

Задание 8.3. DISA

Выбор варианта абонентом. Прерывание.

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

   

1. Создать новый сценарий "query" и настройте его на номер 501.

2. Реализовать блок из вопроса абоненту, который может выбрать вариант с помощью DTMF.

3. Использовать компонент Воспроизведение. 

4. В зависимости от выбора выполнить различные действия – воспроизвести число с номером выбранного режима.

5. Добавьте в начало сценария паузу в 1 секунду.

6. Протестируйте звонком. Выбор варианта осуществляйте 

  • DTMF после окончания аудиофайла, 
  • DTMF во время звучания аудиофайла,
  • DTMF еще до начала воспроизведения во время паузы.

При необходимости запишите аудиофайлы с запросом у абонента на странице яндекс-speechkit и преобразуйте их в wav или mp3 с помощью audacity или консольного ffmpeg.

Какие сложности возникли?

Задание 8.4*. Файлы и пост-обработка

=== Запись голосовой почты.
Гарантированная запись.
Файловая система. ===

Работа с файлами в сценариях распределенной микросервисной системы существенно отличается от таковой в системах, обслуживаемых одним сервером. В рамках задания работа с файлами будет опробована на примере записи голосового сообщения. Будет получен опыт взаимодействия с API системы с помощью CURL или API-тестера, а также опыт настройки ветки пост обработки.

   

1. Откройте в адресной строке URL: http://SERVER_ADDRESS/rest/v1/fs/targets/files/ 

2. Закачайте в этот URL аудио-файл.

Вы можете это сделать с помощью curl или используйте расширение для браузера, например Talend API-tester.

Произвольные непубличные статические файлы домена (files)        

Справка. /api/rest/v1/fs/targets/files.html

 1. ⁠Создать новый сценарий "mail" и настройте его на номер 502. Реализуйте в нем: 

  • запись голосового сообщения, 
  • копирование записи в каталог для дальнейшего скачивания (необходимая информация по ссылке выше)
  • отправку записи в ящик абонента 102 компонентом "Голосовая почта". 

2. ⁠Необходимо предусмотреть, что:

  • абонент уведомляется о начале записи сообщения.
  • абонент может записывать сообщение произвольной длины в пределах 2 минут. 
  • абонент может испугаться и не записать сообщение. Корректными сообщениями считать сообщения длиной более 3 секунд.
  • абонент может завершать запись нажатием DTMF кнопки, может положить трубку, или ждать подтверждения от системы.
  • вне зависимости от того, каким образом запись завершена, голосовая почта должна быть отправлена, если только запись начата.

3. ⁠Исполните сценарий несколько раз. 

4. Прослушайте и посчитайте все записанные голосовые сообщения.

5. Откройте в адресной строке http://SERVER_ADDRESS/rest/v1/fs/targets/files/ . Там должно находиться то же самое количество файлов.

Почему нельзя сохраняя на диск в сценарии указывать абсолютные пути?

Задание 8.5*. Асинхронная обработка, JSON

=== Асинхронное исполнение.
Фоновое воспроизведение.
Взаимодействие сценариев.
Накопление DTMF.
Парсер JSON.  ===

В рамках задания будут опробованы подходы по параллельному вычислению, взаимодействию между параллельно выполняемыми сценариями. В нетривиальных сценариях то и дело приходится работать с JSON значениями — они приезжают в сценарии и через API, и при работе с сущностями. В задании будет опробован парсер значений JSON, а также получен опыт создания корректного JSON значения в сценарии для передачи в виде параметра куда-либо наружу.

Создайте новый сценарий IVR "test_async_ivr" и настройте его на номер 503. 

1. ⁠Параллельное фоновое воспроизведение.

  • Добавьте в сценарий IVR два фоновых воспроизведения подряд, так чтобы мелодия звучала не слишком громко, и на ее фоне звучала фраза, не прерывая мелодию.   

2. ⁠Создайте служебный сценарий: 

  • Примите там входные параметры: 1 – идентификатор родительского сценария, 2 – строка с json-содержимым. Используйте функцию выражений 'startparam(N)', 3 – строковый ключ.
  • Отобразите в уведомлении стартовые параметры,
  • Вычислите функцию от json-строки, например достаньте значение по ключу (компонент Парсер).
  • Подождите случайный таймаут от 1 до 60 секунд, 
  • Отправьте полученное значение в родительский сценарий по переданному идентификатору,
  • Отобразите в уведомлении информацию о завершении.        

3. ⁠В сценарии IVR:

  • Создайте переменную 'value' и задайте в неё произвольное строковое значение.
  • Сгенерируйте в переменную 'json' какой-нибудь json-объект. Сделайте это несколькими разными способами:
    • через константу;
    • через выражение с исползованием значения переменной 'value' и значением какой-либо встроенной функции, например remotenum();
    • через шаблон с использованием значения переменной 'value' и значением какой-либо встроенной функции, например callednum().
  • Запустите из сценария IVR асинхронный служебный сценарий для осуществления параллельного вычисления (или обращения к внешней системе).
  • Передайте в асинхронный сценарий первым параметром собственный идентификатор (функция выражений scriptref()) для возможности отправки результата, вторым - значение переменной json, третьим – название ключа, существующего в переданном json.     

4. После запуска организуйте следующую логику:

  • Сценарий интерактивно взаимодействует с абонентом. Воспроизводит длинную мелодию, а получив DTMF меняет мелодию на другую.
  • Ожидает ответа от асинхронного сценария, как только ответ приходит - прерывает воспроизведение, отображает результат текущему пользователю, и завершается.

Какие сложности возникли? 
Какие варианты решения задачи можете предложить?

Разбирать JSON-значение можно: компонентом “Парсер”, компонентом “Код JS”, формируя выражение для присвоения непосредственно в редакторе сценариев с использованием формата языка Erlang, выполняя заранее подготовленный проектный метод в каком-либо микросервисе продуктового слоя, выполняя консольное приложение. Каждый из этих способов имеет место и преимущество над другими по ряду параметров, поэтому овладеть в перспективе следует ими всеми.

Задание 8.6*. Восстановление

Восстановление сценария при падении медиа-шлюза

Будет получено представление о том, какими средствами и с каким результатом происходит дальнейшая обработка сценария IVR в случае, если по какой-либо причине неожиданно завершается работа обслуживающего медиа-шлюза. Будет получен опыт подключения к контейнеру и взаимодействия с процессами платформы.

1. ⁠Подключитесь к серверу (по ssh, если он не совпадает с вашей рабочей станцией).

2. Подключитесь к docker-контейнеру.

3. Запустите длинный сценарий IVR с любой логикой внутри. Например "test".

4. Во время исполнения сценария завершите принудительно процесс медиа-шлюза, обслуживающего сценарий (либо все процессы медиа-шлюзов, если у вас сложности с определением конкретного медиа-шлюза).

Какой результат наблюдается?

Задание 8.7**. Главный сценарий, early-media, трейс, js.

=== Главный сценарий
Early-media
Запись
Ветка пост-обработки
Динамическая модель данных
JSON
Код JS ===

В рамках задания будет создан и настроен сценарий обработки всех входящих вызовов. Будет опробован режим early-media (медиа-взаимодействия без поднятия трубки).

Под двумя звездочками — получение опыта создания собственного класса (коллекции в модели данных) и ведения трейса в сценарии с сохранением данных в него по мере исполнения сценария. Это например может быть полезно для реализации сценариев, которые могут начинать обслуживать абонента из разных точек, достигнутых абонентом в предыдущих этапах обслуживания.

Полезно иметь в арсенале удобный способ работы с JSON-значениями. В ряде случаев удобнее всего для этого использовать код на javascript. Первый опыт этого будет получен.

1. Создайте новый сценарий IVR "main". 

  • Назначьте его для обслуживания любых входящих вызовов с любых учетных записей провайдера.

2. В сценарии добавьте в самом начале воспроизведение приветствия, не "снимая трубку", то есть не отвечая 200 ОК и не запуская биллинг.

Чтобы абонент мог слышать воспроизводимое аудио-сообщение, необходимо отправить предварительный ответ 183 Session Progress. Важен именно числовой код ответа.

В общем случае у вас есть около 20 секунд, прежде чем провайдер отклонит вызов, находящийся в состоянии Early-Media. Однако в некоторых случаях этот интервал больше, и его можно продлевать периодической повторной отправкой предварительного ответа 183.  

Если ваш тестовый провайдер организован с помощью саморегистрации, то этого ограничения у вас нет.

  • Протестируйте с помощью входящего вызова и добейтесь работоспособности.

3. Не снимая трубки, запросите у абонента направление перевода. После ввода или таймаута организуйте перевод абонента в соответствующем направлении непосредственно из режима early-media.

Воспользоваться компонентами Перевод нельзя, поскольку они реализуются через SIP-команду REFER, а она требует установленного соединения, то есть предварительной отправки 200 ОК.

Зато вы можете воспользоваться SIP-ответом 3xx с переадресацией, ведь финального ответа сценарий еще не отправлял.

  •  Протестируйте с помощью входящего вызова и добейтесь работоспособности.

4. Добавьте компонент Запись и обеспечьте отправку голосового сообщения в почтовый ящик условного секретаря. Также оставайтесь в режиме early-media. Разместите эту ветвь при вводе абонентом DTMF "9".  

  • Протестируйте с помощью входящего вызова и добейтесь работоспособности.

5. Создайте строковую переменную "trace" для сбора последовательности обслуживания в сценарии.

  • Добавьте в сценарий функцию для добавления в трейс очередной позиции - это ветка, начинающаяся с комонента Метка и заканчивающаяся компонентом Возврат.
  • В рамках ветки добавляйте в строку очередное положение, переданное на вход компонента "Метка", например через запятую. 
  • После выбора абонентом ответа передайте его компонентом Функция на добавление в трейс.
  • Выведите перед завершением сценария уведомление с содержанием переменной трейс.
  • Протестируйте с помощью входящего вызова и добейтесь корректной работы.

6. Измените сценарий, ответив на вызов после приветствия, замените переадресацию на перевод. Итого:

  • При вводе внутреннего номера - переводите на номер.
  • При вводе или отсутствии ввода - переводите на номер секретаря (101).
  • При вводе 9 - переводите на запись голосового сообщения секретарю.
  • Фиксируйте выбор абонента в трейсе.
  • Фиксируйте результат выполнения выбранного действия в трейсе. Как это обеспечить в случае перевода?

7. Создайте класс "MainIvrSeances" в настройках администратора домена. Добавьте в список его свойств: время (datetime), номер телефона (string), маршрут (trace),  записи (attachments). 

  • Какого режим хранилища следует использовать для решения задачи сохранения трейсов обработанных вызовов?

8. При старте сценария создайте сущность MainIvrSeance в модели данных домена с помощью компонента "Операция", сразу заполнив время вызова и номер абонента.

Номер абонента доступен среди функций выражений remotenum().

9. Перед завершением сценария обновляйте сущность, размещая в ней накопленный трейс.

  • Каким образом гарантировать сохранение трейса при обрыве соединения?
  • Примените предложенные варианты.

10. Сохраните в сущность MainIvrSeance записанного значения в качестве вложения. 

11. Измените формат собираемого трейса: вместо строки, содержащей позиции через запятую, сформируйте JSON значение с массивом внутри.

Для работы с JSON можно использовать:

  1. Строковые константы с JSON-представлением объектов, сбор строки с JSON представлением объекта в выражениях и шаблонах, функцию выражений escape(...), компонент парсер.
  2. Код на языке javascript с помощью компонента Код JS.
  3. Код на языке erlang в рамках выражения при расчете аргумента.
  4. Заранее созданный метод в микросервисе продуктового слоя.
  5. Вызов заранее подготовленного внешнего веб-сервиса, консольного приложения или запроса к БД.
  • Примените компонент Код JS для добавления в JSON-трейс нового положения.
  • Примените компонент Парсер для выделения из JSON текущего значения трейса и вывода в уведомление.
  • Выполните компонент Парсер с помощью функции component(A,B,C) в выражениях.

12. Создайте служебный сценарий "script_trace", и создайте в нем содержание ветки функции trace из ранее созданного сценария IVR.

Вы можете пересоздать компоненты вручную.
Есть и другой путь - открыть JSON сценария IVR, обнаружить по именам внутренние компоненты ветки trace, и, скопировав их в буфер, вставить в JSON служебного сценария. А затем открыв сценарий в редакторе, причесать компоненты, соединив их ветками перехода и привязав существующие переменные.  

  • Дополнительно реализуйте в нем обработку входного параметра и применение для а) создания сущности MainIvrSeance, б) добавления в трейс нового положения и сохранения в соответствующую сущность, в) добавление записанного сообщения в качестве вложения. Какие параметры следует предусмотреть? 
  • Замените использование компонента Функция в сценарии IVR для сохранения трейса на выполнение асинхронного служебного сценария; перенесите всю работу с сущностью MainIvrSeance в служебный сценарий.
  • Какие преимущества и недостатки обнаруживаются в подходе с использованием асинхронного служебного сценария перед использованием функции внутри сценария?

Подведите итоги.