In this fourth segment of our complete tour through VoiceXML, we will learn how to test user input after it has been spoken. We'll also learn how to utilize conditional statements such as if and else to control call flow. Lastly, we'll learn how to catch and handle errors and other VoiceXML events.
Wow, I feel like we've really come a long way in a month. We've had an
in-depth tour of most of the VoiceXML basics. I've hope you've been learning
as much as I have. In this fourth segment of our complete tour through VoiceXML,
we will learn how to test user input after it has been spoken. We'll also learn
how to utilize conditional statements such as if and else to control
call flow. Lastly, we'll learn how to catch and handle errors and other VoiceXML
events. All in this edition of the VoiceXML Developer.
Handle events with <nomatch>, <noinput>, <help>, and <error>
One important aspect of writing a robust VoiceXML application is handling events
that are thrown by the VoiceXML gateway. Failing to do so may cause your application
to end abruptly. There a number of events that should be handled in all VoiceXML
applications that are used in production. These are help,
nomatch, noinput, and error.
Event handlers can be used in fields, forms, menus, and subdialogs. The
noinput event is triggered when the system doesn't receive
input as expected. The nomatch event is triggered when a user
gives input that doesn't match the defined grammar. The help
event is triggered when the user says "help" at any point in the dialog.
An error event can be triggered for many different reasons including
a system failure and unavailable resources.
This example is a phone-based hot dog stand that includes handlers
for all the events listed above.
An example dialog using the VoiceXML above follows:
Computer: Welcome to Mr. T's snack shop.
Alright. What you want sucker?
Operator: <no response>
Computer: Hey, I ain't got all day punk.
It's time to pick and pay before I get upset!
Operator: I want a watermelon.
Computer: Hey stupid! Order a hotdog, pretzel,
chips, or soda punk! It's time to pick and pay before
I get upset!
Computer: Help? The only help I give starts with a
capital tee and ends with my fist.
It's time to pick and pay before I get upset!
Computer: So, you want a soda. Well, pay up sucker!
Event handlers are called based upon the scope in which they
exist in relation to the element that threw the event. In the example
above, Mr T is an impatient hot dot vendor. He will ask you for your
order on line 6. Because the timeout attribute of the
prompt element is set to 3, if you don't give Mr. T
your order in three seconds, the prompt element will throw a
noinput event. Because the <noinput>
element on line 8 is in the same scope as the prompt, the VoiceXML
interpreter will execute its contents, which express Mr. T's impatience
with the user, and prompt the user again with <reprompt /> on line
One neat feature of prompts is the ability to execute
different content based upon the number of times the user has been
prompted. This is accomplished by setting the count
attribute to the instance number that the prompt should be played. So the first
prompt that's played is, "Alright. What you want sucker?"
The next time that the prompt is called, the user would hear,
"It's time to pick and pay before I get upset!" This second
prompt would get played in the case where a user does not provide input
within three seconds and the noinput event is called.
The count attribute can also be used in
<nomatch> and <noinput> elements to make the dialog more
natural by providing different feedback if the user makes the
same error more than once. Subsequent nomatch
or noinput events may indicate that the user is
having problems understanding what they're supposed to say. Therefore,
the count attribute is a way to provide the
user with more detailed instructions the second time they
(or the VoiceXML interpreter) make a mistake.
Speaking of nomatch, this event is thrown when a
user provides spoken or DTMF input that doesn't match a grammar.
Line 14 contains the <nomatch> element for our
Another important event handler is <help>. Help is a special
keyword in VoiceXML that, when spoken by a user, triggers the help
event. The <help> element catches this event on line 24. Since users
may not be aware of this feature, you may want to include it in your prompts.
For example, "Please say your name and social security number or say help
Lastly, when the VoiceXML interpreter encounters a fatal error, it throws
the error event, which can be caught with the <error>
element on line 29. You may want to let the user know that an error has
occurred and either return them to a previous menu or exit the application.
For example, "An error has occurred while processing your request.
Please hold while I transfer you to a customer service representative."
Processing input with <filled>
Once we have received input that matches the field or form level grammar(s),
it's time to do something with it. This might include validating a credit
card number, looking up information based upon a customer name, or submitting
the information to a back-end script. The <filled> element can exist
within a field or form scope. That is, if the element exists inside a
element, it will be called when that field has been filled with a value. If
it exists inside the <form> element, but outside the
<field> elements, it will be called once ALL form
fields have been filled. So basically, you can check and validate information
each time a field is filled, all at once when all fields have been filled,
or both. In this example on line 18, we simply
play a prompt once the user has made a selection. In the next example, on
lines 34 and 44, we're actually validating the input with conditional statements.
You can view the main example for this edition of VoiceXML Developer here.
To try this example, call VoiceXML Planet at 510-315-6666; press 1 to listen to the demos,
then press 3 to hear this example. This example simulates an E-Commerce application
for Frank's Flute Factory. Frank would like to reduce the costs of his call center
for repeat customers by having them order via an automated system rather than
having to talk to a sales representative. He feels this will reduce his costs
and enable his customers to place orders faster. The example is a prototype
application for his company. The example utilizes the examples we've discussed
previously and introduces a few new elements that we haven't seen yet. These are:
<option>, <if> and <else>, <throw> and <catch>,
and <subdialog>. These new elements will be discussed below.
Use <option> for selection lists within a <form>
The <option> element is similar in
function to the <choice> element. The difference
is that <option> is used inside a <form>
element rather than a <menu> element. When combined with
<enumerate />, our example above provides users with a selection
of flutes that they can buy over the telephone on lines 9 through 22. The prompt
would be, "Please say the type of flute you would like to purchase. cedar. oak.
Processing Input with conditional statements
VoiceXML contains three conditional statements that work together to
provide more control over dialog flow. These are <if>, <else>,
and <elseif>. We can use any variable or field value in the current
dialog or in the root document in these conditional statements. The
<if> element on line 36, which is executed after the user has selected
a flute, checks the type of flute that the user selected. If the flute
is not cedar or maple, the outOfStock event is thrown
with the <throw> element. We can create our own custom events and
handlers through this mechanism. On line 54, the <catch> element,
whose event attribute is set to outOfStock, catches
the event and tells the customer that oak flutes are temporarily out of
stock, and allows the user to select another type of flute with the
<goto> element on line 56.
If the user did select a cedar or maple flute, we assign a prompt string
on line 37 for the confirmPrompt variable, which was declared on line 2,
and is passed to a subdialog on line 43.
Componentizing VoiceXML with <subdialog>
Once the user has provided a valid flute type, a <subdialog>
is called, which asks the user to confirm that they want to purchase
the flute type that the system recognized. The subdialog is called on
line 43 and contains several attributes. The src
attribute specifies the file that contains the VoiceXML for the
subdialog. The name attribute contains the variable
name for the subdialog. Values that are returned from the subdialog
will be accessed using this value. The enctype
attribute identifies the encoding type that will be used for the
HTTP request. This will typically be set to application/x-www-form-urlencoded.
The method attribute defines the HTTP method for submitting
the data. You will typically use either the get or post methods for this
attribute. On line 44, we pass the confirmPrompt variable that was assigned
previously using the <parameter> element. The name
attribute defines the name of the variable as it will be accessed in the
subdialog. The contents of the subdialog, confirm.vxml are listed
The userPrompt variable is declared on line 2. This subdialog asks the
user to confirm that they want to purchase the flute by prompting the
user to press 1 for yes or 2 for no. We utilize the boolean internal
grammar for this purpose, and return the results back with the <return>
element on line 14.
Back in the main example, once the subroutine has been called, we
test the value of the returned value. Because the type was boolean, the
value will be either true or false. If the value is true on line 46,
we thank the user for their order. If the user pressed 2, we cancel
their order and prompt them to select another flute on line 48 inside
In this edition of the VoiceXML Developer, we've seen
some real examples of VoiceXML in action. We're also getting close to finishing
up our tour. We've learned about almost all of the VoiceXML elements! Join
us next time at the VoiceXML Developer, where we'll dive into the world
of voice recognition grammars, the most powerful (and complicated) aspect
of VoiceXML. See you next time.
About Jonathan Eisenzopf
Jonathan is a member of the Ferrum Group, LLC based in Reston, Virginia
that specializes in Voice Web consulting and training. He has also written
articles for other online and print publications including WebReference.com
and WDVL.com. Feel free to send an email to firstname.lastname@example.org regarding
questions or comments about the VoiceXML Developer series, or for more
information about training and consulting services.