| CCXML 1.0-W3C Development Guide | Home | Frameset Home |
|
<foreach> element to manipulate user-Objects, and the Connection Object using the JavaScript Object Notation extensions to the Voxeo platform...take it from us, JSON is really, really cool to work with, and easy, too! In addition, this tutorial will illustrate how a developer can use the <send> tag to asynchonously send an event to a webserver, and receive data back from the request: This last has been a rather common "how do I do this?" question amongst our developer community, and when you ask, we listen, baby! Be fully advised that this tutorial is not at all meant to be attempted by developers who are unfamiliar with the basic concepts outlined in our previous tutorials: If you have not gone through these preceding lessons on CCXML 1.0, then chances are that a lot of the concepts that we cover in this tutorial will be foreign to you, and will likely result in no small amount of confusion.<script> element<foreach> element to loop through the property values of an Object<send> to fire off an asynchronous notification to an external webserver<eventprocessor> to enclose all of our <transition> elements. We won't bore you with the simple stuff this time, as you should be familiar with this by now. Instead, let's start out by looking at the <script> that is going to declare our user Object that we will be using later:
<?xml version="1.0" encoding="UTF-8"?>
<ccxml version="1.0" xmlns:voxeo="http://community.voxeo.com/xmlns/ccxml">
<script>
<![CDATA[
//create and object that has a string, an array, and an object>
var myObject = new Object();
//manually assign property values to our user Object
myObject.v1 = 'value_1';
myObject.v2 = 'value_2';
//declare an empty user Array
myObject.Arr = new Array();
//assign values to the [0] and [1] positions of the Array
myObject.Arr.push('array_value_1');
myObject.Arr.push('array_value_2');
//assign a sub-object value to our existing object
myObject.Obj = new Object();
myObject.Obj.Prop = 5;
]]>
</script>
<eventprocessor>
</eventprocessor>
</ccxml>
<script> element, and do so at the very top of our CCXML 1.0 document so that our Object values will be scoped document-wide: If we declared them within any given <transition>, then the next <transition> that executes would not be able to access these values that we have so carefully set. Note that any declared variable, Object, or Array that we create within the <script> tag will be accessible directly within the CCXML 1.0 context. To illustrate, both of these variable declarations are essentially identical:
<script>
var myVar ='foo';
</script>
<var name="myVar" expr="'foo'"/>
<transition> elements that we have become accustomed to, and throw in some <log> statements that are going to output some "raw" values for us. Nothing that you see here should be too shocking and new to you, but just you wait, we get all kinds of fancy later on.
<?xml version="1.0" encoding="UTF-8"?>
<ccxml version="1.0" xmlns:voxeo="http://community.voxeo.com/xmlns/ccxml">
<script>
<![CDATA[
var myObject = new Object();
myObject.v1 = 'value_1';
myObject.v2 = 'value_2';
myObject.Arr = new Array();
myObject.Arr.push('hello');
myObject.Arr.push('world');
myObject.Obj = new Object();
myObject.Obj.Prop = 5;
]]>
</script>
<eventprocessor>
<transition event="connection.alerting">
<accept/>
<log expr="'***** MYOBJECT = ' + myObject"/>
</transition>
<transition event="connection.connected">
<log expr="'*** Call was accepted ***'"/>
</transition>
<transition event="connection.disconnected">
<log expr="'*** Call was disconnected ***'"/>
<exit/>
</transition>
<transition event="error.*">
<log expr="'an error has occured (' + event$.reason + ')'"/>
<log expr="'*** EVENT$.NAME = ' + event$.name"/>
<log expr="'*** EVENT$.REASON = ' + event$.reason"/>
<log expr="'*** EVENT$.TAGNAME = ' + event$.tagname"/>
<log expr="'*** EVENT$.EVENTID = ' + event$.eventid"/>
<log expr="'*** EVENT$.EVENTSOURCE = ' + event$.eventsource"/>
<log expr="'*** EVENT$.EVENTSOURCETYPE = ' + event$.eventsourcetype"/>
<voxeo:sendemail to="'youremail@somewhere.com'"
from="'myApp@here.com'"
type="'debug'"
body="'We had an error! \n Time to panic! \n
Flee the cities, abandon all hope!'"/>
<exit/>
</transition>
</eventprocessor>
</ccxml>
<transition> elements we added for the "connection.alerting", "connection.connected", and our all-purpose error handler for "error.*" are all familiar ground for us here. But if we run the code as-is, our newly-added <log> statement doesn't give us any useful data at all:
log: ***** MYOBJECT = [object Object]
<foreach> element. Before we dig too deep into this, let's take a moment and explore an available Object that we don't have to even declare at all: The CCXML 1.0 Connection Object.<transition> to a "connection.*" event within our CCXML application: More or less, whenever we access a CCXML 1.0 application. The property values of this Object can be really helpful for diagnostic and debugging purposes, and smart coders make a point to <log> this stuff as a matter of course, as it gives us a full-bore breakdown of each relevant telephony event source that is received by the CCXML 1.0 interpreter. These predefined properties we can access pretty easily, as long as we are hip to the right syntax to use:
transitionName.connection.propertyName
<transition event="connection.alerting">
<log expr="'***** EVENT$.CONNECTION.CONNECTIONID = ' + event$.connection.connectionid"/>
</transition>
<log> these values, (along with our user Object property values), by leveraging the <foreach> element.<foreach> element to reference our Object, and loop through all the available properties for both our Connection Object, as well as our user-defined Object, so that we can take a gander at our values. What's neat about the <foreach> element is that all we need to do is reference the Object name in the 'object' attribute, and half the battle is won already. Nested cozily within the element itself, we will put our <log> statement that will reference two things:
<?xml version="1.0" encoding="UTF-8"?>
<ccxml version="1.0" xmlns:voxeo="http://community.voxeo.com/xmlns/ccxml">
<script>
<![CDATA[
var myObject = new Object();
myObject.v1 = 'value_1';
myObject.v2 = 'value_2';
myObject.Arr = new Array();
myObject.Arr.push('hello');
myObject.Arr.push('world');
myObject.Obj = new Object();
myObject.Obj.Prop = 5;
]]>
</script>
<eventprocessor>
<transition event="connection.alerting">
<accept/>
<log expr="'***** MYOBJECT = ' + myObject"/>
<foreach object="myObject">
<log expr="'*** MYOBJECT ' + index$ + ' PROPERTY VALUE = ' + item$"/>
</foreach>
<foreach object="event$.connection">
<log expr="'*** CONNECTION OBJECT ' + index$ + ' PROPERTY VALUE = ' + item$"/>
</foreach>
</transition>
<transition event="connection.connected">
<log expr="'*** Call was accepted ***'"/>
</transition>
<transition event="connection.disconnected">
<log expr="'*** Call was disconnected ***'"/>
<exit/>
</transition>
<transition event="error.*">
<log expr="'an error has occured (' + event$.reason + ')'"/>
<log expr="'*** EVENT$.NAME = ' + event$.name"/>
<log expr="'*** EVENT$.REASON = ' + event$.reason"/>
<log expr="'*** EVENT$.TAGNAME = ' + event$.tagname"/>
<log expr="'*** EVENT$.EVENTID = ' + event$.eventid"/>
<log expr="'*** EVENT$.EVENTSOURCE = ' + event$.eventsource"/>
<log expr="'*** EVENT$.EVENTSOURCETYPE = ' + event$.eventsourcetype"/>
<voxeo:sendemail to="'youremail@somewhere.com'"
from="'myApp@here.com'"
type="'debug'"
body="'We had an error! \n Time to panic! \n
Flee the cities, abandon all hope!'"/>
<exit/>
</transition>
</eventprocessor>
</ccxml>
log: ***** MYOBJECT = [object Object]
log: *** MYOBJECT Arr PROPERTY VALUE = hello,world
log: *** MYOBJECT Obj PROPERTY VALUE = [object Object]
log: *** MYOBJECT v1 PROPERTY VALUE = value_1
log: *** MYOBJECT v2 PROPERTY VALUE = value_2
log: *** CONNECTION OBJECT aai PROPERTY VALUE =
log: *** CONNECTION OBJECT connectionid PROPERTY VALUE = 9a70627953544110c32262a0db24c434
log: *** CONNECTION OBJECT dialogid PROPERTY VALUE =
log: *** CONNECTION OBJECT input PROPERTY VALUE =
log: *** CONNECTION OBJECT local PROPERTY VALUE = 4071112222
log: *** CONNECTION OBJECT originator PROPERTY VALUE = remote
log: *** CONNECTION OBJECT outputs PROPERTY VALUE =
log: *** CONNECTION OBJECT protocol PROPERTY VALUE = [object Object]
log: *** CONNECTION OBJECT redirect PROPERTY VALUE =
log: *** CONNECTION OBJECT remote PROPERTY VALUE = 4074181800
log: *** CONNECTION OBJECT state PROPERTY VALUE = 0
<foreach> loop. Now we can get even craftier, and see what happens when we try an <send> our user-Object to a webserver....oh I didn't mention that yet? Shame on me. See, we cannot shove a raw Object to a webserver using <send>, so we need to figure out how to get around this. Spend some time on this, and let us know if you have any Bright Ideas; we will wait.<send>. And while we are at it, we can send back the same String from the webserver back to the CCXML, and then convert it back into an Object using the "JSON.parse" method? Excellent idea, Sherlock. I'll be putting you in for a promotion.<script> tag right out of the gate at the document scope, we should probably create a stringified version of our Object at the same scope so that we can use it later on when we want to <send> the value. We should also add our <send> tag into the mix so that we can get a feel for how we populate the various attributes to denote the fact that we are sending to an external webserver, and add in our <transition> events for a successful, and an unsuccessful attempt at sending these variables:
<?xml version="1.0" encoding="UTF-8"?>
<ccxml version="1.0" xmlns:voxeo="http://community.voxeo.com/xmlns/ccxml">
<script>
<![CDATA[
var myObject = new Object();
myObject.v1 = 'value_1';
myObject.v2 = 'value_2';
myObject.Arr = new Array();
myObject.Arr.push('hello');
myObject.Arr.push('world');
myObject.Obj = new Object();
myObject.Obj.Prop = 5;
]]>
</script>
<var name="sendObj" expr="JSON.stringify(myObject)"/>
<eventprocessor>
<transition event="connection.alerting">
<accept/>
<log expr="'***** MYOBJECT = ' + myObject"/>
<foreach object="myObject">
<log expr="'*** MYOBJECT ' + index$ + ' PROPERTY VALUE = ' + item$"/>
</foreach>
<foreach object="event$.connection">
<log expr="'*** CONNECTION OBJECT ' + index$ + ' PROPERTY VALUE = ' + item$"/>
</foreach>
</transition>
<transition event="connection.connected">
<log expr="'*** Call was accepted ***'"/>
<send name="'http.get'" target="'sendCatcher.php'" targettype="'basichttp'" namelist="sendObj"/>
</transition>
<transition event="myEvent">
<log expr="'***** MYDATA EVENT RECIEVED FROM SERVER *****'"/>
</transition>
<transition event="send.successful">
<log expr="'***** SEND IS SUCCESSFUL *****'"/>
</transition>
<transition event="error.send.targetunavailable">
<log expr="'***** SEND TARGET UNAVAILABLE *****'"/>
<exit/>
</transition>
<transition event="connection.disconnected">
<log expr="'*** Call was disconnected ***'"/>
<exit/>
</transition>
<transition event="error.*">
<log expr="'an error has occured (' + event$.name + ')'"/>
<log expr="'*** EVENT$.NAME = ' + event$.name"/>
<log expr="'*** EVENT$.REASON = ' + event$.reason"/>
<log expr="'*** EVENT$.TAGNAME = ' + event$.tagname"/>
<log expr="'*** EVENT$.EVENTID = ' + event$.eventid"/>
<log expr="'*** EVENT$.EVENTSOURCE = ' + event$.eventsource"/>
<log expr="'*** EVENT$.EVENTSOURCETYPE = ' + event$.eventsourcetype"/>
<voxeo:sendemail to="'youremail@somewhere.com'"
from="'myApp@here.com'"
type="'debug'"
body="'We had an error! \n Time to panic! \n
Flee the cities, abandon all hope!'"/>
<exit/>
</transition>
</eventprocessor>
</ccxml>
<send> syntax should look familiar, as we dealt with the usage of <send> and it's associated handlers in our CCXML-VXML dialog tutorial. In this case, we will want to specify a 'targettype' value of 'basichttp', (remember, we aren't sending our event to the CCXML session, we are sending to an external webserver). Our handlers themselves for 'send.successful' and 'error.send' are essentially cookie-cutter handlers that we don't do anything really fancy with in this case.
<?php
echo "myEvent\n"
?>
<?php
header('Cache-Control: no-cache');
foreach($_REQUEST as $key => $value )
{
echo $key , "=", $value, "\n";
}
?>
<send>. Not too much to it at all: It accepts a string value that has been sent to it, and returns the same string back to the invoking application. Feel free to rewrite this using JSP, ASP, .NET, or even ColdFusion, if that suits your coding style; we aren't limited to just PHP for a catcher script.<log> statements.
<?xml version="1.0" encoding="UTF-8"?>
<ccxml version="1.0" xmlns:voxeo="http://community.voxeo.com/xmlns/ccxml">
<script>
<![CDATA[
var myObject = new Object();
myObject.v1 = 'value_1';
myObject.v2 = 'value_2';
myObject.Arr = new Array();
myObject.Arr.push('hello');
myObject.Arr.push('world');
myObject.Obj = new Object();
myObject.Obj.Prop = 5;
]]>
</script>
<var name="sendObj" expr="JSON.stringify(myObject)"/>
<eventprocessor>
<transition event="connection.alerting">
<accept/>
<log expr="'***** MYOBJECT = ' + myObject"/>
<foreach object="myObject">
<log expr="'*** MYOBJECT ' + index$ + ' PROPERTY VALUE = ' + item$"/>
</foreach>
<foreach object="event$.connection">
<log expr="'*** CONNECTION OBJECT ' + index$ + ' PROPERTY VALUE = ' + item$"/>
</foreach>
</transition>
<transition event="connection.connected">
<log expr="'*** Call was accepted ***'"/>
<log expr="'***** SENDING DATA ..... NOW! *****'"/>
<log expr="'***** SENDOBJ = ' + sendObj"/>
<log expr="'***** MYOBJ = ' + myObject"/>
<send name="'http.get'" target="'sendCatcher.php'" targettype="'basichttp'" namelist="sendObj"/>
</transition>
<transition event="myEvent">
<var name="reObj" expr="JSON.parse(event$.sendObj)"/>
<log expr="'***** DATA RECIEVED FROM SERVER *****'"/>
<!-- hey look, its an object -->
<log expr="'***** AFTER SEND: REOBJ = ' + reObj"/>
<!-- hey look, its now a bunch of strings -->
<foreach object="reObj">
<log expr="'*** REOBJ ' + index$ + ' VALUE = ' + item$"/>
</foreach>
<exit/>
</transition>
<transition event="send.successful">
<log expr="'***** SEND IS SUCCESSFUL *****'"/>
</transition>
<transition event="error.send.targetunavailable">
<log expr="'***** SEND TARGET UNAVAILABLE *****'"/>
<exit/>
</transition>
<transition event="connection.disconnected">
<log expr="'*** Call was disconnected ***'"/>
<exit/>
</transition>
<transition event="error.*">
<log expr="'an error has occured (' + event$.reason + ')'"/>
<log expr="'*** EVENT$.NAME = ' + event$.name"/>
<log expr="'*** EVENT$.REASON = ' + event$.reason"/>
<log expr="'*** EVENT$.TAGNAME = ' + event$.tagname"/>
<log expr="'*** EVENT$.EVENTID = ' + event$.eventid"/>
<log expr="'*** EVENT$.EVENTSOURCE = ' + event$.eventsource"/>
<log expr="'*** EVENT$.EVENTSOURCETYPE = ' + event$.eventsourcetype"/>
<voxeo:sendemail to="'youremail@somewhere.com'"
from="'myApp@here.com'"
type="'debug'"
body="'We had an error! \n Time to panic! \n
Flee the cities, abandon all hope!'"/>
<exit/>
</transition>
</eventprocessor>
</ccxml>
<foreach> loop once again to prove to God and Country that yes, we really did re-convert our data back into an Object, and that we weren't just, you know, faking it. After adding in a few <exit> tags into the various <transition> elements to make sure that we receive a programmatic disconnect, our application is 100% complete, and ready for that test call.<foreach> element to loop through a complex data structure| ANNOTATIONS: EXISTING POSTS |
| login |
|