📜 ⬆️ ⬇️

IVR with voice recognition on Asterisk - fast, easy, free

Creating an IVR based on Asterisk, with DTMF recognition and employee names (based on Voicer from a respected antirek ) and connecting to an existing PBX.

The upcoming new year brought to the company, where I work, (not) good news - an ancient server with an IVR system and a PCI-card for 4 analog ports from Dialogic died. Suddenly, it turned out that modern systems do not have PCI slots, the old ones are not friendly with the new versions of the OS and it is not known how long they will live, and the license is only for a specific old version of the program.
So the idea was born to raise IVR without a fee (and for free) on a virtual machine with Asterisk.

Total, we need:


If all items successfully completed - you can proceed. The first step is to install asterisk itself, voice prompts for the test, as well as nodejs and npm.

apt install nodejs asterisk npm asterisk-core-sounds-ru-gsm 

Next, we need the voicer recognition service and the process manager to start it:

 npm install voicer -g npm install pm2 -g 

Create folders and configuration for voicer:

 mkdir -p /etc/voicer/data 

And we will write down the configuration in the /etc/voicer/config.js file, adding our login / password and key (developer_key) to the desired service. In my case, wit.ai was chosen - free, accurate enough for our tasks.

 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 } } }; 

Next we need to create a service to start voicer. This will be the /etc/init.d/voicer file:

 #!/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 

Well, activate it:

 systemctl daemon-reload systemctl enable voicer systemctl start voicer 

It should be noted that voicer will add recorded files to the / tmp folder and it would be nice to clean it periodically. Create a simple script for this and add it to /etc/cron.daily

 #!/bin/sh rm /tmp/*.wav 

Well, now there is a more difficult part - to configure asterisk itself. Since we already have PBX and all clients use it, we do not need most of the configuration. We delete (or store in a dark cool dry place — optional) from the / etc / asterisk folder everything except asterisk.conf, modules.conf and sip.conf. And we add the sip.conf configuration in the following lines, adding the values ​​we need for:


 [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 

Here you should pay attention to the mode in which the dtmf commands work in your PBX. Consider that they can be processed by different methods for external calls from PBX (for example, from the city or from a mobile phone) and internal calls between subscribers of your PBX. In my case, in the first version these were inband dtmf signals, in the second one - rfc2833. But auto handled it. Also, you can expect interesting features of interaction with your PBX - you will have to find out by personal experience what is required, for example, to save caller ID of the calling (external) subscriber when returning a call from IVR to PBX (sendrpid line).

And there is one more configuration file left. The most important. Dialplan, he's extensions.conf. In it, you definitely need to specify your external number (to which people will call), the secretary’s number (to which the default calls will go) and the way to your voice prompts.

 [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@АДРЕС_СТАНЦИИ) 

This example uses posts with greetings, employee names, and the phrase “connect you.” At the same time, a hint for an employee is searched by his number, and if it is not there, it is simply pronounced “with an employee”. I recommend these kind of hints to order studios - speech synthesis systems, alas, are not perfect and their pronunciation of your company name and the names of the employees is only suitable for entertainment. 40XX - numbers in the company, 4001 - secretary.

The peculiarity of this situation is that our PBX deals with calls. Thus, instead of the usual Dial command, we use the Transfer command - and then the incoming call after the IVR completely leaves the asterisk and frees the PBX sip channels (their number is often hard fixed by the license). In most cases, the Transfer team is advised to use the name of the direction (main_link), but for my PBX it was only a direct indication of the station address.

It's time to add users to the recognition system. To do this, go to the address of our server and port 3100, after which we register there the names, surnames and numbers of employees.

Now our asterisk can receive incoming calls, recognize DTMF signals, recognize employees and redirect to their internal numbers. It remains only to convince the station that it needs to send incoming calls to our server. Depending on the manufacturer, these settings may be completely diverse, but the desired path will contain the words ARS and call routing. But that's another story.

Source: https://habr.com/ru/post/436016/