CCXML 1.0-W3C Development GuideHome  |  Frameset Home

  F: Outbound Dialing  |  TOC  |  Limiting Call length  

Postdialing

If your application is going to be hitting a PBX system of any sort, you'll want to have the ability to enter extension numbers after the call is initially connected. Will the standard w3c CCXML spec allow for this? Heck no. But with the Voxeo CCXML 1.0 implementation, such a chore is easily accomplished by using the 'dtmf' type extension of the <dialogstart> element.

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.


For this example, all we need to do is take our sample code from CCXML 1.0 Lesson 7, and modify it a bit. To start off with, lets get ourselves a nice little HTML page to start the token off. We will need three fields in this code:


Start.html


<title>Postdialing token trigger</title>

<!-- note that the CCXML 1.0 platform uses a unique start URL -->
<form name="SampleForm"
  action="http://session.voxeo.net/CCXML10.start"  method="POST">
  <input type="hidden" name="tokenid" value="YOUR TOKEN ID GOES HERE">

  Enter your phone number:<br>
  <input type="text" name="Num_1" size="10" maxlength="10" value=""><br><br>

  Enter the PBX phone number:<br>
  <input type="text" name="Num_2" size="10" maxlength="10" value=""><br><br>
  Enter the PBX extension number:<br>
  <input type="text" name="Ext" size="5" maxlength="5" value=""><br><br>
  <br><br>
  <input type="reset" value="Clear">
   
  <input type="submit" name="submit" value="Give me a call!">
</form>



Of course, like good Boy Scouts, we will need to Be Prepared, so we will need a 'hold music' page,  and a 'call failed' page, exactly like the ones detailed in CCXML Lesson 6.


Now, we get to the 'meat' of postdialing with CCXML 1.0. We will need to snag our querystring values from the webform, so we'll write this using some tender-loving PHP. Once we grab these variables, we will want to place a call to yourself to get started, and once it is answered, place the call to that PBX destination. Assuming that everyone plays nice and answers their phone, we put our querysting variable into the 'dtmf' dialog src. Put on your seatbelts:


postdial.php


<?PHP
header('Cache-Control: no-cache');
echo '<?xml version="1.0" encoding="UTF-8"?>';


echo "<ccxml version=\"1.0\">";
echo "<var name=\"phoneNum_1\" expr=\"'tel:+1" . $_REQUEST["Num_1"] ."'\" />";
echo "<var name=\"phoneNum_2\" expr=\"'tel:+1" . $_REQUEST["Num_2"] ."'\" />";
echo "<var name=\"pbxExt\" expr=\"'". $_REQUEST["Ext"] ."'\"/>";
?>


<meta name="author" content="Steve Sax"/>
<meta name="copyright" content="2007 Voxeo Corporation"/>
<meta name="maintainer" content="YOUR_EMAIL@HERE.COM"/>


  <var name="state0" expr="'init'"/>
  <var name="callid_1"/>
  <var name="callid_2"/>
  <var name="holdMusicDlg_1"/>
  <var name="dialExtDlg_2"/>


<!-- *** Make our first call out to the non-PBX party *** -->
  <eventprocessor statevariable="state0">
    <transition state="init" event="ccxml.loaded">
      <log expr="'-- Application Starting --'"/>
      <log expr="'-- Making Outbound Call #1 --'"/>
      <assign name="state0" expr="'calling_1'"/> 
      <createcall dest="phoneNum_1"/>
    </transition>   

<!-- *** Put first call leg in a hold state until the second party joins *** -->
    <transition state="calling_1" event="connection.connected">
      <log expr="'-- Call #1 Answered --'"/>
      <assign name="callid_1" expr="event$.connectionid"/>
      <assign name="state0" expr="'play_1_hldmsc'"/>
      <dialogstart src="'holdmusic.vxml'" dialogid="holdMusicDlg_1"/>
    </transition>

<!-- *** Dial out to the PBX party. See if we can achieve first strike *** -->
    <transition state="play_1_hldmsc" event="dialog.started">
      <log expr="'-- Caller #1 Hold Music Started --'"/>
      <assign name="state0" expr="'calling_2'"/>
   
      <createcall dest="phoneNum_2"/>
    </transition>   

<!-- *** Sweet. The PBX system has answered. Our enemy awaits.  *** -->
    <transition state="calling_2" event="connection.connected">
      <log expr="'-- Call #2 Answered --'"/>
      <assign name="callid_2" expr="event$.connectionid"/>
      <assign name="state0" expr="'createDelay_2'"/>
      <send data="'continue'" target="session.id" delay="'3s'"/>
    </transition>

<!-- *** Use the x-senddtmf dialog extension to output the dtmf tones to the PBX system, thereby rendering it defenseless *** -->
    <transition state="createDelay_2" event="continue">
      <log expr="'-- *Continue* Event Received --'"/>
      <assign name="state0" expr="'playExt_2'"/>
      <dialogstart src="'dtmf://'+ pbxExt +'#?pause=200&amp;duration=200'"
                  type="'application/x-senddtmf'"
                  dialogid="dialExtDlg_2"
                  connectionid="callid_2"/>
    </transition>


<!-- *** DTMF tones have finished playing, so we can bring in the first call leg out of hold *** -->
    <transition state="playExt_2" event="dialog.exit">
      <log expr="'-- Extension Dialed On Call #2 --'"/>
      <assign name="state0" expr="'stopHoldMusic_1'"/>
      <dialogterminate dialogid="holdMusicDlg_1"/>
    </transition>

<!-- *** Our caller has now reached the previously specified extension  ***-->
<!-- *** Congratulations. Your IVR application has just outsmarted a slightly dumber one *** -->
    <transition state="stopHoldMusic_1" event="dialog.exit">
      <log expr="'-- Call #1 Hold Music Stopped --'"/>
      <log expr="'-- Now Connecting Call Legs --'"/>
      <assign name="state0" expr="'bridging'"/>
      <join id1="callid_1" id2="callid_2"/>
    </transition>   

<!-- *** If call #1 fails we should just bail out entirely. Or not. Its really up to you. *** -->
    <transition state="calling_1" event="connection.failed">
      <log expr="'-- Call #1 Failed --'"/>
      <exit/>
    </transition>


<!-- *** If call #2 fails we realize that the PBX system has sensed our efforts to outwit it *** -->
<!-- *** Mission aborted. Drastic action is required. ***-->

    <transition state="calling_2" event="connection.failed">
      <log expr="'-- Call #2 Failed --'"/>
      <assign name="state0" expr="'call_2_failed'"/>
      <dialogterminate dialogid="holdMusicDlg_1"/>
    </transition>


<!-- *** Alert our first call leg of the news via a VXML dialog *** -->
    <transition state="call_2_failed" event="dialog.exit">
      <log expr="'-- Hold Music Stopped --'"/>
      <assign name="state0" expr="'playingCallFailed_1'"/>
      <dialogstart src="'callfailed.vxml'"/>                 
    </transition>


<!-- *** Time to gracefully exit, before the PBX system launches a counterattack ***-->
    <transition state="playingCallFailed" event="dialog.exit">
      <log expr="'-- Call Failed Dialog Played --'"/>
      <log expr="'-- So Sad...  Bye Bye --'"/>
      <disconnect/>
      <exit/>
    </transition>

<!-- *** Always have a backup plan.  *** -->
    <transition event="connection.disconnected">
      <if cond="callid_1 == event$.connectionid">
        <exit/>
      </if>
    </transition>

<!-- *** Just in case the PBX system has thermonuclear launch capabilities ***-->
    <transition event="error.*">
      <log expr="' AN ERROR HAS OCCURED: (' + event$.reason + ')'"/>
      <exit/>
    </transition>
  </eventprocessor>   

</ccxml>


Sample Code, Anyone?

Just in case you'd like the 'no-fuss, no-muss, show-me-the-money' code, you can download the whole thing by clicking right HERE!.




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

login
  F: Outbound Dialing  |  TOC  |  Limiting Call length  

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