| CCXML 1.0-W3C Development Guide | Home | Frameset Home |
|
<xml> and <ccxml> headers. As we will be using a Voxeo-specific dialog extension in this lesson, it is very important that we specify the Voxeo XML namespace, otherwise, our called party will hear a fat, juicy error message when we test it the first time:
<?xml version="1.0" encoding="UTF-8"?>
<!-- NOTE THAT WE *MUST* DECLARE THE xmlns ATTRIBUTE -->
<ccxml version="1.0" xmlns:voxeo="http://community.voxeo.com/xmlns/ccxml"
</ccxml>
<?xml version="1.0" encoding="UTF-8"?>
<!-- NOTE THAT WE *MUST* DECLARE THE xmlns ATTRIBUTE -->
<ccxml version="1.0" xmlns:voxeo="http://community.voxeo.com/xmlns/ccxml">
<var name="myState" expr="'init'"/>
<var name="myOutboundConnectionID" expr="'someOutboundID'"/>
<eventprocessor statevariable="myState">
<transition event="error.*">
<log expr="'an error has occurred (' + event$.reason + ')'"/>
<voxeo:sendemail to="'yourEmail@there.com'"
from="'myApp@here.com'"
type="'debug'"
body=" 'generic error detected ! ' "/>
<exit/>
</transition>
</eventprocessor>
</ccxml>
<exit> after we log some values). Since this is only going to happen during the period that we are dialing the outbound destination, we will want to do some state management by setting the CCXML 1.0 application state to "dialing" during this period, and set the "state" attribute of this handler accordingly. And of course, we are all hotshot CCXML developers by now, so we also add in the inevitable <log> statements that will display our connection object and event properties when this event handler is executed:
<?xml version="1.0" encoding="UTF-8"?>
<!-- NOTE THAT WE *MUST* DECLARE THE xmlns ATTRIBUTE -->
<ccxml version="1.0" xmlns:voxeo="http://community.voxeo.com/xmlns/ccxml">
<var name="myState" expr="'init'"/>
<var name="myOutboundConnectionID" expr="'someOutboundID'"/>
<eventprocessor statevariable="myState">
<transition event="ccxml.loaded" state="init">
<log expr="'***** EVENT$.NAME = ' + event$.name"/>
<log expr="'***** EVENT$.SESSIONID = ' + event$.sessionid"/>
<log expr="'***** EVENT$.PARENT = ' + event$.parent"/>
<log expr="'***** EVENT$.EVENTID = ' + event$.eventid"/>
<log expr="'***** EVENT$.EVENTSOURCE = ' + event$.eventsource"/>
<log expr="'***** EVENT$.EVENTSOURCETYPE = ' + event$.eventsourcetype"/>
<assign name="myState" expr="'dialing'"/>
</transition>
<transition event="connection.failed" state="dialing">
<log expr="'***** CONNECTION FAILED *****'"/>
<log expr="'***** EVENT$.NAME = ' + event$.name"/>
<log expr="'***** EVENT$.SESSIONID = ' + event$.sessionid"/>
<log expr="'***** EVENT$.PARENT = ' + event$.parent"/>
<log expr="'***** EVENT$.EVENTID = ' + event$.eventid"/>
<log expr="'***** EVENT$.EVENTSOURCE = ' + event$.eventsource"/>
<log expr="'***** EVENT$.EVENTSOURCETYPE = ' + event$.eventsourcetype"/>
<exit/>
</transition>
<transition event="error.*">
<log expr="'an error has occurred (' + event.$.reason + ')'"/>
<voxeo:sendemail to="'yourEmail@there.com'"
from="'myApp@here.com'"
type="'debug'"
body=" 'generic error detected ! ' "/>
<exit/>
</transition>
</eventprocessor>
</ccxml>
<createcall> element in this case, and they'd be right. In order to do this successfully, we will want to remember that "myOutboundConnectionID" variable that we set earlier, and populate the "connectionID" attribute of the <createcall> element with it.
<?xml version="1.0" encoding="UTF-8"?>
<!-- NOTE THAT WE *MUST* DECLARE THE xmlns ATTRIBUTE -->
<ccxml version="1.0" xmlns:voxeo="http://community.voxeo.com/xmlns/ccxml">
<var name="myState" expr="'init'"/>
<var name="myOutboundConnectionID" expr="'someOutboundID'"/>
<eventprocessor statevariable="myState">
<transition event="ccxml.loaded" state="init">
<log expr="'***** EVENT$.NAME = ' + event$.name"/>
<log expr="'***** EVENT$.SESSIONID = ' + event$.sessionid"/>
<log expr="'***** EVENT$.PARENT = ' + event$.parent"/>
<log expr="'***** EVENT$.EVENTID = ' + event$.eventid"/>
<log expr="'***** EVENT$.EVENTSOURCE = ' + event$.eventsource"/>
<log expr="'***** EVENT$.EVENTSOURCETYPE = ' + event$.eventsourcetype"/>
<assign name="myState" expr="'dialing'"/>
<createcall dest="'tel:4072223333'" connectionid="myOutboundConnectionID" timeout="'45s'"/>
</transition>
<transition event="connection.connected" state="dialing">
<assign name="myState" expr="'connected'"/>
<log expr="'***** CALL WAS ANSWERED *****'"/>
<log expr="'***** EVENT$.CONNECTION.CONNECTIONID = ' + event$.connection.connectionid"/>
<log expr="'***** EVENT$.CONNECTION.PROTOCOL.NAME = ' + event$.connection.protocol.name"/>
<log expr="'***** EVENT$.CONNECTION.PROTOCOL.VERSION = ' + event$.connection.protocol.version"/>
<log expr="'***** EVENT$.CONNECTION.STATE = ' + event$.connection.state"/>
<log expr="'***** EVENT$.CONNECTION.LOCAL = ' + event$.connection.local"/>
<log expr="'***** EVENT$.CONNECTION.REMOTE = ' + event$.connection.remote"/>
<log expr="'***** EVENT$.CONNECTION.ORIGINATOR = ' + event$.connection.originator"/>
</transition>
<transition event="connection.failed" state="dialing">
<log expr="'***** CONNECTION FAILED *****'"/>
<log expr="'***** EVENT$.NAME = ' + event$.name"/>
<log expr="'***** EVENT$.SESSIONID = ' + event$.sessionid"/>
<log expr="'***** EVENT$.PARENT = ' + event$.parent"/>
<log expr="'***** EVENT$.EVENTID = ' + event$.eventid"/>
<log expr="'***** EVENT$.EVENTSOURCE = ' + event$.eventsource"/>
<log expr="'***** EVENT$.EVENTSOURCETYPE = ' + event$.eventsourcetype"/>
<exit/>
</transition>
<transition event="error.*">
<log expr="'an error has occurred (' + event$.reason + ')'"/>
<voxeo:sendemail to="'yourEmail@there.com'"
from="'myApp@here.com'"
type="'debug'"
body=" 'generic error detected ! ' "/>
<exit/>
</transition>
</eventprocessor>
</ccxml>
<dialogstart type="audio/wav"> extension element, which is used exclusively on the Voxeo platform. The beauty of this extension is that we don't need to invoke the VoiceXML interpreter at all, we just specify an audio file to play, and backup TTS, and the CCXML 1.0 interpretr handles the rest for us. And since this is still just a dialog, we want to make sure that we catch when the dialog exits programmatically, so we once again utilize our friend the "dialog.exit" handlers. Note carefully that we set the "state" attribute to this handler so that the only way it can be matched is when the state manager says that we are in the "connected" state.<log> followed by an <exit>. To review, when a caller hangs up midway through message delivery, we will expect to receive a "connection.disconnected" event. When the callee listens to the complete message, we can expect to see the "dialog.exit" event pop up.
<?xml version="1.0" encoding="UTF-8"?>
<!-- NOTE THAT WE *MUST* DECLARE THE xmlns ATTRIBUTE -->
<ccxml version="1.0" xmlns:voxeo="http://community.voxeo.com/xmlns/ccxml">
<var name="myState" expr="'init'"/>
<var name="myOutboundConnectionID" expr="'someOutboundID'"/>
<eventprocessor statevariable="myState">
<transition event="ccxml.loaded" state="init">
<log expr="'***** EVENT$.NAME = ' + event$.name"/>
<log expr="'***** EVENT$.SESSIONID = ' + event$.sessionid"/>
<log expr="'***** EVENT$.PARENT = ' + event$.parent"/>
<log expr="'***** EVENT$.EVENTID = ' + event$.eventid"/>
<log expr="'***** EVENT$.EVENTSOURCE = ' + event$.eventsource"/>
<log expr="'***** EVENT$.EVENTSOURCETYPE = ' + event$.eventsourcetype"/>
<assign name="myState" expr="'dialing'"/>
<createcall dest="'tel:4072223333'" connectionid="myOutboundConnectionID" timeout="'45s'"/>
</transition>
<transition event="connection.connected" state="dialing">
<assign name="myState" expr="'connected'"/>
<log expr="'***** CALL WAS ANSWERED *****'"/>
<log expr="'***** EVENT$.CONNECTION.CONNECTIONID = ' + event$.connection.connectionid"/>
<log expr="'***** EVENT$.CONNECTION.PROTOCOL.NAME = ' + event$.connection.protocol.name"/>
<log expr="'***** EVENT$.CONNECTION.PROTOCOL.VERSION = ' + event$.connection.protocol.version"/>
<log expr="'***** EVENT$.CONNECTION.STATE = ' + event$.connection.state"/>
<log expr="'***** EVENT$.CONNECTION.LOCAL = ' + event$.connection.local"/>
<log expr="'***** EVENT$.CONNECTION.REMOTE = ' + event$.connection.remote"/>
<log expr="'***** EVENT$.CONNECTION.ORIGINATOR = ' + event$.connection.originator"/>
<dialogstart src="'someFile.wav?text=This is an automated call from the H.A.L. 9000 computer system to commander David Bowman. This message is to inform you that all pod bay doors are now closed, and re entry to the Discovery spacecraft is forbidden. This message is too important to jeapordize it to human error. This conversation can serve no further purpose. Goodbye.'" type="'audio/wav'"/>
</transition>
<transition event="connection.failed" state="dialing">
<log expr="'***** CONNECTION FAILED *****'"/>
<log expr="'***** EVENT$.NAME = ' + event$.name"/>
<log expr="'***** EVENT$.SESSIONID = ' + event$.sessionid"/>
<log expr="'***** EVENT$.PARENT = ' + event$.parent"/>
<log expr="'***** EVENT$.EVENTID = ' + event$.eventid"/>
<log expr="'***** EVENT$.EVENTSOURCE = ' + event$.eventsource"/>
<log expr="'***** EVENT$.EVENTSOURCETYPE = ' + event$.eventsourcetype"/>
<exit/>
</transition>
<transition event="dialog.exit" state="connected">
<log expr="'***** DIALOG EXIT REACHED *****'"/>
<log expr="'***** EVENT$.NAME = ' + event$.name"/>
<log expr="'***** EVENT$.DIALOGID = ' + event$.dialogid"/>
<log expr="'***** EVENT$.CONFERENCEID = ' + event$.conferenceid"/>
<log expr="'***** EVENT$.CONNECTIONID = ' + event$.connectionid"/>
<log expr="'***** EVENT$.EVENTID = ' + event$.eventid"/>
<log expr="'***** EVENT$.EVENTSOURCE = ' + event$.eventsource"/>
<log expr="'***** EVENT$.EVENTSOURCETYPE = ' + event$.eventsourcetype"/>
<log expr="'***** EVENT$.DIALOG.DIALOGID = ' + event$.dialog.dialogid"/>
<log expr="'***** EVENT$.DIALOG.CONNECTIONID = ' + event$.dialog.connectionid"/>
<log expr="'***** EVENT$.DIALOG.CONFERENCEID = ' + event$.dialog.conferenceid"/>
<log expr="'***** EVENT$.DIALOG.TYPE = ' + event$.dialog.type"/>
<log expr="'***** EVENT$.DIALOG.SRC = ' + event$.dialog.src"/>
<log expr="'***** EVENT$.DIALOG.INPUT = ' + event$.dialog.input"/>
<log expr="'***** EVENT$.DIALOG.OUTPUTS = ' + event$.dialog.outputs"/>
<exit/>
</transition>
<transition event="connection.disconnected">
<log expr="'***** CONNECTION.DISCONNECT EVENT CAUGHT *****'"/>
<log expr="'***** EVENT$.NAME = ' + event$.name"/>
<log expr="'***** EVENT$.CONNECTIONID = ' + event$.connectionid"/>
<log expr="'***** EVENT$.PROTOCOL = ' + event$.protocol"/>
<log expr="'***** EVENT$.REASON = ' + event$.reason"/>
<log expr="'***** EVENT$.INFO = ' + event$.info"/>
<log expr="'***** EVENT$.CONNECTION = ' + event$.connection"/>
<log expr="'***** EVENT$.EVENTID = ' + event$.eventid"/>
<log expr="'***** EVENT$.EVENTSOURCE = ' + event$.eventsource"/>
<log expr="'***** EVENT$.EVENTSOURCETYPE = ' + event$.eventsourcetype"/>
<log expr="'***** EVENT$.TRIGGER = ' + event$.trigger"/>
<exit/>
</transition>
<transition event="error.*">
<log expr="'an error has occurred (' + event$.reason + ')'"/>
<voxeo:sendemail to="'yourEmail@there.com'"
from="'myApp@here.com'"
type="'debug'"
body=" 'generic error detected ! ' "/>
<exit/>
</transition>
</eventprocessor>
</ccxml>
Example: http://api.voxeo.net/SessionControl/CCXML10.start?tokenid=abc123&resulturl=http://myserver.com/results.php
Example: http://api.voxeo.net/SessionControl/CCXML10.start?tokenid=abc123&xmloutput=truesip:4075551212!66.77.88.99@sbc-staging-internal| Token Router Response | Description |
| Success | The request was processed successfully. |
| Failed to route call | A browser could not be instantiated to accept the token. This could be because there is an inherent issue with the CCXML 1.0 code itself, or at this given moment the browsers are unavailable. |
| Failure | This is an unspecified error, and would result from the token routers being unable to accept the request at this given time. This will result in retries however, and you will likely never see this; more often then not you will receive invalid token if/when there are load-related issues with the token routers. |
| Invalid Token | Check the token syntax to make sure it's valid, or if you're using a brand new token, wait a few minutes and try it again. |
| ANNOTATIONS: EXISTING POSTS |
shilpart28
|
|
| I am new to CCXML ..i am tryin to place multiple calls (parellel) and announce different details to caller.I am able to place single call and announce detauils.If i try to place mulitple calls ,the call is goin throught but only for one call i can hear the announcemt.Fot other calls i am not able to start the dialog.Is there any sample code for that which i can use..Thanks in advance | |
voxeoJason
|
|
| Hi,
I'm a little unclear on what you're trying to do. I understand you want to make two calls at once. Are you wanting to make two completely different calls to two numbers from the same application at the same time? Is this correct? Regards, Jason Voxeo Support |
|
venkoba
|
|
| Hi,
I have created and tested the application successfully. After disconnecting the call i want to post the information to a jsp page which is located on my server. Please give me code snippet for this thanks, |
|
voxeoJeffK
|
|
| Hello,
For external communication you can use the <send> element: http://docs.voxeo.com/ccxml/1.0-final/send.htm There is some sample code as well in "Appendix G: <Send> Element & HTTP Requests" http://docs.voxeo.com/ccxml/1.0-final/appendixg_ccxml10.htm As an example you could use the following to send the MyVar variable to sendTarget.php: <send target="'sendTarget.php'" name="what_i_sent" namelist="myVar" delay="'1s'" targettype="'basichttp'"/> Regards, Jeff Kustermann Voxeo Support |
|
ranm
|
|
| Hi,
The transition <transition event="connection.disconnected"> does not contain an exit statement. This statement is missing both in this page and in the attached code. Is this OK? Regards |
|
VoxeoBrian
|
|
| Hello,
In the specific example we are expecting a dialog to have been started and thus exit which we trap and call <exit/> as you can see in the dialog.exit transition. Having said that, it would be recommended in our example to call <exit/> in the connection.disconnected as well, since we are not managing different call legs, nor wish to take additional action after hangup. I have updated the internal documentation set, when we push a new release this will be reflected with the <exit/> in the connection.disconnected. Hope this helps. Regards, Brian F. |
|
konrad.garus
|
|
| Am I correct that to do outbound calls, I need to:
1. Create a regular CCXML application. 2. Request a token and map it to the application. 3. When I want to place a call, post to the generic api.voxeo.net URL with my token. This would identify my app by token and start the call. |
|
jdyer
|
|
| Hello Konrad,
Yes, that is a high level overview of the requirements to launch a token call from the CCXML context. May I ask, are you having any issues here or were you simply looking for clarification? We are standing by for your update at this time. Regards, John Dyer Customer Engineer Voxeo Support |
|
konrad.garus
|
|
| John, at the moment I was only looking for this high-level understanding. Thank you for the clarification. | |
konrad.garus
|
|
| Could you please explain where I can find more information on launching outbound calls? In particular, I'm looking for possible responses/status codes and handling concurrent calls. | |
voxeoJeffK
|
|
| Hello,
First you might check our blog post here: How-To: Outbound Notification Applications http://blogs.voxeo.com/voxeodeveloperscorner/2009/03/16/how-to-outbound-notification-applications/ Most SIP response codes will resolve to the following at the browser level: badnumber: 500 server internal 404 not found 484 address incomplete unreachable 403 forbidden 501-599 busy 480 temporarily unavailable 486 busy here 603 busy decline timeout 408 timeout unknown any other SIP response code If we can help with any clarifications or additional questions, please let us know. Regards, Jeff Kustermann Voxeo Support |
|
konrad.garus
|
|
| Jeff, thank you for the link. However, this post seems to assume constant call length and does not handle status codes at all. I need quite the opposite - unknown call length and heavy dependency on statuses.
What happens when I run out of ports? Do I get an error code from the api.voxeo.net launcher (the "kickoff page"), or does my ccxml app launch and fail on createcall? Either way, what does the error look like? Is there any references on the codes you enlisted? Such as when exactly they are returned and what they mean. |
|
jdyer
|
|
| Hello,
The example Jeff provided was just intended to be a high level overview of how to implement outbound dialing campaigns, however the methodology would certainly be the same you will simply have to account for disparate call lengths in your throttling mechanism. In regards to response codes, you will want to use our VCS API port which returns a 503 response with an "out of sessions" body when port port usage exceeds availability. (http://ipaddress:9999/CCXML10.start?tokenid=foo) I do hope this helps, and if there are any other questions please let us know, as our team is certainly here to be of service! Regards, John Dyer Customer Engineer Voxeo Support |
|
konrad.garus
|
|
| I'm using Skype DID for development. I noticed that when I reject the call (by pressing the red receiver icon while it's ringing), in logs I get CONNECTION.CONNECTED, then dialog starts and ends 15 seconds later, then finally I get DIALOG.EXIT (but never CONNECTION.DISCONNECTED or CONNECTION.FAILED).
Is this an issue with Skype? How I can I detect and handle caller rejecting a call like this? Thank you. Regards, Konrad Garus |
|
jdyer
|
|
| Hello Konrad,
I suspect this is simple a delay in logging you are seeing here, but I would like to review the debugger content to be sure. Can you please use the support tab in the debugger and post logs into a ticket for our review? Please include a description of the issue as to provide context and we would most certainly be happy to review it. We'll be standing by for your update at this time. Regards, John Dyer Customer Engineer Voxeo Support |
| login |
|