CCXML 1.0-W3C Development Guide Home  |  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.

Note: As of 12/31/08, the ability to play a dialog to a conference is unsupported.  This feature will be available in a future build of Prophecy 9.

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
jassy0809
3/20/2009 6:22 AM (EDT)
Hi,

I need clarification to how to achieve the following scenario (Outbound dialing).

Caller A is called first.  Once caller A accepts the call, caller B is dialed.  Once caller B accepts, join the 2 connections.  Till here i am able to achieve.
I want to start a dialog (which has a silent prompt) and collect some digits from Caller A and do some manipulations.

How do i achieve this? How do i start a dialog after A and B are conferenced?

Thanks in advance.

Reg's
Jassy
voxeoJeffK
3/20/2009 6:37 AM (EDT)
Hello,

Currently there is no way to play a dialog to a conference. This issue is being addressed in Prophecy version 9, but what you can do is to open another call-leg to a separate VoiceXML application that joins the conference just as a person. The VoiceXML script will be able interact with the entire conference, and not just caller A though.

regards,
Jeff Kustermann
Voxeo Support
jassy0809
3/20/2009 6:43 AM (EDT)
Hello Jeff,

Thanks for the timely suggestion.  I will try it out as you mentioned.

Reg's
Jassy
SSAUK_Avanti
12/21/2009 6:03 AM (EST)
Hello.
Your sample code link does'nt seem to work.
Arti
MattHenry
12/21/2009 6:35 AM (EST)


Hi there,

Can I assume that you mean this one?

You wanted it, you got it right [url=http://docs.voxeo.com/opensource/ccxml_Whisper10.zip]HERE[/url]

If so, this link worked fine from here; can you please re-verify?

Thanks,

~Matt
SSAUK_Avanti
12/22/2009 12:41 AM (EST)
Thanks.
It worked this time.
Arti
baber.waqas
7/7/2010 4:19 PM (EDT)
Hi,

i want to achieve the following scenario (Outbound dialing).

Caller A called the application first . After call accepted the application ask caller A to enter some pin code or some data then Application Call Caller B and ask him if he wants to talk with the caller A or not if yes call legs will be joined. after Caller A finish talking with caller B he hangs up , i want my application alive after the hangup from Caller A and application then ask Caller B some questions please tell if this is possible and how do i achieve the last part( After detecting hangup from caller A application will ask questions from Caller B)

Thanks in advance

Baber Waqas
jdyer
7/7/2010 10:40 PM (EDT)
Hello Baber,

This is most certainly possible, and in fact the preceding tutorial should be a great starting point for this type of application. Is there a particular point you are having issue with here, or were you perhaps looking for professional services to help author your application?  Please let us know, as we are most certainly standing by for your update at this time.

Regards,

John Dyer
Customer Engineer
Voxeo Support
mtatum111
8/3/2010 9:17 AM (EDT)
In the whisper.vxml sample that you have,you have a static msg played.  Is there a way to play a msg that will be dynamic.  Such as an employee number which will be different with each call?  Thanks for any suggestions.
VoxeoDustin
8/3/2010 3:29 PM (EDT)
Hey,

Sure. All you'd need to do is use the namelist attribute of <dialogstart> to pass the dynamic data you want to the VoiceXML dialog and reference it within VoiceXML using the session.connections.ccxml.values object like so:

CCXML
-----
<transition event="connection.connected">
  <var name="foo" expr="session.values.foo"/>
  <var name="bar" expr="session.values.bar"/>
  <dialogstart src="'my_vxml.xml'" namelist="foo bar"/>
</transition>

VXML
----
<form>
<block>
  <prompt> Hello, Mr. <value expr="session.connections.ccxml.values.foo"/>, your account balance is <value expr="session.connections.ccxml.values.bar"/>.
  </prompt>
</block>
</form>

The session.values object in the above CCXML is propagated from any name/value pairs that are passed into the invoked document or sent to the token API:

http://api.voxeo.net/SessionControl/CCXML10.Start?tokenid=mytoken&foo=smith&bar=400

Let me know if this is helpful.


Regards,
Dustin Hayre
Solutions Engineer
Voxeo Corporation
petertv2000
8/16/2010 2:01 PM (EDT)
How do I modify the code so that the application start to call Caller A instead of Caller A calling the application first? Once the caller A is picked up, the application can start to call Caller B.
VoxeoBrian
8/16/2010 4:50 PM (EDT)
Hello,

Starting sessions outside of them being created via an inbound call is what we refer to as token initiated outbound calls.

You can review this here:

http://docs.voxeo.com/ccxml/1.0-final/t_7ccxml10.htm

While this example does not show in full how to bridge call legs during a token initiated call, you can certainly gain the concepts of how this is done from this whisper tutorial and what is shown in the above document.

Regards,

Brian F.
BarryH
1/5/2012 9:51 AM (EST)
Need to provide notification to a CSR of a callers account/idetfication number prior to call being transfered to a CSR, can this script read a variable to a CSR prior to them accepting the call
voxeoJeffK
1/5/2012 1:28 PM (EST)
Hello,

You will want to pass the variable data to the VXML whisper dialog. For example here where the dialog is started:

  <dialogstart src="'whisper.vxml'"/>

you could pass over CCXML variables via the "namelist" attribute:

    <dialogstart src="'whisper.vxml'" namelist="accountID" />

Then in the VXML document you grab that data as:

  <var name="theAccountID" expr="session.connection.ccxml.values.accountID"/>

You can then have that variable data as part of a prompt to the agent.

Regards,
Jeff Kustermann
Voxeo Corporation
BarryH
1/5/2012 3:15 PM (EST)
is it possible to use whisper as part of a blind transfer or does the call have to be bridged?
VoxeoDante
1/5/2012 3:23 PM (EST)
Hello Barry,

I am assuming that by Blind transfer, you mean that the platform will no longer be involved what so ever after the transfer starts.  If that is the case, then the answer would be no.  In order for the whisper to work you would need to have the platform involved to play the message to the recipient.  In the case of a blind transfer in this manner, you would drop the platform as soon as the transfer goes out.

I hope this answers your questions.

Regards,
Danté Vitulano
Hosted Solutions Engineer

[url=http://www.voxeo.com/university/home.jsp]
[img=http://www.voxeo.com/images/logos/VoxeoUnivLogo.png/]
[/url]
[b][color=blue]Interested in Training? Visit the Voxeo University Page to Learn More![/color][/b]

login
  Advanced Answering Machine Detection  |  TOC  |  Unjoin via termdigit  

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