Интеграция Asterisk и Яндекс SpeechKit Cloud

Интеграция Asterisk и Яндекс SpeechKit Cloud

Сегодня я хочу поделиться опытом внедрения функционала распознавания речи от компании Яндекс. Данный функционал может оказаться полезным в сфере E-Commerce. Мы будем автоматизировать процессы клиентского обслуживания, а именно:
1. Клиент обращается по горячей линии компании или интернет-магазин, чтобы узнать статус заказа. IVR-система предлагает ввести номер заказа, если клиенту он известен.
2. Клиент вводит номер заказа посредством DTMF, а набранные данные передаются в AGI скрипт.
3. По номеру заказа, формируется SQL-запрос к базе данных, где хранится информация о всех заказах. Из соответствующей таблицы мы получаем имя клиента и статус заказа.
4. Далее формируем текстовую строку, которую необходимо озвучить клиенту и отправляем ее на генерацию аудио файла в API Яндекс SpeechKit Cloud (TTS технология – Text ti Speech).
5. Получаем сгенерированный файл от Яндекс, декодируем его в формат Asterisk (mono, .wav, 8000Hz) и воспроизводим клиенту.
6. Удаляем воспроизведенный файл и завершаем звонок.

Содержание

Шаг 1. Получение API-ключа Яндекс SpeechKit Cloud

Ранее мы рассматривали как получить API-ключ, поэтому останавливаться на этом пункте не будем.

Шаг 2. Создание таблицы с заказами

Создаем SQL таблицу, в которой будем хранить данные о заказах. Мы будем использовать базу данных asteriskcdrdb, которая располагается на том же хосте, что и Asterisk.
use asteriskcdrdb;
CREATE TABLE order (order_name varchar(20),order_phone varchar(20),order_number varchar(20),order_status varchar(20));
INSERT INTO order (order_name, order_phone, order_number, order_status) VALUES ("Александр", "79257777777", 300388, "Отправлен");
INSERT INTO order (order_name, order_phone, order_number, order_status) VALUES ("Иван", "79251111111", 476656, "Оплачен");
INSERT INTO order (order_name, order_phone, order_number, order_status) VALUES ("Сергей", "79252222222", 0089822, "Доставлен");
Мы создали и наполнили таблицу демо-данными для примера. Теперь необходимо создать пользователя, который будет иметь доступ к этой таблице:
CREATE USER 'Логин_mysql'@'localhost' IDENTIFIED BY 'Пароль_mysql';
GRANT SELECT ON asteriskcdrdb.order TO 'Логин_mysql';

Шаг 3. AGI-скрипт

#!/usr/bin/php -q
<?php
error_reporting(0);
require('phpagi.php');
$agi = new AGI();
$result = $agi->get_data('custom/generate', 6000, 10); //принимаем DTMF от клиента;
$number= $result['result']; //записываем в переменную введенный клиентом номер заказа;
$hostname = "localhost"; // у нас localhost. У вас может быть IP адрес сервера, на котором хранится БД с заказами (настройте предварительно pg_hba.conf на удаленном хосте);
$username = "Логин_mysql"; // логин, который вы создали этапом ранее;
$password = "Пароль_mysql"; // пароль, который вы создали этапом ранее;
$dbName = "asteriskcdrdb";
mysql_connect($hostname,$username,$password) OR DIE("Не могу создать соединение ");
mysql_select_db($dbName) or die(mysql_error());
$query = "SELECT * FROM order WHERE `order_number`='$number';"; // подключаемся и парсим данные по номеру заказа;
$res=mysql_query($query) or die(mysql_error());
while ($row = mysql_fetch_assoc($res)) {
$status = $row['order_status'];
$name = $row['order_name']; // имя и статус, полученные из SQL пишем в переменные;
};
$str = 'Дорогой '.$name.'! Статус вашего заказа '.$status.' Спасибо за обращение, всего доброго!'; // формируем строку, которую необходимо синтезировать;
$qs = http_build_query(array("key" => "ваш_API-ключ","text" => $str,"format" => "wav","lang" => "ru-RU","speaker" => "jane","emotion" => "good")); //описываем переменные, которые будем отправлять в сторону API Яндекса. Вы можете регулировать формат файла, локаль, спикера (мужской или женский голоса) и эмоциональный окрас. Заменить "ваш_API-ключ" на ключ, полученный от API Яндекс SpeechKit Cloud;
$ctx = stream_context_create(array("http"=>array("method"=>"GET","header"=>"Referer: rn")));
$soundfile = file_get_contents("https://tts.voicetech.yandex.net/generate?".$qs, false, $ctx);
$file = fopen("order_tts.wav", "w");
fwrite($file, $soundfile);
fclose($file); // получаем аудио файл (сохраняем его как order_tts.wav);
shell_exec('sox -t raw -r 48k -e signed-integer -b 16 -c 1 order_tts.wav -t wav -r 8k -c 1 /var/lib/asterisk/sounds/ru/custom/order_number_output.wav'); // выполняем преобразование аудио в нужный  для Asterisk аудио-формат и копируем его в директорию /var/lib/asterisk/sounds/ru/custom/;
shell_exec('chown asterisk:asterisk /var/lib/asterisk/sounds/ru/custom/order_number_output.wav');
shell_exec('chmod 775 /var/lib/asterisk/sounds/ru/custom/order_number_output.wav'); // даем файлу нужные пермишны;
$agi->exec('Playback',"custom/order_number_output");  // передаем в AGI команду проиграть полученный аудио – файл;
shell_exec('rm -f /var/lib/asterisk/sounds/ru/custom/order_number_output.wav');
shell_exec('rm -f order_tts.wav'); // удаляем оба файла;
?>
Формат текстового запроса описан в переменной $qs. Его следует передавать по протоколу HTTPS, методом GET.

Формат запроса имеет следующий вид:

https://tts.voicetech.yandex.net/generate?
&key=<API-ключ>
&text=<текст>
&format=<mp3|wav|opus>
&[quality=<hi|lo>]
&lang=<ru-RU|en-US|uk-UK|tr-TR>
&speaker=<jane|oksana|alyss|omazh|zahar|ermil>
&[speed=<скорость речи>]
&[emotion=<good|neutral|evil>]

key
API-ключ. Вы можете бесплатно получить API‑ключ в Кабинете разработчика.

text
Текст, который нужно озвучить. Любые символы, кроме символов английского алфавита и цифр, необходимо передавать в url-кодировке. Для передачи слов-омографов используйте + перед ударной гласной. Например, гот+ов или def+ect.
Ограничение на длину строки: 2000 байт.

format
Расширение синтезируемого файла (его формат). Допустимые значения:
mp3 — аудио в формате MPEG, медиаконтейнер MPEG-1 Audio Layer 3;
wav — аудио в формате PCM 16 бит, медиаконтейнер WAV;
opus — аудио в формате Opus, в качестве контейнера используется OGG.

quality (необязательный)
Частота дискретизации и битрейт синтезируемого PCM-аудио (медиаконтейнер WAV). Допустимые значения:
hi — частота дискретизации 48 кГц и битрейт 768 кб/c;
lo — частота дискретизации 8 кГц и битрейт 128 кб/c.
По умолчанию quality=hi. Обратите внимание, параметр quality влияет на характеристики аудио только если format=wav.

lang
Язык.
Допустимые значения: ru-RU — русский язык, en-US — английский язык, uk-UK — украинский язык, tr-TR — турецкий язык.
Язык не определяется автоматически. Значение параметра по умолчанию: ru‑RU.

speaker
Голос синтезированной речи. Можно выбрать один из следующих голосов:
женские голоса: jane, oksana, alyss и omazh;
мужские голоса: zahar и ermil.

speed (необязательный)
Скорость (темп) синтезированной речи. Скорость речи задается дробным числом в диапазоне от 0.1 до 3.0. Где:
3.0 — самый быстрый темп;
1.0 — средняя скорость человеческой речи;
0.1 — самый медленный темп.

emotion (необязательный)
Эмоциональная окраска голоса. Допустимые значения:
good — радостный, доброжелательный;
evil — раздраженный;
neutral — нейтральный (используется по умолчанию).
Примечание.
Значение neutral ранее называлась mixed (смешанная окраска голоса). Сейчас mixed поддерживается, но считается устаревшим.

Скрипт AGI сохраняем под именем tts.php в директории /var/lib/asterisk/agi-bin. Переделаем скрипт в UNIX формат и дадим права на выполнение:
dos2unix /var/lib/asterisk/agi-bin/tts.php
chown asterisk:asterisk /var/lib/asterisk/agi-bin/tts.php
chmod 775 /var/lib/asterisk/agi-bin/tts.php

Шаг 4. Настраиваем Asterisk

В файле /etc/asterisk/extensions.conf записываем новый контекст, который потом будем вызывать из IVR:

[tts_menu]
exten => s,1,Answer()
exten => s,2,AGI(tts.php)

Также вызов AGI-скрипта вы можете сделать через Macro() с использованием функции GoTo() или GoToIfTime().

Вызов AGI во FreePBX

Переходим по пути Admin -> Custom Destinations и нажимаем Add Destionations.
Интеграция Asterisk и Яндекс SpeechKit Cloud
Нажимаем Submit и Apply Config. Мы хотим чтобы из главного IVR – меню клиент при нажатии ‘4’ мог бы узнать статус своего заказа. Переходим в главный IVR и в секции IVR Entries добавляем следующее:
Интеграция Asterisk и Яндекс SpeechKit Cloud

На этом всё! Успехов и удачных внедрений.