Создание IVR на базе Астериск, с распознаванием DTMF и имён сотрудников (на базе Voicer от уважаемого antirek) и подключение к существующей АТС.
Наступающий новый год принёс в компанию, где я работаю, (не)радостную весть — умер древний сервер с системой IVR и PCI-платой на 4 аналоговых порта от Dialogic. Внезапно выяснилось, что современные системы не имеют PCI слотов, старые — не дружат с новыми версиями ОС и неизвестно сколько проживут, а лицензия имеется лишь на конкретную старую версию программы.
Так родилась идея поднять IVR без платы (и бесплатно) на виртуальной машине с Asterisk.
Итого, нам потребуются:
Если все пункты успешно выполнены — можно приступать. Первым делом стоит поставить сам asterisk, голосовые подсказки для теста, а также nodejs и npm.
Далее нам потребуется сам сервис распознавания voicer и process manager для его запуска:
Создадим папки и конфигурацию для voicer:
И запишем конфигурацию в файл /etc/voicer/config.js, добавив туда свои логин/пароль и ключ (developer_key) к желаемому сервису. В моём случае был выбран wit.ai — бесплатен, достаточно точен для наших задач.
Далее нам понадобится создать сервис для запуска voicer. Это будет файл /etc/init.d/voicer:
Ну и активировать его:
При этом надо учесть, что voicer будет складывать записанные файлы в папку /tmp и было бы её неплохо периодически чистить. Создаём простой скрипт для этого и складываем его в /etc/cron.daily
Ну а теперь осталась более сложная часть — настроить сам asterisk. Поскольку АТС у нас уже есть и все клиенты используют её, то большая часть конфигурации нам не нужна. Удаляем (или сохраняем в тёмное прохладное сухое место — по желанию) из папки /etc/asterisk всё, кроме asterisk.conf, modules.conf и sip.conf. И дописываем конфигурацию sip.conf следующими строками, добавив нужные нам значения для:
Тут стоит обратить внимание на то, в каком режиме работают dtmf команды в вашей АТС. Учтите, что они могут обрабатываться разными методами для внешних вызовов АТС (например — из города, или с мобильного телефона) и внутренних звонков между абонентами вашей АТС. В моём случае, в первом варианте это были inband dtmf сигналы, во втором — rfc2833. Но auto с этим справился. Также вас могут ожидать интересные особенности взаимодействия именно с вашей АТС — придётся на личном опыте выяснить, что требуется, например, для сохранения АОН вызывающего (внешнего) абонента при возврате звонка с IVR на АТС (строка sendrpid).
И остался ещё один конфигурационный файл. Самый важный. Dialplan, он же extensions.conf. В нём вам обязательно нужно указать ваш внешний номер (на который будут звонить люди), номер секретаря (на который уйдут звонки по умолчанию) и пути до ваших голосовых подсказок.
В данном примере используются записи с приветствием, именами сотрудников и фраза «соединяю вас». При этом подсказка для сотрудника ищется по его номеру, а если её нет произносится просто «с сотрудником». Подобные подсказки рекомендую заказать студии — системы синтеза речи, увы, не совершенны и их произношение названия вашей компании и фамилий сотрудников годится лишь для развлечения. 40XX — номера в компании, 4001 — секретарь.
Особенность данной ситуации в том, что у нас звонками занимается именно АТС. Таким образом, мы вместо обычной команды Dial используем команду Transfer — и тогда входящий звонок после IVR полностью уходит с asterisk и освобождает sip каналы АТС (их количество часто жёстко зафиксировано лицензией). В большинстве случаев в команде Transfer советуют использовать название направления (main_link), но для моей АТС подошло только прямое указание адреса станции.
Пришло время добавить пользователей для системы распознавания. Для этого заходим на адрес нашего сервера и порт 3100, после чего прописываем там имена, фамилии и номера сотрудников.
Теперь наш астериск умеет получать входящие звонки, распознавать DTMF сигналы, распознавать имена сотрудников и перенаправлять на их внутренние номера. Осталось лишь убедить станцию, что ей нужно отправлять входящие звонки на наш сервер. В зависимости от производителя эти настройки могут быть абсолютно разнообразны, но желаемый путь будет содержать слова ARS и маршрутизация звонков. Но это уже совсем другая история.
Наступающий новый год принёс в компанию, где я работаю, (не)радостную весть — умер древний сервер с системой IVR и PCI-платой на 4 аналоговых порта от Dialogic. Внезапно выяснилось, что современные системы не имеют PCI слотов, старые — не дружат с новыми версиями ОС и неизвестно сколько проживут, а лицензия имеется лишь на конкретную старую версию программы.
Так родилась идея поднять IVR без платы (и бесплатно) на виртуальной машине с Asterisk.
Итого, нам потребуются:
- Существующая АТС с абонентами
- Виртуальная машина (в примере — ubuntu 18.04 lts).
- Регистрация на каком-либо из сервисов распознавания голоса: wit.ai, google или яндекс
- Минимальное знание линукс систем
- Желание разобраться с Астериск
Если все пункты успешно выполнены — можно приступать. Первым делом стоит поставить сам asterisk, голосовые подсказки для теста, а также nodejs и npm.
apt install nodejs asterisk npm asterisk-core-sounds-ru-gsm
Далее нам потребуется сам сервис распознавания voicer и process manager для его запуска:
npm install voicer -g npm install pm2 -g
Создадим папки и конфигурацию для voicer:
mkdir -p /etc/voicer/data
И запишем конфигурацию в файл /etc/voicer/config.js, добавив туда свои логин/пароль и ключ (developer_key) к желаемому сервису. В моём случае был выбран wit.ai — бесплатен, достаточно точен для наших задач.
module.exports = { agi: { port: 3000 }, web: { port: 3100, auth: true, username: 'ИМЯ_ПОЛЬЗОВАТЕЛЯ', password: 'ПАРОЛЬ_ПОЛЬЗОВАТЕЛЯ', realm: 'НАЗВАНИЕ_КОМПАНИИ' }, processing: { totalAttempts: 2, playGreeting: true, playBeepBeforeRecording: false //use system beep }, asterisk: { sounds: { onErrorBeforeFinish: 'invalid', onErrorBeforeRepeat: 'invalid', greeting: 'beep' }, recognitionDialplanVars: { status: 'RECOGNITION_RESULT', target: 'RECOGNITION_TARGET' } }, record: { directory: '/tmp', type: 'wav', duration: 3, }, recognize: { directory: '/tmp', type: 'witai', // ['yandex', 'google', 'witai'] options: { developer_key: 'XXXXXXXXXXXXXXXXXXX' } }, lookup: { type: 'file', options: { dataFile: '/etc/voicer/data/peernames.json' } }, logger: { console: { colorize: true }, file: { filename: '/var/log/voicer.log', json: false } } };
Далее нам понадобится создать сервис для запуска voicer. Это будет файл /etc/init.d/voicer:
#!/bin/sh ### BEGIN INIT INFO # Provides: voicer # Required-Start: $network $syslog $named # Required-Stop: $network $syslog $named # Default-Start: 2 3 4 5 # Default-Stop: 0 1 6 # Short-Description: Start/stop voicer ### END INIT INFO set -e if [ -z "$1" ] ; then echo "Usage: $0 [start|stop|restart]" exit 0 fi if [ "$1" = "start" ] ; then VOICER_CONFIGFILE=/etc/voicer/config pm2 start voicer elif [ "$1" = "stop" ] ; then pm2 stop voicer elif [ "$1" = "restart" ] ; then $0 stop sleep 5 $0 start fi
Ну и активировать его:
systemctl daemon-reload systemctl enable voicer systemctl start voicer
При этом надо учесть, что voicer будет складывать записанные файлы в папку /tmp и было бы её неплохо периодически чистить. Создаём простой скрипт для этого и складываем его в /etc/cron.daily
#!/bin/sh rm /tmp/*.wav
Ну а теперь осталась более сложная часть — настроить сам asterisk. Поскольку АТС у нас уже есть и все клиенты используют её, то большая часть конфигурации нам не нужна. Удаляем (или сохраняем в тёмное прохладное сухое место — по желанию) из папки /etc/asterisk всё, кроме asterisk.conf, modules.conf и sip.conf. И дописываем конфигурацию sip.conf следующими строками, добавив нужные нам значения для:
- fromdomain — адрес сервера с астериск
- host — адрес АТС
- fromuser:secret и defaultuser:remotesecret — пары логин: пароль, которыми обменяются asterisk и АТС
[main_link] fromdomain=xxx.xxx.xxx.xxx host=xxx.xxx.xxx.yyy insecure=port port=5060 realm=asterisk sendrpid=pai fromuser=111 secret=111 defaultuser=222 remotesecret=222 qualify=yes type=friend disallow=all allow=alaw context=main_link promiscredir=yes dtmfmode=auto
Тут стоит обратить внимание на то, в каком режиме работают dtmf команды в вашей АТС. Учтите, что они могут обрабатываться разными методами для внешних вызовов АТС (например — из города, или с мобильного телефона) и внутренних звонков между абонентами вашей АТС. В моём случае, в первом варианте это были inband dtmf сигналы, во втором — rfc2833. Но auto с этим справился. Также вас могут ожидать интересные особенности взаимодействия именно с вашей АТС — придётся на личном опыте выяснить, что требуется, например, для сохранения АОН вызывающего (внешнего) абонента при возврате звонка с IVR на АТС (строка sendrpid).
И остался ещё один конфигурационный файл. Самый важный. Dialplan, он же extensions.conf. В нём вам обязательно нужно указать ваш внешний номер (на который будут звонить люди), номер секретаря (на который уйдут звонки по умолчанию) и пути до ваших голосовых подсказок.
[general] static=yes writeprotect=no [globals] [main_link] exten => ВАШ_ВНЕШНИЙ_НОМЕР,1,Goto(ivr_tree,s,1) [ivr_tree] ;allow direct dialing to internal users exten => _40XX,1,Background(custom/common/SoedinyauVas) ;check user voice existance same => n,Set(exists=${STAT(e,${ASTDATADIR}/sounds/custom/${EXTEN}.vox)}) same => n,Playback(custom/${IF($[ ${exists} = 1 ] ? ${EXTEN} : Sotrudnik)}) same => n,Transfer(SIP/${EXTEN}@АДРЕС_СТАНЦИИ) ;start intro exten => s,1,Answer() same => n,Set(CHANNEL(language)=ru) same => n,Background(custom/common/Welcome) ;start recognition same => n,AGI(agi://localhost:3000) same => n,GotoIf($[${RECOGNITION_RESULT}=SUCCESS]?:default) same => n,Background(custom/common/SoedinyauVas) ;check user voice existance same => n,Set(exists=${STAT(e,${ASTDATADIR}/sounds/custom/${RECOGNITION_TARGET}.vox)}) ;play user name or default name same => n,Playback(custom/${IF($[ ${exists} = 1 ] ? ${RECOGNITION_TARGET} : Sotrudnik)}) same => n,Transfer(SIP/${RECOGNITION_TARGET}@АДРЕС_СТАНЦИИ) same => n,Hangup() ;default route same => n(default),Transfer(SIP/4001@АДРЕС_СТАНЦИИ)
В данном примере используются записи с приветствием, именами сотрудников и фраза «соединяю вас». При этом подсказка для сотрудника ищется по его номеру, а если её нет произносится просто «с сотрудником». Подобные подсказки рекомендую заказать студии — системы синтеза речи, увы, не совершенны и их произношение названия вашей компании и фамилий сотрудников годится лишь для развлечения. 40XX — номера в компании, 4001 — секретарь.
Особенность данной ситуации в том, что у нас звонками занимается именно АТС. Таким образом, мы вместо обычной команды Dial используем команду Transfer — и тогда входящий звонок после IVR полностью уходит с asterisk и освобождает sip каналы АТС (их количество часто жёстко зафиксировано лицензией). В большинстве случаев в команде Transfer советуют использовать название направления (main_link), но для моей АТС подошло только прямое указание адреса станции.
Пришло время добавить пользователей для системы распознавания. Для этого заходим на адрес нашего сервера и порт 3100, после чего прописываем там имена, фамилии и номера сотрудников.
Теперь наш астериск умеет получать входящие звонки, распознавать DTMF сигналы, распознавать имена сотрудников и перенаправлять на их внутренние номера. Осталось лишь убедить станцию, что ей нужно отправлять входящие звонки на наш сервер. В зависимости от производителя эти настройки могут быть абсолютно разнообразны, но желаемый путь будет содержать слова ARS и маршрутизация звонков. Но это уже совсем другая история.
