2.8. Events

For a voice application to be useful it must respond in real time to user input. VoiceXML models these real-time occurrences as events. Much of this event handling happens automatically - an active grammar is satisfied by user's response, thus causing a form field to be filled. In this situation the VoiceXML programmer doesn't need to explicitly catch the event. It is implicit in the definition of the grammar element and the elements that comprise the form.

The VoiceXML programmer usually needs to worry about events only for exceptional behavior, such as the caller's response not being understood by the speech recognizer, or the caller asking for help. In these situations the VoiceXML programmer may want to "catch" an event - in other words, provide some VoiceXML code that is executed to handle this exceptional occurrence.

In addition to events generated from user actions, the VoiceXML programmer can catch two other types of events:

  • events pertaining to an interpreter error, such as the inability to resolve a URI reference, and

  • events explicitly thrown by the VoiceXML code.

This section will examine these different types of events and demonstrate how to handle these events in VoiceXML.

2.8.1. Events or exceptions?

Readers familiar with object-oriented software design using Java or C++ might find that "events" in VoiceXML aren't an exact fit to these software models. Events in VoiceXML are used sometimes as they are typically used in an event-driven architecture, and at other times, more the way exceptions are used in programming languages like Java and C++.

What is the difference between an event and an exception? They both cause an interruption in the normal sequential flow of a program. Exceptions, however, typically cause the program segment where they occurred to be abandoned, while events do not. For example, if a function f() throws an exception half way through, the remainder of that function does not execute; a "catch block" may be executed, and then whatever code that called function f() will resume. Events, on the other hand, typically cause the program to be temporarily interrupted by some "handler code." Once the handler code completes, the program resumes where it left off.

In fact, VoiceXML events are more like exceptions than events. An event usually causes whatever VoiceXML element that was being executed to be abandoned and an appropriate catch block to be executed instead. However, a VoiceXML programmer can achieve some subtle effects simply by altering the placement and contents of the catch block, as discussed in the next section.

2.8.2. Context sensitive catch blocks

If multiple catch blocks for the same event are visible at the point where the caller triggers the event, the catch block in the most local scope takes precedence. This allows a VoiceXML programmer to create context-sensitive catch blocks that provide ifferent responses based on where the caller is in the dialog.

et us consider the help event, typically triggered by the user saying the word "Help." VoiceXML provides the help element type as a convenient shorthand for eclaring the help catch block. Example 2-50 demonstrates the use of the help element type.

Example 2-50. Using the help element type
<?xml version="1.0" encoding="iso-8859-1"?>
<vxml>

  <form id="test">
    <help>
      <prompt>These questions are meant to challenge you.</prompt>
      <reprompt/>
    </help>

    <field name="sqrtPi" type="number">
      <prompt>What is the square-root of pi?</prompt>
      <filled>
        <prompt>
           You said <value expr="sqrtPi"/> is the square-root of pi.
        </prompt>
      </filled>
    </field>

    <field name="fib100" type="number">
      <help>
        <prompt>
          The hundredth Fibonacci number is the sum of 
          the ninety-ninth and the ninety-eighth Fibonacci numbers.
        </prompt> 
        <reprompt/>
      </help>
      <prompt>What is the hundredth Fibonacci number?</prompt>
      <filled>
        <prompt>
          You said <value expr="fib100"/> is the hundredth 
          Fibonacci number.
        </prompt>
      </filled>
    </field>

    <filled mode="all">
      <prompt> 
        Admittedly, those were very difficult questions.
      </prompt>
      <goto next="index.xml"/>
    </filled>
  </form>
</vxml>

This simple VoiceXML dialog has two fields, sqrtPi and fib100. It also has a form-level help element defined. The contents of this element are executed if the caller says "Help" from anywhere within this form where there isn't another, more locally scoped help element. The fib100 field also has a help element defined. This help will take precedence over the form-level help if the caller says "Help" while within the fib100 field.

The form-level help simply plays the message "These uestions are meant to challenge you" and instructs the VoiceXML interpreter to continue with the next unanswered prompt in the form, as specified by the reprompt element. The fib100 field-level help is identical, except it plays the message "The hundredth Fibonacci number is the sum of the ninety-ninth and the ninety-eighth Fibonacci numbers" instead.

The example scenario in Example 2-51 demonstrates he behavior of this VoiceXML dialog.

Example 2-51. Possible dialog resulting from the document in Example 2-50
IVR     : What is the square root of pi?
Caller  : Help.
IVR     : These questions are meant to challenge you.
          What is the square root of pi?
Caller  : 10.
IVR     : You said 10 is the square-root of pi. 
          What is the hundredth Fibonacci number?
Caller  : Help. 
IVR     : The hundredth Fibonacci number is the sum of
          the ninety-ninth and the ninety-eighth Fibonacci numbers.
          What is the hundredth Fibonacci number?
Caller  : 1,000.
IVR     : You said 1,000 is the hundredth Fibonacci number.
          Admittedly, those were very difficult questions.

The first time the caller says "Help," the VoiceXML interpreter is in the sqrtPi field element. The only help element in the field's scope is the form-level help, so the VoiceXML interpreter abandons the execution of the sqrtPi field and executes the contents of the help. In this case it plays a message and reprompts - in other words, instructs the VoiceXML interpreter to continue executing the current form.

When the caller says "Help" the second time, the VoiceXML interpreter is in the fib100 field element, so the field-level help is chosen over (i.e. shadows) the form-level help because it is in the more local scope.

It is important to note that the VoiceXML interpreter does not "pop the stack" before executing the contents of a catch block. That is to say, if the help were declared outside of (i.e. above) the form, it would not execute the contents of the help from the document scope, but rather from the field scope - the scope in which the event was detected. This is a subtle point, and as such it may not be observed by all VoiceXML interpreter implementers.

One last compliance wrinkle to consider is what would happen if the caller said "Help" while the VoiceXML interpreter was saying "Admittedly, those were very difficult questions." Since this speech is being generated by the form-level filled block, the VoiceXML Specification would seem to dictate that the form-level help catches this event.

In fact, many interpreters (e.g. TellMe) will instead let either the document- or application-level help catch this event, if defined. The logic is obvious: if the caller is already in the filled, the form has been completed and therefore, the caller no longer needs form-level help. There is a caveat, however: if the filled block concludes with a submit element posting the form data up to a Web server, that submit may never be executed since the high-level help block may never return control back to the filled block.

2.8.3. Caller-driven events

VoiceXML provides the catch element type as a generic way to handle any event. The type of event that a catch is supposed to catch is specified with the event attribute. The following is a summary of common events that you might need to catch:

help

The caller says "Help" or presses a DTMF key associated with a help function. This event can also be caught using the shorthand help element type.

noinput

The caller fails to answer a question in the time allotted. This event can also be caught using the shorthand noinput element type.

nomatch

The caller answers a question but the answer does not match any active grammars. This event can also be caught using theshorthand nomatch element type.

cancel

The caller attempts to "barge-in" on, and thus cancel, the playing of a prompt.

exit

The caller has asked to exit the system.

maxspeechtimeout

The user's response was too long.

telephone.disconnect.hangup

The caller has hung up his or her phone disconnecting the call.

telephone.disconnect.transfer

The caller was transferred to another line and will not continue with this dialog.

A VoiceXML programmer can catch any of these events using a catch element to provide the desired behavior.

2.8.4. Interpreter events

In addition to events generated by the caller, the VoiceXML interpreter can also generate events reflecting some error conditions encountered while interpreting a VoiceXML application. These events are caught, like any other events, using a catch element:

<catch event="error"> ...catch block... </catch>

This will catch any interpreter event. A synonymous way of writing this is simply:

<error> ...catch block... </error>

You can be more specific by catching only a subset of events:

<catch event="error.badfetch"> ...catch block... </catch>

The contents of this catch element will only be executed in the instance where the VoiceXML interpreter was unable to fetch a resource from an HTTP server. The following is a list of the error "subevents":

error.badfetch[.protocol.responseCode]

The error.badfetch event indicates the VoiceXML interpreter was unable to retrieve a resource it needed. An error.badfetch event typically occurs when the interpreter encounters, for example, such an element in a VoiceXML application:

<goto next="http://www.somecompany.com/welcome.xml" />

and upon requesting the file welcome.xml the HTTP server responded with "404 Document not found." Additionally, if welcome.xml was found but was not well-formed XML, this would also generate an error.badfetch event.

One can go so far as to restrict the catching of badfetch error events to a particular protocol and a particular error message, for example:

<catch event="error.badfetch.HTTP.404">
  The document you requested could not be found on the server.
</catch>

error.semantic

The error.semantic event indicates that there was a run-time error. This could be the result of an error interpreting ECMAScript code, for example, attempting to reference an undefined variable or to divide a number by zero.

error.noauthorization

The error.noauthorization event indicates that the underlying implementation disallowed some action attempted by the VoiceXML application. For example, a VoiceXML hosting company might not permit their developers to use a transfer element to make a long-distance phone call.

error.unsupported.format

The error.unsupported.format event indicates that the VoiceXML interpreter retrieved some resource, such as an audio file or a grammar file, but could not read the format. For example, a VoiceXML interpreter may only support the Dialogic .vox audio file format. The tag <audiosrc="welcome.mp3"/> would then result in an error.unsupported.format event being thrown.

error.unsupported.element

The error.unsupported.element event indicates that the VoiceXML interpreter does not implement the entire VoiceXML Specification, and therefore does not support some of the element types of the VoiceXML language.

2.8.5. Conditional catching

Using a catch element allows the VoiceXML author to provide different responses for multiple occurrences of the same event. Let's consider an example where a VoiceXML application needs to collect the caller's five digit identification number (Example 2-52).

Example 2-52. A dialog that may result from the document in Example 2-53
IVR     : Please say your identification number.
Caller  : seven - seven - five.
IVR     : I'm sorry, that is not a valid identification number. 
          Please say your identification number.
Caller  : seven - seven - nine.
IVR     : Your identification number should be a five digit number. 
          Please say your identification number.
Caller  : seven - four - three - one.
IVR     : I'm sorry. That is still not a valid identification 
          number. Let me connect you with a customer service 
          representative.

In this example, the caller repeatedly fails to enter a five digit identification number. Rather than simply repeat the same error message ad infinitum, a VoiceXML application can provide different catch behavior depending on how many times a particular form item generated a given event. The VoiceXML document for the dialog in Example 2-52 is shown in Example 2-53.

Example 2-53. Providing different catch behavior based on count
<?xml version="1.0" encoding="iso-8859-1"?>
<vxml>

  <form id="test">
    <block>Hello</block>

    <field name="custID" type="digits?minlength=5;maxlength=5">
      <prompt> Please key in your identification number.</prompt>

      <nomatch count="1">
        I'm sorry, that is not a valid identification number. 
        <reprompt/>
      </nomatch>

      <nomatch count="2">
        Your identification number should be a five digit number.
        <reprompt/>
      </nomatch>

      <nomatch count="3">
        I'm sorry. That is still not a valid identification number. 
        Let me connect you with a customer service representative.
        <goto next="#custrep"/>
      </nomatch>

      <filled> Got it: <value expr="custID"/>
      </filled>

    </field>
  </form>

  <form id="custrep">
    <block>Transferring you now</block>
    <transfer name="xfer" dest="18005551212"/>
  </form>  
</vxml>

The test form has a single field, custID. This field contains three nomatch elements, each with a different value for the count attribute. The first time the custID field generates a nomatch event, the nomatch count for that field will be set to 1 and the <nomatch count="1"> element will be the best candidate for handling this event. That catch block plays a message for the user, then instructs the interpreter to try executing the form again.

The second time the caller gets it wrong, the nomatch count for this field is set to 2 and the <nomatch count="2"> element is now the best candidate for handling this event. Again, this catch block plays another message and repromts. The third time the caller makes a mistake, this application exits the form and proceeds to the custrep form, thus not giving the user any more chances.

If you rewrite the <nomatch count="3"> element as follows:

<nomatch count="3">
  Sorry, still wrong.
  <reprompt/>
</nomatch>

then another failed attempt to answer the question will again result in a nomatch event, but now with the nomatch count for this field set to 4. In this case the <nomatch count="3"> element is still the best candidate, as it has the highest count provided.

Let's assume that we want to use this "Sorry, still wrong" handler if there is no customer service representative currently available, and use the "Let me transfer you..." handler if a representative is available. Let's also assume that our VoiceXML interpreter provides information about the availability of a customer service representative by setting the ECMAScript variable custSvcRepAvailable to true if one is available and false otherwise. (Note that this assumption implies that the VoiceXML Interpreter platform has been tightly integrated with some call center infrastructure. Such scenarios will be covered in greater detail in Chapter 4, “Enterprise voice application architecture,” on page 308.)

For this, we can use another feature of the catch element type: the cond attribute. This attribute allows the VoiceXML author to provide an ECMAScript expression that, if it evaluates to true, activates the catch handler, otherwise deactivates the handler. Using this attribute along with the assumption of the custSvcRepAvailable feature, we can achieve our goals as shown in Example 2-54.

Example 2-54. Controlling nomatch visit logic
<nomatch count="3" cond="custSvcRepAvailable==true">
  I'm sorry. That is still not a valid identification number. 
  Let me connect you with a customer service representative.
  <goto next="#custrep"/>
</nomatch>

<nomatch count="3" cond="custSvcRepAvailable==false">
  Sorry, still wrong.
  <reprompt/>
</nomatch>

The VoiceXML interpreter will only choose the first nomatch if the nomatch count for this field is 3 or more and the custSvcRepAvailable variable is set to true. If this variable were set to false, the second nomatch would become the best candidate.

2.8.6. Document links

A document link associates a grammar with a destination VoiceXML document. When the caller says some word that is recognized by the grammar, the VoiceXML interpreter will abandon the execution of the current document and load the destination document associated with the link. Example 2-55 demonstrates using links.

Example 2-55. Using the link element
<?xml version="1.0" encoding="iso-8859-1"?>
<vxml>
  <link next="index.xml">
    <grammar mode="voice">menu</grammar>
  </link>

  <form id="boring">
    <block> This is a long long long long long
            very very very very boring dialog. 
            It is so boring because
            it simply repeats and repeats and repeats and repeats. 
    </block>
    <block> <goto next="#boring"/> </block>
  </form>
</vxml>

The link element in the document context instructs the VoiceXML interpreter to listen for the word "menu," as specified by the grammar element within link. When the interpreter hears "menu" it will abandon the current page and jump to index.xml.

Links, like catch blocks, are context sensitive. The link will only be active when it is in scope and no other link with similar grammar is in a more local scope. It is important, however, to keep in mind that the speech recognizer is turned on and listening for a link's grammar for as long as the link is in scope. This could cause some confusion if a part of the caller's answer to a question also matches a link's grammar.

In addition to "going somewhere," a link element can also throw an event upon its grammar being recognized. This functionality is discussed in Chapter 3, “VoiceXML language reference,” on page 136.

..................Content has been hidden....................

You can't read the all page of ebook, please click here login for view all page.
Reset
3.22.249.220