CCXML 1.0-W3C Development GuideHome  |  Frameset Home

  Advanced Answering Machine Detection  |  TOC  |  Unjoin via termdigit  

Conferencing with Whisper

Adding the ability to send a 'whisper' message to a user of your conference can be a very handy feature to have for professional-sounding applications. Since VoiceXML does not have any provisions for this on it's own, we once again turn to CCXML to Save The Day.

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.

Say What?

So what exactly is this 'whisper' functionality? Pretty simple, actually. Let's say that you want to make a call to a certain party, and need to send them a pre-emptive message before being connected. Such as, 'You are late for the conference call, and The Big Boss is pretty angry. Start groveling.' Or maybe you want to authenticate who it is that's answering the phone, with a message such as 'There is a call waiting for you. If this is Cornelius, please enter your personal ID code to join.' (We could make this last even cooler by using voiceprint identification, I might add).

We also want the ability to allow this message to only get played for specific callees, which we can achive easily enough by specifying which call legs will carry this message. Let's take a look at how we can make this happen:


<?xml version="1.0" encoding="UTF-8" ?>
<ccxml version="1.0" xmlns="http://www.w3.org/2002/09/ccxml" xmlns:voxeo="http://community.voxeo.com/xmlns/ccxml">

<meta name="author" content="Jeff Menkel"/>
<meta name="copyright" content="2005 Voxeo Corporation"/>
<meta name="description" content="Conferencing with Whisper Tutorial"/>
<meta name="maintainer" content="YOUR_EMAIL@HERE.COM"/>
 
  <var name="state0" expr="'init'"/>
  <var name="callid_in"/>
  <var name="callid_out"/>
  <var name="holdMusicDlg"/>
  <var name="mainVXMLDlg"/>
 
  <eventprocessor statevariable="state0">

<!--  *****************************************  -->
<!--  Inbound call is accepted.                  -->
<!--  *****************************************  -->

    <transition state="init" event="connection.alerting">
      <log expr="'ACCEPTING INBOUND CALL'"/>
      <accept/>
    </transition>

<!--  *****************************************  -->
<!--  Begin playing the main VXML dialog.        -->
<!--  *****************************************  -->

    <transition state="init" event="connection.connected" name="evt">
      <log expr="'INBOUND CALL CONNECTED / STARTING MAIN VXML DIALOG'"/>
      <assign name="callid_in" expr="evt.connectionid"/>
      <assign name="state0" expr="'mainVXMLDialog'"/>           
      <dialogstart src="'mainVXML.vxml'" dialogid="mainVXMLDlg"/>         
    </transition>   

<!--  *****************************************  -->
<!--  If the caller chooses to make the          -->
<!--  Outbound call then play hold music for    -->
<!--  Inbound call and then create the Outbound  -->
<!--  call.                                      -->
<!--  *****************************************  -->

    <transition state="mainVXMLDialog" event="dialog.exit" name="evt">
      <log expr="'FINISHED MAIN VXML DIALOG / CALLERS ANSWER IS: ' + evt.values.answer"/>
      <if cond="'1' == evt.values.answer">
        <assign name="state0" expr="'calling'"/>           
        <dialogstart src="'holdmusic.vxml'" dialogid="holdMusicDlg" connectionid="callid_in"/>         
        <createcall dest="'tel:4075551212'"/>
      <else/>
        <exit/>
      </if>
    </transition>
   
<!--  *****************************************  -->
<!--  If outbound call fails.                    -->
<!--  *****************************************  -->

    <transition state="calling" event="connection.failed">
      <log expr="'OUTBOUND CALL FAILED'"/>
      <assign name="state0" expr="'callfailed'"/>
      <dialogterminate dialogid="holdMusicDlg"/>
    </transition>

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

    <transition state="playingCallFailed" event="dialog.exit">
      <log expr="'DISCONNECTING INBOUND CALL'"/>
      <disconnect/>
    </transition>

<!--  *****************************************  -->
<!--  Outbound call is answered and played a    -->
<!--  "whisper" VXML dialog.                      -->
<!--  *****************************************  -->

    <transition state="calling" event="connection.connected" name="evt">
      <log expr="'OUTBOUND CALL CONNECTED / STARTING WHISPER DIALOG'"/>
      <assign name="callid_out" expr="evt.connectionid"/>
      <assign name="state0" expr="'callAccepted'"/>
      <dialogstart src="'whisper.vxml'"/>
    </transition>

<!--  *****************************************  -->
<!--  When "whisper" dialog is finished stop      -->
<!--  hold music for Inbound call.              -->
<!--  *****************************************  -->

    <transition state="callAccepted" event="dialog.exit" name="evt">
      <log expr="'WHISPER DIALOG ENDED / KILLING HOLD MUSIC ----'" />
      <assign name="state0" expr="'endHoldMusic'"/>
      <dialogterminate dialogid="holdMusicDlg"/>
    </transition>

<!--  *****************************************  -->
<!--  When hold music dialog is finished join    -->
<!--  Outbound and Inbound call legs.            -->
<!--  *****************************************  -->

    <transition state="endHoldMusic" event="dialog.exit">
      <log expr="'HOLD MUSIC ENDED'"/>
      <assign name="state0" expr="'bridged'"/>
      <send name="'bridgeCall'" target="session.id" delay="'4s'"/>
    </transition>   
   
<transition event="bridgeCall" state="bridged">
      <join id1="callid_in" id2="callid_out" duplex="'full'"/>
  <log expr="'JOIN CALLS LEGS'"/>
</transition>

    <transition event="connection.disconnected" name="evt">
      <if cond="callid_in == evt.connectionid">
        <exit/>
      </if>
    </transition>

    <transition event="error.*" name="evt">
      <log expr="'AN ERROR HAS OCCURED (' + evt.reason + ')'"/>
      <exit/>
    </transition>
  </eventprocessor>   
</ccxml>



How it all boils down

So, what do we have going on here, you ask? Looking at the code, the app first accepts an inbound call from the user, (you), and we start an initial dialog, ( mainVXML.vxml ), that prompts the user to either connect the call to the specified outbound party, or to terminate the conference entirely. More likely than not, we will want to choose to connect to the desired party. At this point, the caller gets sent to a hold music page, ( holdmusic.vxml ) while the app dials the second party. Assuming that the second party answers the line, then this second party will be sent to the VXML dialog containing the whisper message, (whisper.vxml). After the message has been played to the second party, we then kill the hold music dialog, and finally join the two together by way of the <join> element.

Notice a few things about this code layout. First and foremost, we have the catch-all <transitionevent="error.*"> followed by an immediate <exit>, so as to prevent an endless looping of our application. We are also going to add a dialog to play to the initial caller if the second party cannot be reached, or an error occurs that results in a call failure, (callfailed.vxml).

Based on this very simple example, it would be enormously easy to tweak the whisper dialog for authentication purposes, or even allow the initial caller to record a whisper message to play to the callee before the two are connected. Add in just a little server side code, and the possibilities for increasing the functionality of these 'starter' documents are virtually endless.


Sample Code, Anyone?

You wanted it, you got it right HERE!




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

login
  Advanced Answering Machine Detection  |  TOC  |  Unjoin via termdigit  

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