VoiceXML Developer Series: A Tour Through VoiceXML, Part IV

Friday Oct 4th 2002 by Jonathan Eisenzopf
Share:

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!
Operator: help
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!
Operator: soda
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 9.

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 dialog.

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 for instructions".

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 <field> 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.

Example 3

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. maple".

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 here.

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 the <else>.

Conclusion

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 eisen@ferrumgroup.com regarding questions or comments about the VoiceXML Developer series, or for more information about training and consulting services.

Share:
Home
Mobile Site | Full Site
Copyright 2017 © QuinStreet Inc. All Rights Reserved