CallXML 3.0 Development Guide Home  |  Frameset Home


<on>  element


The new <on> element replaces the deprecated <on(EVENTNAME)> handlers from CallXML2.0, and is compliant to the XML events specification, (http://www.w3.org/TR/2003/REC-xml-events-20031014/).
This also provides the developer with a cleaner, and more modular syntactic shorthand for the following CallXML2.0 elements:



The syntax for the <on> element replaces the above elements when used in the following format:

<on event="event:value">

As such, the following expressions are in fact, identical:

CallXML2.0
<ontermdigit value="#">

CallXML3.0
<on event="termdigit:#">

The <on> element can also be used to trap user-defined events that are kicked off when using the new <throw> element:

<throw event="myEvent">
..
<on event="myEvent">
<!-- do something here -->
</on>





usage

<on event="(event type)" foreach="(comma delimited list of array values)" next="(navigation identifier)" target="(element id)" test="CDATA">


attributes

event Data Type: (event type) Default: none - attribute is required
The 'event' attribute is used in conjunction with the <on> handler to specify the specific event name that we wish to filter. Using a generic handler, where we specify the exact condition to catch is much less cumbersome than the CallXML2.0 event handling scheme, where we had to define the correct element name of the event to catch.

The standard syntax for this new method of simple event handling is as follows:
  • <on event ="answer">
  • <on event ="callfailure">
  • <on event ="error">
  • <on event ="externalevent:user_event_name">
  • <on event="externalevent:busy">
  • <on event ="hangup">
  • <on event ="maxdigits">
  • <on event ="maxtime">
  • <on event ="maxsilence">
  • <on event ="user_event_name">
  • <on event ="choice:grammar_match">
  • <on event ="choice:nomatch">
  • <on event ="termdigit:#">
  • <on event ="cparesult:human">
foreach Data Type: (comma delimited list of array values) Default: Optional
The 'foreach' attribute, usable on any CallXML3.0 container elements, should look familiar to many web developers. A developer can indicate a comma-delimited array of values to iterate through within 'foreach' attribute, and then use the 'var' attribute to specify the variable that will hold the current iteration value while in the enclosing container element.

Alternatively, 'foreach' uses the "container.value" variable to store the current iteration if the 'var' is unspecified.  and "container.value" will populate any unspecified 'value' attributes of  child elements of the container in question.
next Data Type: (navigation identifier) Default: none - attribute is optional
The 'next' attribute sets the URL the CallXML platform will go to when the container ends.
target Data Type: (element id) Default: none - attribute is optional
The 'target' attribute is another new enhancement to the restructured <on> element that permits the developer to specify what elements a handler can accept events from. At a code level, this means that we can include, or exclude events from a specific handler on a per-case basis, thereby allowing fine-grained control over the event handling schema within the application.
test Data Type: CDATA Default: Optional
The 'test' attribute is a new supplement to the CallXML markup that permits the developer to execute the contents of a container element, or action element, based on whether or not the specified condition is met. If the defined condition is met, then the code contained within the element is then executed. If the condition is not met, then the application resumes execution with the next sequential container container element in the document.



code samples

<3.0 on-event>
<?xml version="1.0" encoding="UTF-8"?>

<callxml version="3.0">

  <do label="B1">


    <prompt choices="1">
      Press one now.
      Or press 2.
      Or hang up.
      Or dont press anything at all.
    </prompt>

    <getdigits var="Var_1" maxtime="3s"/>

  <on event="choice:1">
    <prompt value="you pressed 1"/>
  </on>

  <on event="nomatch">
    <prompt value="That isn't a valid selection"/>
  </on>


  <on event="maxtime">
    <prompt value="you didnt press anything"/>

  </on>

  <on event="hangup">
    <log> *** USER HUNG UP ***</log>
  </on>

  </do>

</callxml>



<3.0 on-target>
<?xml version="1.0" encoding="UTF-8"?>

<callxml version="3.0">

  <do label="B1" choices="jack tripper, mister roper, chissy">


    <say id="P1">
      Who is your favorite member of the smash TV hit 'Threes Company'?
    </say>

    <say id="P2">
      You have the option to choose any of these characters.
    </say>

    <say id="P3">
      jack tripper, mister roper, or chrissy.
    </say>

    <say id="P4">
    but you really should choose jack tripper, if you are smart.
    </say>

  <on event="choice:jack tripper" target="P1">
    <log> *** RECO EVENT OCCURRED WITHIN P1 ***</log>
    <say>
      Jack is pretending to be gay so he can live with two hot girls.
    </say>
  </on>

  <on event="choice:jack tripper" target="P2">
    <log> *** RECO EVENT OCCURRED WITHIN P2 ***</log>
    <say>
      Jack is pretending to be gay so he can live with two hot girls.
    </say>
  </on>

  <on event="choice:jack tripper" target="P3">
    <log> *** RECO EVENT OCCURRED WITHIN P3 ***</log>
    <say>
      Jack is pretending to be gay so he can live with two hot girls.
      However, he is a little bit too convincing....
    </say>
  </on>

  <on event="choice:jack tripper" target="P4">
    <log> *** RECO EVENT OCCURRED WITHIN P4 ***</log>
    <say>
      Jack is pretending to be gay so he can live with two hot girls.
    </say>
  </on>

  <on event="choice:mister roper">
    <say>
    mister roper is clueless to jack trippers heterosexuality.
    </say>
  </on>

  <on event="choice:chrissy">
    <say>
    chrissy is a bombshell.
    </say>
  </on>

  </do>

</callxml>



<3.0 on-test>
<?xml version="1.0" encoding="UTF-8"?>

<callxml version="3.0">

  <do label="D1">
 
  <assign var="MycallerID" value="session.callerID"/>

  <prompt value="I bet you would like to hang up now, wouldn't you"/>
 
  <wait value="20s"/>

  <on event="hangup" test="1 = 2">
    <log> *** THIS WILL NOT EXECUTE, AS 1 IS -NOT- EQUAL TO 2 ***</log>
  </on>

  <on event="hangup" test="'$MycallerID;' = '$MycallerID;'">
    <log> *** THIS CAN EXECUTE, AS MycallerID IS EQUAL TO callerID ***</log>
  </on>


  <on event="hangup" test="1 =1 ">
    <log> *** THIS CAN EXECUTE, AS 1 -IS- EQUAL TO 1 ***</log>
  </on>

  <on event="hangup" test="&apos;one&apos;= &apos;one&apos;">
    <log> *** THIS CAN EXECUTE, AS 'one' -IS- EQUAL TO 'one' ***</log>
  </on>

  <on event="hangup" test="6 != 9">
    <log> *** THIS CAN EXECUTE, AS 'one' -IS- EQUAL TO 'one' ***</log>
  </on>

  <on event="hangup" test="anyString">
    <log> *** THIS CAN EXECUTE, AS THIS IS A NON-EMPTY STRING ***</log>
  </on>

  </do>

</callxml>



<3.0 FetchAudioParent.xml> - masking long fetches
<?xml version="1.0" encoding="UTF-8" ?>
<callxml version="3.0">
<!-- sometimes, we want to 'mask' the fetch of a large document -->
<!-- by playing audio during the fetch.-->
<!-- To do so, we will use a parent+child architecture, -->
<!-- and make use of the new '$session.eventvalue;' session variable-->


<assign var="parentSessionID" value="$session.ID;"/>

  <do label="D_0">
    <log>*** STARTING THE PARENT SESSION ***</log> 
    <run value="FetchAudioChild.xml" submit="*" method="get"
            var="timerSessionID" />

    <playaudio format="audio/wav"
              value="Spidey.wav"/>

    <on event="externalevent">
    <log>*** WITHIN THE PARENT AGAIN ***</log>
    <log>*** LIST SLASHDOT:  $session.eventvalue; ***</log>
    </on>

  </do>

</callxml>


<3.0 FetchAudioChild.xml>
<?xml version="1.0" encoding="UTF-8" ?>
<callxml version="3.0">

<!--  grab the RSS newsfeed, which will take a few  -->
<!-- seconds to fetch -->
<fetch value="http://slashdot.org/index.rss" var="SlashDotNews" />


<with label="Assign" value="$SlashDotNews;">
  <sendevent session="$parentSessionID;"/>
</with>

</callxml>



additional links

none


  ANNOTATIONS: EXISTING POSTS
esirkin
5/18/2007 2:46 AM (EDT)
In your examples you show use of <on event="maxtime"> as well as in examples in <recordaudio>.  But this event is not listed in your list of possible events in your documentation on this page.  A small nit, but could confuse the patients.

eric
jbassett
5/18/2007 6:55 AM (EDT)
Hello,

You are correct. Good catch. I will go ahead and forward this on so we can get it properly added.

Thanks
Jesse Bassett
Voxeo Support
jpw
1/19/2008 6:50 PM (EST)
so, it's been like 6 months. maxtime is still not listed. is maxtime legitimate? and if so, what's the difference in maxtime and maxsilence? Your reply to the previous customer from 200 days ago isn;t clear -- is the "good catch" that maxtime is wrong, or that it's not listed in the documentation?
voxeojeff
1/20/2008 11:14 AM (EST)
Jpw,

According to Jesse's last posting here, the fact that he mentions that maxtime should be added indicates that it is indeed a valid event.  As for maxtime vs. maxsilence, maxtime is used as a measuring stick to determine human vs. machine (cpa).  Maxsilence is used to determine the end of voice activity.

http://docs.voxeo.com/callxml/3.0/ansdetection_cxml30.htm

Regards,

Jeff
jpw
1/24/2008 8:07 PM (EST)
is the next= any different from putting a <goto> at the end of the <on> handler?

Also, does the next= have to be a url, or can it be a local label inside the same document?
VoxeoDustin
1/24/2008 9:28 PM (EST)
Hey JP,

The next attribute is pretty much the same as using a goto. When using next it will process the entire contents of the <on> handler, then go to the next document or block. You can transition through blocks by prefacing the block name with # in the next= attribute:
  <on event="choice:1" next="#B1">
    <prompt value="you pressed 1"/>
  </on>

Note that, like goto, it will only transition to blocks in the same scope or the root scope.
zoop
3/11/2008 11:02 PM (EDT)
I need a little more assistance with the on event=external  I'm just converting some callxml 2.0 code to 3.0 and looks like I'm missing something.  I currently have something like this.


file1

<sendevent value="Ididsomething" session="$parentsession;"/>

file2

<onexternalevent value="Ididsomething" next="#someblock"/>

From looking at the example aove it doesn't appear to have a way to identify the "value"  I see the with tag on the sendevent  But how does the new <on> handle this?

Thanks.
VoxeoDustin
3/11/2008 11:21 PM (EDT)
Hey zoop,

You can access the value of the event like so:
[code]
    <sendevent id="myEvent" value="foo" session="$parentSessionID;"/>



    <on event="externalevent:myEvent">
    <log>*** WITHIN THE PARENT AGAIN ***</log>
    <log>*** LIST SLASHDOT:  $session.eventvalue; ***</log>
    </on>
[/code]

Thanks,
Dustin
zoop
3/17/2008 12:21 AM (EDT)
Ok got another one for you.  In Callxml 2.0 we had <onerror type="xxxxx">  in 3.0 is this now to be <on event="error:xxxx"> ?  I don't see it documented well on this page.
voxeojeff
3/17/2008 9:36 AM (EDT)
Hello zoop,

Yes, you are correct.  Specifying <on event="error:errorname"> will work.  For example, lets say you specify a playaudio URL which does not exist.  This results in a 404 error, and generates an event: error "telephony" (server error 404).  The following handler will catch it:
[code]
  <on event="error:telephony">
    <say> there was an error! </say>
    <log> *** ERROR *** </say>
  </on>
[/code]

You can also make it a global error handler, by just specifying <on event="error">.

Hope this helps,

Jeff
zoop
3/18/2008 7:00 PM (EDT)
Here is how it's done.

Document1 has:

<on event="externalevent:SOMEID"/>

Document2 sending to document1

<sendevent value="SOMEID" session="DOCUMENT1SESSIONID"/>


Finally had time to test it out and see how to make it go.

thanks for the help.
mdesgiw
4/18/2008 12:41 PM (EDT)
Anybody know why this doesn't work?  If we receive audio and it doesn't match any of our choices, we want to play the introductory message again and wait for user input.

<on event="choice:nomatch" target="B1">
  <say choices="9">No Match.</say>
</on>

We test the above and can never get a "nomatch" condition for some reason.
VoxeoDustin
4/18/2008 3:10 PM (EDT)
Hey,

Would you mind opening an account ticket with the relevant code and debugger output? Once we have this info in hand we'll have a better idea of why this is failing for you.

Thanks,
Dustin
mdesgiw
5/18/2008 7:25 PM (EDT)
Should I care about the following debugger output? 
I have a "on event=hangup" code block that seems to to get executed, but when I test hanging up on an outgoing call, the debugger still complains thusly:

>>>event: error "linenotactive" (there is no active phone line to execute the action)
>>>event: error "document" (unhandled event "event="onerror", event="", type="linenotactive"")
>>>end of session

My "on event=hangup" code is simply this:
<on event="hangup">
  <log>*** User hung up (page2.xml) ***</log>
  <hangup/>
  <exit/>
</on>

Presumably the "end of session" that the debugger reports is because of my "<exit/>" and "<hangup/>" commands, yes?

Why does the debugger still insists  on showing that a "error:linenotactive" (I assume that would be the syntax) event was raised and not handled by my code?

I have tried to capture this event in the following ways.  None of these "on" events captures the "linenotactive" event.  What's up with that?

<on event="error:linenotactive">
  <log value="*** LINE NOT ACTIVE (error:linenotactive) ***" />
  <hangup/>
  <exit/>
</on>
<on event="document:linenotactive">
  <log value="*** LINE NOT ACTIVE (document:linenotactive) ***" />
  <hangup/>
  <exit/>
</on>
<on event="onerror:linenotactive">
  <log value="*** LINE NOT ACTIVE (onerror:linenotactive) ***" />
  <hangup/>
  <exit/>
</on>
<on event=":linenotactive">
  <log value="*** LINE NOT ACTIVE (:linenotactive) ***" />
  <hangup/>
  <exit/>
</on>

If for any reason the line goes dead during an outbound call, how best to capture and handle that event?

Thanks,
Marc
voxeojeff
5/18/2008 10:23 PM (EDT)
Hi Marc,

It's quite possible that you are trying to hang up a line which has already hung up, thus resulting in this error.  If that's the case, then there is no cause for alarm here.  However, to be sure... please go ahead and send us a complete debugger log illustrating this error so that we may examine it for you.  To do so,

1) Open the debugger window, (Account => Application Debugger)
2) Call the application, and reproduce the error
3) Click the 'support' tab in the debugger, give a short description of the issue, and click on submit.

Thanks,

Jeff
mdesgiw
5/19/2008 12:10 PM (EDT)
OK, so you think maybe one of my <hangup>s occurs after the line is already released?

Here's the log file.  My <log> statement is executing, showing that the onhangup event fired and then I get the "linenotactive" message. 

Sounds like the line *is* already dead, but "linenotactive" is not in your docs.  Shouldn't I be able to trap for that and respond accordingly?  Using "error:linenotactive" appears to do nothing in an "on" event...

Here's the log for an outgoing call for which I physically hung up when my prompts started playing:

(note: actual domain name changed to "myserver" in the log below...)

00067 1ead 02:42:56 AM event: answer
00068 1ead 02:42:56 AM action: begin value=""
00069 1ead 02:42:56 AM BEGIN BLOCK: Label="MessageBlock" Value="" Next=""
00070 1ead 02:42:56 AM action: text "hello Marc" format="" termdigits="" choices="" cleardigits=0
00071 1ead 02:42:57 AM Log: *** going to xfer.xml#B1... ***
00072 1ead 02:42:57 AM now going to http://myserver.com/ivrlib/xfer.xml [click on link for full URL]
00073 1ead 02:42:57 AM action: goto value="http://myserver.com/ivrlib/xfer.xml#B1
Submit (method="GET" cache=""):
00075 1ead 02:42:57 AM document loaded: parsing click link to view
00076 1ead 02:42:57 AM action: begin value=""
00077 1ead 02:42:57 AM BEGIN BLOCK: Label="block___1___" Value="" Next=""
00078 1ead 02:42:57 AM action: begin value="ON"
00079 1ead 02:42:57 AM BEGIN BLOCK: Label="B1" Value="ON" Next=""
00080 1ead 02:42:57 AM SRE stopped
00081 1ead 02:42:57 AM Log: ExpertMode=ON
00082 1ead 02:42:57 AM action: text "time to respond. press five or say YES to confirm. ..." cleardigits=0...
00083 1ead 02:43:00 AM event: hangup
00084 1ead 02:43:00 AM action: begin value="ON"
00085 1ead 02:43:00 AM BEGIN BLOCK: Label="block___16___" Value="ON" Next=""
00086 1ead 02:43:00 AM Log: *** User hung up (xfer.xml) ***
00087 1ead 02:43:00 AM event: error "linenotactive" (there is no active phone line to execute the action)
00088 1ead 02:43:00 AM event: error "document" (unhandled event "event="onerror", event="", type="linenotactive"")
00089 1ead 02:43:00 AM end of session

VoxeoDustin
5/19/2008 12:19 PM (EDT)
Hey Marc,

Jeff is correct that the hangup handler is at fault:

<on event="hangup">
  <log>*** User hung up (page2.xml) ***</log>
  <hangup/>
  <exit/>
</on>

Will cause an issue because we've already hungup. Simply removing the <hangup/> should resolve the linenotactive error.

You can catch this error by implementing:

<on event="error:document">
  <!-- on -->
</on>

Do note, that in most cases, you will not want to issue a hangup in an error handler, but an exit, which will implicitly disconnect the call leg. In the case of any fatal error, the call leg will already be disconnected, so reissuing a hangup during the error handler will simply throw another error - not good. ;)

Let me know if you have further questions.

Cheers,
Dustin
pdeschen
11/2/2009 5:15 PM (EST)
Hello,

Unless I have missed something, test <3.0 on-test> does seems to work properly. And that would explain the behavior in my own application.

If the first event handler matching a specific event does not have a valid "test" (i.e. test expresion returning false), then all other handler for that event are simply ignored.

I d like to have some more clarification on that.

Thanks

MattHenry
11/2/2009 5:28 PM (EST)


Hi there,

To be clear, the expected behavior for the <on> handler with a "test" attribute defined could be illustrated by the following code snippet:


<block>
  <assign var="V1" value="'foo'"/>
  <throw event="myEvent"/>
 
  <on event="myEvent">
  <log>*** THIS WILL BE EXECUTED ***</log>
  </on>

  <on event="myEvent" test="'$V1;' != 'bar'">
  <log>*** THIS WONT BE EXECUTED ***</log>
  </on>

  <on event="myEvent" test="'$V1;' = 'foo'">
  <log>*** THIS WONT BE EXECUTED ***</log>
  </on>

</block>


Bear in mind that once a valid event handler is found for an event, we can hardly execute other handlers for the same event: CallXML's order of operations uses a top-down model, and with the above code, the first handler meets the criteria to handle the thrown event, and this handler is expected to do something: Throw another event, <goto> another container element, or whatever. Does this help to clarify, or have I misunderstood the question?


~Matt
pdeschen
11/2/2009 5:51 PM (EST)
Matt,

Alright. But how would you explain the following documentation example found above:

<callxml version="3.0">
  <do label="D1">
  <assign var="MycallerID" value="session.callerID"/>
  <prompt value="I bet you would like to hang up now, wouldn't you"/>
  <wait value="20s"/>
  <on event="hangup" test="1 = 2">
    <log> *** THIS WILL NOT EXECUTE, AS 1 IS -NOT- EQUAL TO 2 ***</log>
  </on>
  <on event="hangup" test="'$MycallerID;' = '$MycallerID;'">
    <log> *** THIS CAN EXECUTE, AS MycallerID IS EQUAL TO callerID ***</log>
  </on>
  <on event="hangup" test="1 =1 ">
    <log> *** THIS CAN EXECUTE, AS 1 -IS- EQUAL TO 1 ***</log>
  </on>
  <on event="hangup" test="'one'= 'one'">
    <log> *** THIS CAN EXECUTE, AS 'one' -IS- EQUAL TO 'one' ***</log>
  </on>
  <on event="hangup" test="6 != 9">
    <log> *** THIS CAN EXECUTE, AS 'one' -IS- EQUAL TO 'one' ***</log>
  </on>
  <on event="hangup" test="anyString">
    <log> *** THIS CAN EXECUTE, AS THIS IS A NON-EMPTY STRING ***</log>
  </on>
  </do>
</callxml>

In that case, no handler will be executed. My understanding would be that the first handler matching the event AND which test attribute condition returns true would be executed.

MattHenry
11/2/2009 8:58 PM (EST)


Hi again,

I'd think that in this scenario, the following handler would execute upon hangup, as it is the first one listed that would match the criteria:

  <on event="hangup" test="'$MycallerID;' = '$MycallerID;'">
    <log> *** THIS CAN EXECUTE, AS MycallerID IS EQUAL TO callerID ***</log>
  </on>

While the others *can* execute in the sense that they are valid handlers whose "test" criteria evaluate to "true", these are considered secondary & tertiary handlers for the purposes of this code snippet: Although I can understand how this might imply multiple handlers for the same event might execute, this snippet was simply intended o illustrate different operators for the "test" equation such as "not-equal-to", number comparisons, string comparisons, etc.


Cheers,

~Matthew Henry
pdeschen
11/2/2009 10:24 PM (EST)
Matt,

Thanks for the quick response. That was all my point and my understanding, that is, the second handler should trigger. Unfortunately, that's not the case: the second handler does NOT execute...

Just try it out.

Thanks
VoxeoTony
11/3/2009 1:04 AM (EST)
Hello,

I see what you mean by the example, and how it handles the call hang up.  It does in fact hit the first on event and process in a first come, first serve structure.  So in the sample the extra events will not be used.  However, this example also showcases different examples of tests that can be run using the test attribute.  It's just a matter of making sure our readers know that the intent of this document example.

You mention in your post that you are using this example as a structure for your own application.  If you wish to explore this further I would recommend opening an account ticket to ensure further privacy with regards to your own applications.


@Tony

login



© 2012 Voxeo Corporation  |  Voxeo IVR  |  VoiceXML & CCXML IVR Developer Site