Протестировать методы API можно на странице интерактивного обозревателя API и без написания кода
Некоторые ресурсы, описанные на странице, по умолчанию могут быть не доступны из-за типа приложения (см. Создание и авторизация приложений)
Правило голосовой навигации в голосовом меню:
Перед заданием правил голосовой навигации администратором платформы должна быть включена возможность использования правила voice_helper голосового меню. В обратном случае правило не может быть создано, а при отключении функционала правило в настройках голосового меню будет проигнорировано. Права приложения API должны быть all (также включается администратором платформы). Настройка выполняется аналогично другим правилам голосового меню в опциях контекста, количество правил также не ограничено. В ходе распознавания доступен финальный результат распознавания и предположения (предположения доступны в случае прерывания распознавания по набору цифр либо по тайм-ауту).
Описание структур данных
Имя | Тип | Описание |
---|---|---|
action | string | voice_helper – установить правило голосовой навигации. |
sound | integer | Идентификатор звукового файла, который необходимо проиграть, можно получить с помощью ресурса: GET /client/{client_id}/sound/ |
voice_helper_digits_max | integer | Количество цифр донабора, после которого заканчивается распознавание речи. Если на момент до набора нужного количества digits финальный результат распознавания недоступен, мы будем работать с предположениями |
voice_helper_rules | string | Список правил переадресации в виде массива { “to_option” : номер_опции, “transcription”: “распознанное слово” } |
voice_helper_timeout | integer | Время в миллисекундах, по истечении которого заканчивается распознавание речи. Если за это время финальный результат недоступен, мы будем работать с предположениями. Минимальное значение — 3000 |
voice_helper_classic_term | boolean | Разрешить либо запретить классический донабор с клавиатуры (по умолчанию запрещено и используется только как прерывание распознавания, см. параметр voice_helper_digits_max). |
voice_helper_final_count
integer
Количество попыток сообщить голосом то, что имеется в voice_helper_rules. Финальное распознавание определяется паузой в речи (до финального распознавания возможны только предположения). Обычно устанавливается от одной до трех попыток final_count
Создание правила голосового меню
К примеру, вызов попадает на внутренний номер с extension_id 204 в контекст 1 на опцию “start“. Будем считать, что контекст пустой и правил в нем еще нет. Добавляем правило, отправляем запрос:
Tabs |
---|
[{"content":{"version":1,"type":"doc","content":[{"type":"paragraph","content":[{"type":"text","text":"В разделе "},{"type":"text","text":"authentication","marks":[{"type":"strong"}]},{"type":"text","text":" в поля "},{"type":"text","text":"client_id","marks":[{"type":"strong"}]},{"type":"text","text":" и "},{"type":"text","text":"client_secret","marks":[{"type":"strong"}]},{"type":"text","text":" требуется ввести полученные при регистрации приложения значения "},{"type":"text","text":"Application_ID","marks":[{"type":"strong"}]},{"type":"text","text":" и "},{"type":"text","text":"Application_Secret","marks":[{"type":"strong"}]},{"type":"text","text":", затем нажать на кнопку \""},{"type":"text","text":"Try it out!","marks":[{"type":"strong"}]},{"type":"text","text":"\". Если данные приложения верны, в ответ вернётся токен доступа ("},{"type":"text","text":"access_token","marks":[{"type":"strong"}]},{"type":"text","text":"). Полученный токен доступа следует ввести в поле \""},{"type":"text","text":"Access Token Field","marks":[{"type":"strong"}]},{"type":"text","text":"\" вверху страницы и сохранить его нажатием кнопки \""},{"type":"text","text":"Set Token","marks":[{"type":"strong"}]},{"type":"text","text":"\"."}]},{"type":"paragraph","content":[{"type":"text","text":"Создание контекста:"}]},{"type":"table","attrs":{"isNumberColumnEnabled":false,"layout":"default"},"content":[{"type":"tableRow","content":[{"type":"tableHeader","attrs":{},"content":[{"type":"paragraph","content":[{"type":"text","text":"метод","marks":[{"type":"strong"}]}]}]},{"type":"tableHeader","attrs":{},"content":[{"type":"paragraph","content":[{"type":"text","text":"ресурс","marks":[{"type":"strong"}]}]}]},{"type":"tableHeader","attrs":{},"content":[{"type":"paragraph","content":[{"type":"text","text":"данные","marks":[{"type":"strong"}]}]}]}]},{"type":"tableRow","content":[{"type":"tableCell","attrs":{},"content":[{"type":"paragraph","content":[{"type":"text","text":"POST"}]}]},{"type":"tableCell","attrs":{},"content":[{"type":"paragraph","content":[{"type":"text","text":"/"},{"type":"text","text":"extension/204/ivr/context/1/options/start/rules/"}]}]},{"type":"tableCell","attrs":{},"content":[{"type":"paragraph","content":[{"type":"text","text":"{"},{"type":"hardBreak"},{"type":"text","text":"\"voice_helper_digits_max\": 2,"},{"type":"hardBreak"},{"type":"text","text":"\"voice_helper_rules\": ["},{"type":"hardBreak"},{"type":"text","text":"{"},{"type":"hardBreak"},{"type":"text","text":"\"to_option\": 1,"},{"type":"hardBreak"},{"type":"text","text":"\"transcription\": \"привет|здравствуй|здарова\""},{"type":"hardBreak"},{"type":"text","text":"},"},{"type":"hardBreak"},{"type":"text","text":"{"},{"type":"hardBreak"},{"type":"text","text":"\"to_option\": 2,"},{"type":"hardBreak"},{"type":"text","text":"\"transcription\": \"прощай|пока\""},{"type":"hardBreak"},{"type":"text","text":"},"},{"type":"hardBreak"},{"type":"text","text":"],"},{"type":"hardBreak"},{"type":"text","text":"\"sound\": 52,"},{"type":"hardBreak"},{"type":"text","text":"\"voice_helper_timeout\": 7000"},{"type":"hardBreak"},{"type":"text","text":"}"}]}]}]}]},{"type":"paragraph","content":[{"type":"text","text":"Обновление текущего контекста:"}]},{"type":"table","attrs":{"isNumberColumnEnabled":false,"layout":"default"},"content":[{"type":"tableRow","content":[{"type":"tableHeader","attrs":{},"content":[{"type":"paragraph","content":[{"type":"text","text":"метод","marks":[{"type":"strong"}]}]}]},{"type":"tableHeader","attrs":{},"content":[{"type":"paragraph","content":[{"type":"text","text":"ресурс","marks":[{"type":"strong"}]}]}]},{"type":"tableHeader","attrs":{},"content":[{"type":"paragraph","content":[{"type":"text","text":"данные","marks":[{"type":"strong"}]}]}]}]},{"type":"tableRow","content":[{"type":"tableCell","attrs":{},"content":[{"type":"paragraph","content":[{"type":"text","text":"PUT"}]}]},{"type":"tableCell","attrs":{},"content":[{"type":"paragraph","content":[{"type":"text","text":"/"},{"type":"text","text":"extension/204/ivr/context/1/options/start/rules/1"}]}]},{"type":"tableCell","attrs":{},"content":[{"type":"paragraph","content":[{"type":"text","text":"{"},{"type":"hardBreak"},{"type":"text","text":"\"voice_helper_digits_max\": 2,"},{"type":"hardBreak"},{"type":"text","text":"\"voice_helper_rules\": ["},{"type":"hardBreak"},{"type":"text","text":"{"},{"type":"hardBreak"},{"type":"text","text":"\"to_option\": 1,"},{"type":"hardBreak"},{"type":"text","text":"\"transcription\": \"привет|здравствуй|здарова\""},{"type":"hardBreak"},{"type":"text","text":"},"},{"type":"hardBreak"},{"type":"text","text":"{"},{"type":"hardBreak"},{"type":"text","text":"\"to_option\": 2,"},{"type":"hardBreak"},{"type":"text","text":"\"transcription\": \"прощай|пока\""},{"type":"hardBreak"},{"type":"text","text":"},"},{"type":"hardBreak"},{"type":"text","text":"],"},{"type":"hardBreak"},{"type":"text","text":"\"sound\": 52,"},{"type":"hardBreak"},{"type":"text","text":"\"voice_helper_timeout\": 7000"},{"type":"hardBreak"},{"type":"text","text":"}"}]}]}]}]},{"type":"paragraph","content":[]}]},"id":"19d8553e-48b1-433a-b7b3-ac0f9b6bab25","label":"Интерактивный обозреватель API ","type":"tab"},{"content":{"version":1,"type":"doc","content":[{"type":"paragraph","content":[{"type":"text","text":"Для отправки запросов с помощью программы cURL установим значения переменных "},{"type":"text","text":"url ","marks":[{"type":"strong"}]},{"type":"text","text":"и "},{"type":"text","text":"access_token","marks":[{"type":"strong"}]},{"type":"text","text":":"}]},{"type":"paragraph","content":[{"type":"text","text":"export url=\"https://<hostname>/api/ver1.0\"","marks":[{"type":"code"}]},{"type":"text","text":" "},{"type":"hardBreak"},{"type":"text","text":"(где hostname — hostname API-сервера провайдера IP-телефонии),"}]},{"type":"paragraph","content":[{"type":"text","text":"export access_token=\"8SNsrS0jV35vfmKqKeKtRrHfpbg4UX\"","marks":[{"type":"code"}]},{"type":"text","text":" "},{"type":"hardBreak"},{"type":"text","text":"(полученный токен доступа)."}]},{"type":"paragraph","content":[{"type":"text","text":"Запрос для создания контекста:"}]},{"type":"codeBlock","attrs":{"language":"shell"},"content":[{"type":"text","text":"curl \\\n-H \"Authorization: Bearer ${access_token}\" \\\n-H \"Content-Type: application/json\" \\\r\n-d '{\n \"voice_helper_digits_max\": 2,\n \"voice_helper_rules\": [\n {\n \"to_option\": 1,\n \"transcription\": \"привет|здравствуй|здарова\"\n },\n {\n \"to_option\": 2,\n \"transcription\": \"прощай|пока\"\n },\n ],\n \"sound\": 52,\n \"voice_helper_timeout\": 7000\n}' \\\n-X POST ${url}/extension/204/ivr/context/1/options/start/rules/"}]},{"type":"paragraph","content":[{"type":"text","text":"Запрос для обновления текущего контекста:"}]},{"type":"codeBlock","attrs":{"language":"shell"},"content":[{"type":"text","text":"curl \\\n-H \"Authorization: Bearer ${access_token}\" \\\n-H \"Content-Type: application/json\" \\\r\n-d '{\n \"voice_helper_digits_max\": 2,\n \"voice_helper_rules\": [\n {\n \"to_option\": 1,\n \"transcription\": \"привет|здравствуй|здарова\"\n },\n {\n \"to_option\": 2,\n \"transcription\": \"прощай|пока\"\n },\n ],\n \"sound\": 52,\n \"voice_helper_timeout\": 7000\n}' \\\n-X PUT ${url}/extension/204/ivr/context/1/options/start/rules/1"}]}]},"id":"d64cceb4-96ce-4e6d-b799-3e3a83ab410a","label":"Программа cURL ","type":"tab"},{"content":{"version":1,"type":"doc","content":[{"type":"paragraph","content":[{"type":"text","text":"Для отправки запросов на языке Python установим значения переменных URL и ACCESS_TOKEN:"}]},{"type":"paragraph","content":[{"type":"text","text":"URL = \"https://<hostname>/api/ver1.0\"","marks":[{"type":"code"}]},{"type":"hardBreak"},{"type":"text","text":"(где hostname — hostname API-сервера провайдера IP-телефонии),"}]},{"type":"paragraph","content":[{"type":"text","text":"ACCESS_TOKEN = \"8SNsrS0jV35vfmKqKeKtRrHfpbg4UX\"","marks":[{"type":"code"}]},{"type":"hardBreak"},{"type":"text","text":"(полученный токен доступа)."}]},{"type":"paragraph","content":[{"type":"text","text":"Запрос для создания контекста:"}]},{"type":"codeBlock","attrs":{"language":"python"},"content":[{"type":"text","text":"#!/usr/bin/python\n\nimport requests\n\nurl = f'{URL}/extension/204/ivr/context/1/options/start/rules/'\nheaders = {\n 'Authorization': f'Bearer {ACCESS_TOKEN}',\r\n 'Content-Type': 'application/json'\n}\ndata = '''{\n \"voice_helper_digits_max\": 2,\n \"voice_helper_rules\": [\n {\n \"to_option\": 1,\n \"transcription\": \"привет|здравствуй|здарова\"\n },\n {\n \"to_option\": 2,\n \"transcription\": \"прощай|пока\"\n },\n ],\n \"sound\": 52,\n \"voice_helper_timeout\": 7000\n}'''\nresponse = requests.post(url, headers=headers)\nprint(response.text)"}]},{"type":"paragraph","content":[{"type":"text","text":"Запрос для обновления текущего контекста:"}]},{"type":"codeBlock","attrs":{"language":"python"},"content":[{"type":"text","text":"#!/usr/bin/python\n\nimport requests\n\nurl = f'{URL}/extension/204/ivr/context/1/options/start/rules/1'\nheaders = {\n 'Authorization': f'Bearer {ACCESS_TOKEN}',\r\n 'Content-Type': 'application/json'\n}\ndata = '''{\n \"voice_helper_digits_max\": 2,\n \"voice_helper_rules\": [\n {\n \"to_option\": 1,\n \"transcription\": \"привет|здравствуй|здарова\"\n },\n {\n \"to_option\": 2,\n \"transcription\": \"прощай|пока\"\n },\n ],\n \"sound\": 52,\n \"voice_helper_timeout\": 7000\n}'''\nresponse = requests.put(url, headers=headers)\nprint(response.text)"}]}]},"id":"330b1ded-3454-41bc-bbd1-f0b38b6d1652","label":"На языке Python3 ","type":"tab"}] |
Ответ системы (остальные параметры не имеют значения и исключены из примера):
Code Block | ||
---|---|---|
| ||
{ … "voice_helper_sound": 52, "voice_helper_timeout": 7000, "id": 39, "voice_helper_digits_max": "2", "voice_helper_rules": [ { "transcription": "привет|здравствуй|здарова", "to_option": 1 }, { "transcription": "прощай|пока", "to_option": 2 } ], "final": true, "action": "voice_helper", … } |
В ответе на запрос будет содержаться идентификатор созданного правила: "id": 39. В результате указанного выше запроса будет создано правило голосовой навигации, по которому будет проиграна мелодия по умолчанию.
Опции to_option, куда попадут при сообщении слова из transcription, должны быть созданы (они не создаются автоматически). Параметр transcription может содержать как точное слово, так и часть слова.
Создание звукового приветствия
Если нужно задать конкретное звуковое приветствие, чтобы сообщить в нем, что от звонящего ожидается то или иное слово, нужно заранее подготовить звуковой файл. Ресурс “Звуковые файлы” позволит загрузить файл и узнать идентификатор этого файла. После этого нужно обновить параметры правила голосового помощника, задав идентификатор необходимого звукового файла.
Обновление параметров правила голосового помощника
Обновить любой параметр правила можно с помощью метода
PUT /api/ver1.0/extension/{extension_id}/ivr/context/{context_id}/options/{option_digits}/rules/{rule_id}
К примеру, для задания актуального приветствия с указанием нужного идентификатора файла SOUND_ID нужно отправить вышеуказанный запрос с телом{"sound": SOUND_ID}
Аналогичным способом обновляется любой параметр правила voice_helper. Например, можно заменить правила voice_helper_rules с помощью запроса
PUT /api/ver1.0/extension/{extension_id}/ivr/context/{context_id}/options/{option_digits}/rules/{rule_id} с телом
Code Block | ||
---|---|---|
| ||
{"voice_helper_rules": [ { "to_option": 1, "transcription": "продукты|еда" }, { "to_option": 2, "transcription": "комиксы|комик|икс" } ] } |
Не рекомендуется задавать много условий в одном правиле voice_helper_rules (желательно не более 500).
Параметр to_option – это опции контекста (start, invalid, timeout, 1, 2, 3, 4 и т.д.). Правило voice_helper создано в опции start, а навигация голосом будет по опциям 1-10 (либо, к примеру, по 4-40).
Создание опций выполняется запросом
POST /api/ver1.0/extension/{extension_id}/ivr/context/{context_id}/options/ с телом
Code Block | ||
---|---|---|
| ||
{"digits": "string"} |
где string – опции контекста start, invalid, timeout, 1, 2, 3, 4 и т.д.
Получение распознанных данных удаленным сервером
Существует возможность получить данные распознавания на своем удаленном сервере.
Функция “Call Interactive” позволяет в качестве действия опции контекста голосового меню (IVR) инициировать HTTP-запрос на заданный URL и обработать ответ на него. С запросом передается постоянный набор параметров, содержащий информацию о вызове в IVR. Для управления действиями после распознавания существуют опциональные параметры запроса функции Call Interactive:
voice_navigator_DTMF – донабор с телефонного терминала во время правила голосового меню action='voice_helper';
voice_navigator_STT – содержит распознавание голоса во время правила голосового меню action='voice_helper'.
Функция “Call interactive” запросом POST http://mysite.com/myscript?check_number возвращает нужное приветствие с указанием дополнительных параметров, помимо TTS (play_now="false", save_to_var="true"). В таком случае voice_helper c заданным параметром play_sound_from_variable проигнорирует установленное у себя приветствие.
Вызов попадает в стартовый контекст (start), где помимо стандартных опций контекста (start, timeout, invalid) настроены пользовательские опции, например: “1” – ‘call_interactive’, “2” – ‘voice_helper'. Система ожидает, когда звонящий скажет что-то либо донаберет опцию (это объявлено в правиле voice_helper). Например, если звонящий скажет “оператор” – попадет на опцию “0”, а если что-либо из заданных слов (например: "узнать, дату, дата, готовности, готовность, отгрузке, отгрузка, товар, счету, счет") либо наберет 1 – попадет на опцию “1”, где будет работать правило Call Interactive, по которому на сервер будет отправлен запрос POST http://mysite.com/myscript?check_stt_res , после чего сервером будут получены данные:voice_navigator_STT=%D1%85%D0%BE%D1%87%D1%83+%D1%83%D0%B7%D0%BD%D0%B0%D1%82%D1%8C+%D0%B4%D0%B0%D1%82%D1%83+%D0%B3%D0%BE%D1%82%D0%BE%D0%B2%D0%BD%D0%BE%D1%81%D1%82%D0%B8+%D0%BA+%D0%BE%D1%82%D0%B3%D1%80%D1%83%D0%B7%D0%BA%D0%B5+%D1%82%D0%BE%D0%B2%D0%B0%D1%80%D0%B0
url decode voice_navigator_STT=хочу узнать дату готовности к отгрузке товара
либо voice_navigator_DTMF=1
Если в правиле voice_helper ни одна из опций не отработает (не донаберут или не скажут ни “0”, ни “1”), то в стартовом контексте будет звучать приветствие по умолчанию с предложением соединиться с оператором (“Скажите “оператор” или нажмите “0”). В таком случае можно добавить Call interactive с запросом запрос POST http://mysite.com/myscript?no_option_voice_helper, в котором если и будет voice_navigator_STT, то оно будет содержать значение, альтернативное опциям “0” и “1” (например, если звонящий спросит: "А куда я попал?”), после чего можно задавать другие действия как управлением из Call Interactive, так и статическими правилами в IVR.
События с распознанным текстом
Чтобы получить события с финальным распознанным текстом во время разговора, необходимо воспользоваться следующей схемой. По событию на внутреннем номере (dial-in для входящих вызовов в IVR, anwser для входящих и исходящих с внутреннего номера типа “телефонный терминал”) в зависимости от CallFlow события нужно запомнить extension_id (идентификатор внутреннего номера; если in — CalledExtensionID, если out — CallerExtensionID)и CallAPIID и воспользоваться ресурсом:
PUT /extension/{extension_id}/speech_to_text/{call_api_id}
Описание структур данных
Имя | Тип | Описание |
---|---|---|
extension_id | string | Идентификатор внутреннего номера |
call_api_id | string | Идентификатор звонка, по которому начнется распознавание речи |
action | string | Действие, может принимать значения start или stop |
direction | string | Направление распознанной речи относительно extension_id: out — если голос идет от внутреннего номера, in — если голос идет к внутреннему номеру |
url | string | URL, куда будут отправляться события с распознанным из речи текстом |
Info |
---|
При повторной попытке одного и того же action с одним и тем же direction на один и тот же разговор будет выдано сообщение об ошибке! |
События выглядят подобным образом:
Code Block | ||
---|---|---|
| ||
POST / HTTP/1.1 Host: 213.170.66.158:12345 user-agent: Ringme Event Generator Accept: Accept-Encoding: gzip, deflate Content-Length: 394 Content-Type: application/x-www-form-urlencoded call_api_id=3232240860-15e67fb4-8f9a-11ea-90b9-05381d8e3a62&extension_id=34414&direction=out&text=%D0%90+%D0%B2%D0%BE%D0%B4%D0%B5+%D0%BC%D0%B8%D0%BC%D0%BE+%D1%81%D0%B5%D0%B9%D1%87%D0%B0%D1%81+%D0%BB%D0%B5%D1%82+%D1%81%D0%B5%D0%B3%D0%BE+%D0%BA%D0%BE%D0%BC%D0%B0%D1%80%D0%B0+%D0%B7%D0%B0%D0%B1%D0%BE%D1%82%D0%B0+%D0%BB%D1%8E%D0%B4%D0%B8+%D1%87%D0%B0%D1%81%D1%83+%D1%81+15+%D0%B3%D0%BE%D0%B4%D0%B0 |
Длину контента можно считать по Content-Length.
Распознанный текст в читаемом виде – после url decode utf8.
Ресурсы раздела “Внутренний номер”
Expand | ||||||||||||||
---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| ||||||||||||||
PUT /extension/{extension_id}/speech_to_text/{call_api_id} Параметры URL
Параметры запроса
|