Components of an IVR

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:


The arguments are described in Table 17.1, “The Read() application”.

Table 17.1. The Read() application

variable The variable into which the caller’s response is stored. It is best practice to give each variable in your IVR a name that is similar to the prompt associated with that variable. This will help later if, for business reasons or ease of use, you need to reorder the steps of the IVR. Naming your variables var1, var2, etc. may seem easy in the short term, but later in your life cycle it will make fixing bugs more difficult.
prompt A file (or list of files, joined together with the & character) to play for the caller, requesting input. Remember to omit the format extension on the end of each filename.
maxdigits The maximum number of characters to allow as input. In the case of yes/no and multiple choice questions, it’s best practice to limit this value to 1. In the case of larger lengths, the caller may always terminate input by pressing the pound key.
options s (skip)Exit immediately if the channel has not been answered.
i (indication)Rather than playing a prompt, play an indication tone of some sort (such as the dialtone).
n (noanswer)Read digits from the caller, even if the line is not yet answered.
attempts The number of times to play the prompt. If the caller fails to enter anything, the Read() application can automatically re-prompt the user. The default is one attempt.
timeout The number of seconds the caller has to enter his input. The default value in Asterisk is 10 seconds, although it can be altered for a single prompt using this option, or for the entire session by assigning a value using the dialplan function TIMEOUT(response).

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.