CCXML Voxeo 1.0 Development GuideHome  |  Frameset Home

  Conferencing with Whisper   |  TOC  |  ANI and DNIS  
This documentation is for CCXML 1.0-Voxeo, which has been superceded by CCXML 1.0-W3C. The CCXML-Voxeo platform is not being updated any longer. The CCXML 1.0-W3C version, however, has many new features and is actively being enhanced. If you're writing a new CCXML application, you should use CCXML 1.0-W3C. Click here for the CCXML 1.0-W3C documentation.

Join and Unjoin via Termdigit

Looking for bold new ways to use CCXML? Well, you'll find half of that here. The concepts we present here are not really new per-se, but kinda bold. Or emboldened, maybe. Consult your nearest dictionary. And, it does seem to merit some space in the CCXML documentation, because most folks will eventually ask ' how can I kick someone out of my conference'.

Well,  to answer this question, we will want to use the Voxeo-proprietary extension to the <join> tag, called the "voxeo-termdigits" attribute.

Note: This example application requires the enabling of outdial priveleges on the Voxeo network, and the provisioning of a alphanumeric token string to your application. In order to get hooked up with all these neat features, check our Support Guide for all the juicy details.

Here's the scenario: We want to allow a caller to ring the app, and then place an outbound call to another party. But, if the second party gets snippy with us, we want to be able to put him in his place and exit the conference via a keypress to let him cool off. So how is it put together, you ask? Let's take a peek:

Start.xml


<?xml version="1.0" encoding="UTF-8" ?>
<ccxml version="1.0">
  <var name="state0" expr="'init'"/>
  <eventhandler statevariable="state0">

<!--  *****************************************  -->
<!--  Inbound call is accepted and create        -->
<!--  conference named "conf".                                  -->
<!--  *****************************************  -->

    <transition state="'init'" event="connection.CONNECTION_ALERTING">
      <accept/>
      <createconference name="conf"/>     
    </transition>

    <transition state="'init'" event="ccxml.conference.created">
      <log expr="'---- conference created and its ID is [' + conf + ']'" />
    </transition>

<!--  *****************************************  -->
<!--  Play hold music for Inbound call and then  -->
<!--  create the Outbound call.                  -->
<!--  *****************************************  -->

    <transition state="'init'" event="connection.CONNECTION_CONNECTED" name="evt">
      <var name="callid_in" expr="evt.callid"/>
      <assign name="state0" expr="'calling'"/>           
      <dialogstart src="'holdmusic.vxml'" name="holdMusicDlg"/>         
      <createcall dest="'1235554321'"/>
    </transition>   
   
    <transition state="'calling'" event="connection.CONNECTION_FAILED">
      <assign name="state0" expr="'callfailed'"/>
      <dialogterminate sessionid="holdMusicDlg"/>
    </transition>

    <transition state="'callfailed'" event="dialog.exit">
      <assign name="state0" expr="'playingCallFailed'"/>
      <dialogstart src="'callfailed.vxml'"/>                 
    </transition>

    <transition state="'playingCallFailed'" event="dialog.exit">
      <disconnect/>
    </transition>

<!--  *****************************************  -->
<!--  Outbound call is answered and played a    -->
<!--  small VXML dialog.                        -->
<!--  *****************************************  -->
   
    <transition state="'calling'" event="connection.CONNECTION_CONNECTED" name="evt">
      <var name="callid_out" expr="evt.callid"/>
      <assign name="state0" expr="'callAccepted'"/>
      <dialogstart src="'newcall2.vxml'"/>
    </transition>

<!--  *****************************************  -->
<!--  Join Outbound call to "conf".  NOTICE:    -->
<!--  We have included the ability for this      -->
<!--  call leg to use the term digit to unjoin  -->
<!--  the conference.                            -->
<!--  *****************************************  -->

    <transition state="'callAccepted'" event="dialog.exit" name="evt">
      <assign name="state0" expr="'joinCallOut'"/>
      <assign name="termdigits" expr="'1234'"/>
      <join id1="callid_out" id2="conf" voxeo-termdigits="'#'" />
    </transition>

<!--  *****************************************  -->
<!--  Stop hold music for Inbound call.          -->
<!--  *****************************************  -->

    <transition state="'joinCallOut'" event="ccxml.conference.joined" name="evt">
      <log expr="'---- call leg ' + evt.callid + ' has joined the conference'" />
      <assign name="state0" expr="'joinCallIn'"/>
      <log expr="'---- Ending Hold Music ----'" />
      <dialogterminate sessionid="holdMusicDlg"/>
    </transition>

<!--  *****************************************  -->
<!--  Join Inbound call to "conf".  NOTICE:  We  -->
<!--  do *not* allow this call leg to use term  -->
<!--  digits.                                    -->
<!--  *****************************************  -->

    <transition state="'joinCallIn'" event="dialog.exit">
      <assign name="state0" expr="'bridged'"/>
      <join id1="callid_in" id2="conf"/>
    </transition>   

    <transition state="'bridged'" event="ccxml.conference.joined" name="evt">
      <log expr="'---- call leg ' + evt.callid + ' has joined the conference'" />
    </transition>

<!--  *****************************************  -->
<!--  conf is unjoined.  We check to make sure  -->
<!--  that the Outbound call leg did it.  Then  -->
<!--  start a VXML dialog for the Outbound      -->
<!--  call leg and unjoin the Inbound call leg  -->
<!--  from the conf.                            -->
<!--  *****************************************  -->

    <transition state="'bridged'" event="ccxml.conference.unjoined" name="evt">
      <log expr="'---- call leg ' + evt.callid + ' has unjoined the conference'" />
      <log expr="'---- TERMDIGIT PRESSED WAS: ' + evt.digits + ' ----'" />
      <if cond="evt.callid == callid_out">
        <log expr="'---- callOut has hit the term digit ----'"/>
        <assign name="state0" expr="'bridgeBroken'"/>
        <dialogstart src="'termdigit.vxml'" name="termDigitDlg" callid="callid_out"/>         
        <unjoin id1="callid_in" id2="conf"/>
      <else/>
        <destroyconference conferenceid="conf" />
        <assign name="state0" expr="'conferencedestroyed'" />
      </if>
    </transition>   

<!--  *****************************************  -->
<!--  When the Inbound call is unjoind we will  -->
<!--  beging playing hold music to that leg.    -->
<!--  *****************************************  -->

    <transition state="'bridgeBroken'" event="ccxml.conference.unjoined" name="evt">
      <log expr="'---- call leg ' + evt.callid + ' has been unjoined from the conference'" />
      <log expr="'---- callIn will now be placed on hold ----'"/>
      <dialogstart src="'holdmusic.vxml'" name="holdMusicDlg" callid="callid_in"/>         
    </transition>

<!--  *****************************************  -->
<!--  If the Outbound leg presses "1" in his    -->
<!--  VXML dialog then we will kill the hold    -->
<!--  music for the Inbound leg and prepair to  -->
<!--  join both legs back into the conf.        -->
<!--  *****************************************  -->

    <transition state="'bridgeBroken'" event="dialog.exit" name="evt">
      <if cond="'1' == evt.answer">
        <assign name="state0" expr="'prepare2rejoin'"/>
        <dialogterminate sessionid="holdMusicDlg"/>
      <else/>
        <exit/>
      </if>
    </transition>

<!--  *****************************************  -->
<!--  Join both legs back into the conf and      -->
<!--  Voila...  Gravy...                        -->
<!--  *****************************************  -->

    <transition state="'prepare2rejoin'" event="dialog.exit">
      <assign name="state0" expr="'bridged'"/>
      <join id1="callid_in" id2="conf"/>
    <join id1="callid_out" id2="conf" voxeo-termdigits="'#'" />
    </transition>   
   
    <transition event="ccxml.conference.destroyed">
      <exit/>
    </transition>

   
    <transition event="call.CALL_INVALID" name="evt">
      <if cond="callid_in == evt.callid">
        <exit/>
      </if>
    </transition>

    <transition event="error.*" name="evt">
      <log expr="'an error has occured (' + evt.error + ')'"/>
      <exit/>
    </transition>
  </eventhandler>   
</ccxml>



All the code that you see above is pretty much by-the-book, and should be pretty familiar to you. The originiator of the conference dials in, and enters a 'hold' state, ( holdmusic ), while the app makes an outbound call to the second party. Once the second party answers he is alerted via a VXML dialog, ( newcall2.vxml ), that there is a call waiting  He then is connected to the conference. Now, the curve ball we throw in this bit of code revolves around the <join> element, as previously mentioned. We specify that if caller 1 (only!) presses the 'dtmf-pound' key then he will be allowed to leave the conference, and get sent to a another 'hold' page, ( termdigit.vxml )where he can choose to either end the call, or rejoin the conference. Meanwhile, caller 2 is left in the conference until the call initiator takes action.

Sample Code, Anyone?

Look right about HERE!





  ANNOTATIONS: EXISTING POSTS
0 posts - click the button below to add a note to this page

login
  Conferencing with Whisper   |  TOC  |  ANI and DNIS  

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