newspaint

Documenting Problems That Were Difficult To Find The Answer To

Creating A Basic IVR With Asterisk

So you want to start your home business using Asterisk. And you’d like incoming callers to be treated to the customary interactive voice response (IVR) that many modern businesses have.

Some Useful Links

When playing with dialplans keep these Asterisk links handy: application commands, variables, functions, and standard extensions.

The Audio

Start by recording a few voice prompts, such as “Welcome to Widgets Incorporated”. Save this as a .wav file.

Note that, for Asterisk to handle the voice files appropriately, they should be in 16-bit 8000Hz format. You can use ffmpeg to convert your audio files into the appropriate output format:

user@host:~> ffmpeg -i welcome-to-widgets-orig.wav \
  -ac 1 -ab 128000 -ar 8000 welcome-to-widgets-8000.wav
Input #0, wav, from 'welcome-to-widgets-orig.wav':
  Duration: 00:00:01.96, bitrate: 705 kb/s
    Stream #0.0: Audio: pcm_s16le, 44100 Hz, 1 channels, s16, 705 kb/s
Output #0, wav, to 'welcome-to-widgets-8000.wav':
  Metadata:
    encoder         : Lavf53.21.1
    Stream #0.0: Audio: pcm_s16le, 8000 Hz, 1 channels, s16, 128 kb/s
Stream mapping:
  Stream #0.0 -> #0.0
Press ctrl-c to stop encoding
size=      31kB time=1.96 bitrate= 128.2kbits/s
video:0kB audio:31kB global headers:0kB muxing overhead 0.146721%

Next – where do you put your audio files? You have to look it up from /etc/asterisk/asterisk.conf:

user@host:~> grep astdatadir /etc/asterisk/asterisk.conf
astdatadir => /usr/share/asterisk

So on my system sounds are, by default, at /usr/share/asterisk/sounds/. You can create subfolders but always be sure to prefix the subfolder name in the extensions.conf dialplan if you do.

The Dialplan

Now we have to create our dialplan. For the sake of testing let’s define an extension that will hook straight into our IVR.

exten => _755,1,NoOp()
  same => n,Goto(ivr-root,s,1)

This says that if 755 is dialled then we should jump into the ivr-root context with the s extension.

Now, what do we want our IVR to do? Maybe answer the phone and then pause for 500ms before the next step (the Answer() function does this). Next read out a message in the background while listening for an extension (the Background() function does this). Finally wait after the background message has been played for several seconds for an extension to be dialed (the WaitExten()function does this). The following would accomplish this:

[ivr-root]
exten => s,1,NoOp()
  same => n,Answer(500)
  same => n,Background(welcome-to-widgets-8000&enter-extension)
  same => n,WaitExten(3)
  same => n,HangUp()

You could write the Background statement as two separate statements (might be easier to read):

[ivr-root]
exten => s,1,NoOp()
  same => n,Answer(500)
  same => n,Background(custom/welcome-to-widgets-8000)
  same => n,Background(custom/enter-extension)
  same => n,WaitExten(3)
  same => n,HangUp()

Now you can give options and jump to other contexts. Imagine if you had a message “Please press 1 for Jim, press 2 for Bob, press 3 to hear this option again” saved as option-readout.wav you could have:

[ivr-root]
exten => s,1,NoOp()
  same => n,Answer(500)
  same => n,Background(custom/welcome-to-widgets-8000)
  same => n(my_marker),Background(custom/option-readout.wav)
  same => n,WaitExten(3)
  same => n,HangUp()

exten => 1,1,Dial(SIP/101) ; dial Jim

exten => 2,1,Dial(SIP/102) ; dial Bob

exten => 3,1,Goto(s,my_marker) ; repeat options

What if you want to press 2 for a new (e.g. sales) menu? Press 3 for a different (e.g. technical) menu? Create new contexts for the new menus.

[ivr-root]
exten => s,1,NoOp()
  same => n,Answer(500)
  same => n,Background(custom/welcome-to-widgets-8000)
  same => n(my_marker),Background(custom/option-readout)
  same => n,WaitExten(3)
  same => n,HangUp()

exten => 1,1,Dial(SIP/101) ; dial Jim

exten => 2,1,Goto(ivr-menu-sales,s,1)
exten => 3,1,Goto(ivr-menu-tech,s,1)

exten => 3,1,Goto(s,my_marker) ; repeat options

; ----
; sales group
[ivr-menu-sales]
exten => s,1,NoOp()
  same => n,Background(custom/options-sales)
  same => n,WaitExten(3)
  same => n,HangUp()

exten => 0,1,Goto(ivr-root,s,my_marker) ; go back to main manu

exten => 1,1,Dial(SIP/102) ; dial Bob

; ----
; technical group
[ivr-menu-tech]
exten => s,1,NoOp()
  same => n,Background(custom/options-tech)
  same => n,WaitExten(3)
  same => n,HangUp()

exten => 0,1,Goto(ivr-root,s,my_marker) ; go back to main manu

exten => 1,1,Playback(custom/our-website-location)

exten => 2,1,Playback(custom/frequently-asked-questions)

exten => 3,1,Dial(SIP/103) ; dial Fred

Diagnosis

To diagnose your IVR dialplan it is probably best to run Asterisk in verbose mode.

user@host:~> asterisk -rvvvv

To switch off verbose mode run asterisk again:

user@host:~> asterisk -r
host*CLI> core set verbose 1
Verbosity was 4 and is now 1

Issues

Frequency Mismatch

[Sep  3 13:22:55] WARNING[23571]: format_wav.c:110 check_header_fmt: Unexpected frequency mismatch 44100 (expecting 8000)

You may have to convert the file into an appropriate format using ffmpeg or similar. See also this blog post.

File Not Found

[Sep  3 13:25:05] WARNING[23726]: file.c:663 ast_openstream_full: File custom/welcome-to-widgets-8000 does not exist in any format
[Sep  3 13:25:05] WARNING[23726]: file.c:958 ast_streamfile: Unable to open custom/welcome-to-widgets-8000 (format 0x4 (ulaw)): No such file or directory

You need to double check the spelling of the file name, that the file actually exists in the directory, that the permissions of the file and directory allow reading, and that the Asterisks thinks sounds are where you think they are.

You can try specifying the full path to the file, e.g.:

  same => n,Background(/usr/local/share/asterisk/sounds/custom/welcome-to-widgets-8000)

If that succeeds then double check your asterisk.conf file.

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s

%d bloggers like this: