Volume 3, Issue 4 - July/August 2003
 
   
   
 

continued from page one...

Here's the sample code. Observe that I took a number of shortcuts. What? No sign in dialog?
I've also left it as an exercise to the reader to populate the 'messages' array and increment the 'msg_index' to iterate through the user's mailbox.

<vxml version="2.0"
xmlns="http://www.w3.org/2001/vxml">

<script>
<![CDATA[
// forward/reverse increments
var FORWARD = 5000;
var REVERSE = -5000;
var FUDGE = 3000; // fudge factor to compensate for reco lag
var messages = []; // TODO: populate this an ordered list of the user's v-mail messages
var msg_index = 0; // TODO: Increment this after each message is played

/*
Given:
start - the approximate time when the audio was queued
increment - the increment to move forward or backward in the audio
oldOffset - the previous offset into the audio

Calculate and return the new offset.
*/
function CalcOffset(start, increment, oldOffset)
{
var elapsed = (new Date() - start);
var newOffset = oldOffset + elapsed + increment - FUDGE;
return ((newOffset < 0) ? 0 : newOffset);
}
]]>
</script>

<link event="vmail.onquit">
<grammar mode="voice" version="1.0" root="r" type="application/srgs+xml">
<rule id="r" scope="public">
<one-of>
<item>quit</item>
</one-of>
</rule>
</grammar>
</link>

<catch event="vmail.onquit">
goodbye.
<disconnect/>
</catch>

<catch event="connection.disconnect.hangup">
<log>caught hangup</log>
</catch>

<catch>
<log>caught unexpected event <value expr="_event"/></log>
I'm sorry, but an error has occurred.
Please try again later.
<disconnect/>
</catch>

<form id="welcome">
<block>
Welcome to the voice mail system.
<break time="500ms"/>
<goto next="#menu"/>
</block>
</form>

<form id="menu">
<field name="cmd">
<prompt cond="messages.length == 1">
You have 1 new message.
<break time="500ms"/>
To hear your message, say 'play message' or press 1.
</prompt>
<prompt cond="messages.length &gt; 1">
You have <value expr="messages.length"/> new messages.
To hear your messages, say 'play messages' or press 1.
</prompt>
<prompt>
<break time="300ms"/>
To hear your mailbox options, say 'options' or press 2.
</prompt>

<grammar mode="voice" version="1.0" root="r" type="application/srgs+xml">
<rule id="r" scope="public">
<one-of>
<item>play messages<tag>1</tag></item>
<item>options<tag>2</tag></item>
</one-of>
</rule>
</grammar>

<grammar mode="dtmf" version="1.0" root="r" type="application/srgs+xml">
<rule id="r" scope="public">
<one-of>
<item>1</item>
<item>2</item>
</one-of>
</rule>
</grammar>

<catch event="noinput nomatch">
Sorry. I didn't get that.
<reprompt/>
</catch>

<catch event="noinput nomatch" count="3">
Sorry we're having trouble.
Please try again later.
<disconnect/>
</catch>

<filled>
<if cond="1 == cmd">
<goto next="#play"/>
<elseif cond="2 == cmd"/>
Sorry. This feature is currently unavailable.
<clear namelist="cmd"/>
</if>
</filled>
</field>
</form>

<form id="play">
<!-- track approx. time when prompt is queued -->
<var name="start"/>
<var name="curOffset" expr="0"/> <!-- track offset into clip -->

<block name="init">
<assign name="start" expr="new Date()"/>
<!-- BUGBUG: In a real application, you would parameterize this -->
First message.
<break time="300ms"/>
</block>

<field name="msg">

<property name="timeout" value="0s"/>
<property name="termchar" value=" "/>
<property name="inputmodes" value="dtmf"/>

<link event="vmail.forward">
<grammar mode="dtmf" version="1.0" root="r" type="application/srgs+xml">
<rule id="r" scope="public">
<one-of>
<item>3</item>
</one-of>
</rule>
</grammar>
</link>

<link event="vmail.reverse">
<grammar mode="dtmf" version="1.0" root="r" type="application/srgs+xml">
<rule id="r" scope="public">
<one-of>
<item>1</item>
</one-of>
</rule>
</grammar>
</link>

<link event="vmail.stop">
<grammar mode="dtmf" version="1.0" root="r" type="application/srgs+xml">
<rule id="r" scope="public">
<one-of>
<item>7</item>
</one-of>
</rule>
</grammar>
</link>

<link event="help">
<grammar mode="dtmf" version="1.0" root="r" type="application/srgs+xml">
<rule id="r" scope="public">
<one-of>
<item>0</item>
</one-of>
</rule>
</grammar>
</link>

<catch event="vmail.forward">
<log>old offset: <value expr="curOffset"/></log>
<assign name="curOffset" expr="CalcOffset(start, FORWARD, curOffset)"/>
<log>new offset: <value expr="curOffset"/></log>
<assign name="start" expr="new Date()"/>
<reprompt/>
</catch>

<catch event="vmail.reverse">
<log>old offset: <value expr="curOffset"/></log>
<assign name="curOffset" expr="CalcOffset(start, REVERSE, curOffset)"/>
<log>new offset: <value expr="curOffset"/></log>
<assign name="start" expr="new Date()"/>
<reprompt/>
</catch>
<catch event="vmail.stop">
stop
<goto next="#again"/>
</catch>

<catch event="noinput">
<goto next="#again"/>
</catch>

<catch event="nomatch">
<!-- may want to provide your user with help on valid DTMF here -->
Sorry I didn't get that.
<throw event="help"/>
</catch>

<help>
Press 1 to rewind. Press 3 to fast forward. Press 7 to stop.
Resuming message.
<break time="300ms"/>
<log>old offset: <value expr="curOffset"/></log>
<assign name="curOffset" expr="CalcOffset(start, 0, curOffset)"/>
<log>new offset: <value expr="curOffset"/></log>
<assign name="start" expr="new Date()"/>
<reprompt/>
</help>

<catch>
<log>unexpected event <value expr="_event"/></log>
Sorry. We are experiencing technical difficulties. Please try again later.
<disconnect/>
</catch>

<prompt>
<!-- ask the server to return the .wav of the current message -->
<audio expr="'/cgi-bin/playmessage.cgi?msg_id=' + messages[msg_index] + '&amp;offset='
+ curOffset"/>
</prompt>

<!-- empty grammar; all reco is performed via links -->
<grammar mode="dtmf" version="1.0" root="r" type="application/srgs+xml"/>

</field>

</form>

<form id="again">
<field type="boolean" name="yn">
<prompt>Do you want to hear this message again?</prompt>

<catch event="noinput nomatch">
Sorry. I didn't get that.
<reprompt/>
</catch>

<catch event="noinput nomatch" count="3">
Sorry we're having trouble.
Please try again later.
<disconnect/>
</catch>

<filled>
<if cond="yn">
<goto next="#play"/>
<else/>
Returning to the main menu.
<break time="300ms"/>
<goto next="#menu"/>
</if>
</filled>
</field>
</form>
</vxml>

back to the top

Copyright © 2001-2002 VoiceXML Forum. All rights reserved.
The VoiceXML Forum is a program of the
IEEE Industry Standards and Technology Organization (IEEE-ISTO).