The most basic elements of an IVR are quite similar to those of an automated attendant, though the goal is different. We need at least one prompt to tell the caller what the IVR expects from him, a method of receiving input from the caller, logic to verify that the caller’s response is valid input, logic to determine what the next step of the IVR should be, and finally, a storage mechanism for the responses, if applicable. We might think of an IVR as a decision tree, although it need not have any branches. For example, a survey may present exactly the same set of prompts to each caller, regardless of what choices the callers make, and the only routing logic involved is whether the responses given are valid for the questions.
From the caller’s perspective, every IVR needs to start with a prompt. This initial prompt will tell the caller what the IVR is for and ask the caller to provide the first input. We discussed prompts in the automated attendant in Chapter 15, The Automated Attendant. Later, we’ll create a dialplan that will allow you to better manage multiple voice prompts.
The second component of an IVR is a method for
receiving input from the caller. Recall that in Chapter 15, The Automated Attendant we discussed the Background()
and WaitExten()
applications for receiving a new
extension. While you could create an IVR using
Background()
and WaitExten()
, it is
generally easier and more practical to use the Read()
application, which handles both the prompt and the capture of the
response. The Read()
application was designed specifically for use with IVR systems. Its
syntax is as follows:
Read(variable
[,filename
[&filename2
...]][,maxdigits
][,option
][,attempts
][,timeout
])
The arguments are described in Table 17.1, “The Read() application”.
Table 17.1. The Read() application
Once the input is received, it must be validated.
If you do not validate the input, you are most likely going to find your
callers complaining of an unstable application. It is not enough to handle
the inputs you are expecting; you also need to handle inputs you do not
expect. For example, callers may get frustrated and dial
0
when in your IVR; if you’ve done a good job, you will
handle this gracefully and connect them to somebody who can help them, or
provide a useful alternative. A well-designed IVR (just like any program)
will try to anticipate every possible input and provide mechanisms to
gracefully handle that input.
Once the input is validated, you can submit it to an external resource for processing. This could be done via a database query, a submission to a URI, an AGI program, or many other things. This external application should produce a result, which you will want to relay back to the caller. This could be a detailed result, such as “Your account balance is…,” or a simple confirmation, such as “Your account has been updated.” We can’t think of any case where some sort of result returned to the caller is not required.
Sometimes the IVR may have multiple steps, and therefore a result might include a request for more information from the caller in order to move to the next step of the IVR application.
It is possible to design very complex IVR systems, with dozens or even hundreds of possible paths. We’ve said it before and we’ll say it again: people don’t like talking to your phone system, regardless of how clever it is. Keep your IVR simple for your callers, and they are much more likely to get some benefit from it.