VoiceXML 2.1 Development Guide Home  |  Frameset Home

  tutorial DTMF Recognition  |  TOC  |  tutorial Subgrammars  

Tutorial: JavaScript and VoiceXML

This tutorial describes how to use JavaScript in your VoiceXML application to perform client-side processing. When we're done, you'll have a basic understanding of how to include JavaScript functions in your applications and how to use those functions to enhance your VoiceXML.

This tutorial builds on lessons learned in Tutorial 7. If you haven't completed that tutorial, you'll need to go through it first.

Note: ECMAScript is a standard scripting language based on JavaScript 1.1. The VoiceXML specification makes several references to ECMAScript. JavaScript is currently used as the ECMAScript implementation on the Voxeo network.

Step 1: Creating our initial VoiceXML document



<?xml version="1.0" encoding="UTF-8"?>
<vxml version = "2.1" >

<meta name="maintainer" content="YOUREMAILADDRESS@HERE.com"/>

  <form id="Hello World">
    <block>
    <prompt>
      Hello there. The caller i d number is <value expr="session.callerid"/>
      The called i d of this application is <value expr="session.calledid"/>
    <prompt>
    </block>
  </form>
</vxml>


You should be familiar with this code from our earlier tutorial on Caller/CalledID. It simply grabs the session variables for these values, and speaks these values back to the caller. Hey, wait a minute...........when I run this script it tells me my caller ID is "eight billion, three hunderd fourteen million ..." What's going on? That's not my phone number!

Ohhhh, wait a second, I know what's going on. It is reading my phone number like a number, not a digit-by-digit value like we would be accustomed to hearing. We covered how to use the <say-as> elements so that our phone number was spoken as a set of digits, but just to illustrate how JavaScript works in your VoiceXML application, we will tackle this problem from another direction.


Step 2: Creating the JavaScript function

Let's try a little trick so that our phone number is spoken as a stream of digits instead of as a number. The trick is to add a space between each digit in the phone number. That way each digit is spoken separately and not as one large number. But... how are we going to do that with VoiceXML?

We are going to use VoiceXML's <script>  element to write a JavaScript function. This function will add the spaces so that we can hear our phone number the way it should be, instead of "eight billion...".

As mentioned in our Introduction to this tutorial, the <script> element allows you to include scripting language code in your application. In this case, the scripting language is JavaScript. Code contained in the <script>  element is executed on the client side, so we don't have to go to the back-end server for such a simple task. Each <script>  element follows the same scoping rules as other elements, meaning, the <script>  element is executed in the scope of the containing element.


<script>
<![CDATA[
    function sayasDigits(number)
    {
      var digitNumber = number.charAt(0);
      for(var i = 1; i < number.length; i++)
      {
        digitNumber += ' ' + number.charAt(i);
      }
      return digitNumber;
    }
  ]]>
</script>


As you can see, the JavaScript part of the code is very straight forward. But what is that CDATA thing at the top of the script? We use the CDATA directive so that our script can contain characters that are normally reserved for XML syntax usage. XML uses certain characters, such as the 'less-than' sign, "<", as part of the syntax, and not as part of the content. Since our script uses one of these characters we need to use this CDATA directive so that these reserved characters are interpreted as content, and not as part of the syntax....otherwise, would likely see a nasty XML parsing error when viewing the code in a web browser.


Step 3: Using the JavaScript function in VoiceXML elements

Okay, now that we have defined this nifty little JavaScript function, how do we use it? You may have noticed that several VoiceXML elements have an 'expr' attribute. Heck, you may even have used the 'expr' attribute before. Well, the 'expr' attribute can contain any valid JavaScript expression. So, we can use our function in the 'expr' attribute of various VoiceXML elements. Let's see how its done.


<prompt>
  Hello there. The caller i d number is:
  <value expr="sayasDigits(session.callerid)"/>
</prompt>


Here, we are calling the function 'sayasDigits' and passing in the caller ID value. The function adds the spaces between each of digit of the number and returns to us the newly formatted value. As the text-tospeech engine will read off any numeric value that is space-delimited as a digit, we are in the clear. The value of the 'expr' attribute, in this case the new 'number' is then spoken to the caller.


Step 4: The complete application

We have all the necessary pieces now, so lets assemble them into a complete VoiceXML application.


<?xml version="1.0" encoding="UTF-8"?>
<vxml version = "2.1">

<meta name="maintainer" content="YOUREMAILADDRESS@HERE.com"/>
  <form id="HelloWorld">
    <block>
      <script>
        <![CDATA[
          function sayasDigits(number)
          {
            var digitNumber = number.charAt(0);
            for(var i = 1; i < number.length; i++)
            {
              digitNumber += ' ' + number.charAt(i);
            }
            return digitNumber;
          }
        ]]>
      </script>
    <prompt>
      Hello there. The caller i d value is: <value expr="sayasDigits(session.callerid)"/>
      The called i d of this application is: <value expr="sayasDigits(session.calledid)"/>
    </prompt>
    </block>
  </form>
</vxml>



Step 5: upload, and try it out

All that remains is to upload the new VoiceXML application, provision a number, and call the associated number to hear the results.

Download the Code!

  Source code


What was just covered:





  ANNOTATIONS: EXISTING POSTS
alvaro
7/19/2006 8:01 AM (EDT)
Hi! I'm Alvaro and I would like to know how to create a text file(.txt) in an VoiceXML application to store data. May someone help me? If it's possible I would prefer a practical example with a little explanation. I am novate. Thanks.
VoxeoDenise
7/19/2006 2:24 PM (EDT)
Hey Alvaro,

In order to write to a text file using VoiceXML, you will need to implement some sort of Server Side Language such as PHP, ASP, JSP, or Cold Fusion.

Hopefully this will help to get you started.  Please feel free to contact us if you have any further questions.

Regards,
Denise Rodriguez
Voxeo Extreme Support
alvaro
7/20/2006 6:15 AM (EDT)
Thanks for your answer.
Now a have another doubt. I want to store data in this URL: http://localhost/....../reserva.php?info1=..&info2=..&info3=.. and I have tried with the submit element but it doesn`t work and I would like to know if there is another element or another way using submit to do this. With submit I have use the "next" attribute and/or the "namelist" attribute.
Don.Lawson
7/20/2006 10:47 AM (EDT)
Alvaro,
The namelist attribute specifies a space-separated list of variables to send to the URI indicated by the next or expr attributes. Note that if the namelist attribute is left unspecified, then all input-item variables will be submitted to the destination URI.

So for your case

<submit next="http://localhost/....../reserva.php" namelist="info1 info2 info3" />

And of course if you leave the namelist attribute out of it, all of the variables will be past along.  You can also specify a method attribute to make it a POST request.  It defaults to GET so if your php script is expecting POST you will need to specify this.  Also in your php script make sure you are using the $_REQUEST global variable instead of $_POST as it will eliminate any error related to this.


  Don Lawson
  Voxeo Support
anil.s
5/9/2008 8:39 AM (EDT)
Hi,
I am Anil.. I am not able to figure it out why i am getting the following error. Please post me in which scenarios generally the voice xml end up with these kind of errors.

    "Cannot read property "termchar" from undefined (JSI#1)"

Thanks,
Anil
voxeojeremyr
5/9/2008 1:28 PM (EDT)
Hi Anil,

I am not familiar with that error.  I think that you are trying to set the termchar property and that there is some kind error when trying to set the value.

To help us troubleshoot this more effectively, could you open an account ticket and attach your code and a debugger log?

Thanks,
Jeremy Richmond
Voxeo Support
dhawansalil
9/18/2008 1:23 AM (EDT)
Hello
How can i get all the parameters of vxml call onto a jsp.Also i need to extract unique call id for the vxml application?
voxeoJeffK
9/18/2008 2:10 AM (EDT)
Hi,

That is usually accomplished by using the "namelist" attribute of the <submit> tag:

  <submit next="http://MyServer.com/MyPage.asp" namelist="var1 var2"  method = "get"/>

We have a tutorial exploring that topic here:

http://docs.voxeo.com/voicexml/2.0/qs_vars.htm

For your question on callerid, I think you'll find everything you need here:

http://docs.voxeo.com/voicexml/2.0/ani_dnis.htm

hope that helps,
Jeff K.
yogeshp
12/11/2008 4:31 AM (EST)
Hi ,
  1.Can i use ajax in voice aml application for database interaction ?
  2.How i can debug javascript error in voice xml application ?

Yogesh Patil
 
   
voxeoAlexBring
12/11/2008 5:25 AM (EST)
Hello,
    To answer your questions:
1) Unfortunately our applications do not support direct use of ajax within the applications, however you can use the [url=http://docs.voxeo.com/voicexml/2.0/data.htm]DATA[/url] element in VoiceXML to help achieve some communication between your applications and some ajax script.

2) Sadly our application debugger does not offer any specific error handling for javascript. The only errors you may see in the debugger from javascript are parse and invalid parameter errors.

Please let us know if you have any more questions, and we will be happy to assist.

Regards,

Alex Bring
Voxeo Support
premisenational
2/7/2009 2:16 PM (EST)
Hello:

We need to add date-and-time contingent logic to our Voxeo VXML application (specifically, do a transfer out call to live operator during business hours, but offer other menu items on nights and weekends).

Do you have any code samples with contingent logic based on time and date?

Thanks.

Richard W.

VoxeoDustin
2/7/2009 2:52 PM (EST)
Hey Richard,

This is pretty simple to do with the ECMAScript getHours() function of the Date object. This simply returns an integer that is the current hour. Since our servers are GMT, we make a quick adjustment for timezone, then run a little conditional logic to determine if it's during business hours:

<?xml version="1.0" encoding="UTF-8" ?>
<vxml version="2.1">

<var name="timezone" expr="-5"/>
<!-- timezone adjustment in relation to GMT. e.g. -5, +2, etc -->
<var name="time" expr="new Date().getHours() + timezone"/>

<var name="open_hour" expr="8"/>
<var name="close_hour" expr="17"/>
<!-- open and close hours in 24 hour format -->

<form>
  <block>
          <log expr="'**** HOUR = ' + time"/> 

    <if cond="time > open_hour &amp;&amp; time < close_hour">
      <goto next="#Transfer"/>
    <else/>
      <prompt> Please call back between <value expr="open_hour"/> A M and <value expr="close_hour"/> P M </prompt>
    </if>
    <log expr="'**** HOUR = ' + time"/>
  </block>
</form>

<form id="Transfer">
  <block>
    <prompt> Transferring your call </prompt>
  </block>
</form>

</vxml>

Let me know if this is what you're looking for.

Cheers,
Dustin Hayre
Customer Support Engineer 2
Voxeo Support
montgom
3/13/2009 3:37 PM (EDT)
I've been enjoying the tutorials tremendously and have gleaned a lot of useful information. I'm trying to parse a URL for the parameter value for use as the SRC element in a DATA tag.  Simply put I'm relying on the VXML file to call back to the web server for the order details. If I use a static src="AA99.xml" or a SRC="www.something.com/AA99.xml" it works great. But the name of the file will be different each time, hence my need to parse the URL.  Here's the code without the DATA tag etc. 

<?xml version="1.0" encoding="utf-8"?>
<vxml version="2.1">
<form id="F1">
  <block>
    <script>
        <![CDATA[
function getQueryVariable(variable) {
  var query = window.location.search.substring(1);
  var vars = variable.split("&");
    for (var i=0;i<vars.length;i++) {
      var pair = vars[i].split("=");
        if (pair[0] == variable) {
          return pair[1];
        }
      }
      alert('Query Variable ' + variable + ' not found');
    }
    ]]>
    </script>
<!-- use the calling URL to fetch the details -->
<var name="parse_url" expr="getQueryVariable('x')"/>
<prompt>the value of parse u r l is <value expr="parse_url"/>
</prompt>
</block>
</form>
</vxml>

I'm using Prophecy and using this input for Route 1 URL: http://127.0.0.1:9990/order_03.xml?x=AA99.xml
All I'm trying to get from the script is AA99.xml which I'll use to obtain order details from my web server.  Is there a better way?  Like an application or session variable that I've missed?  Cheers. 

Mike
VoxeoDustin
3/13/2009 4:03 PM (EDT)
Hey Mike,

CCXML does support session creation by passing in a URI, however this only works on an on-premise solution and for outbound calling.

The simplest way to handle this in VoiceXML may be to leverage a little bit of server-side to grab the URI from the querystring:

<?xml version="1.0"?>
<vxml version="2.1">
<var name="vxmlURI" expr="<?php echo $_REQUEST[x]?>"/>

<form>
<block>
  <goto expr="'http://myserver.com/' + vxmlURI"/>
</block>
</form>
</vxml>

Let me know if we can be of further assistance.

Cheers,
Dustin Hayre
Customer Support Engineer 2
Voxeo Support
touqeermuhmmad
4/14/2010 5:20 AM (EDT)
Hi,

Can i use webservice using javascript in vxml document

Kind Regards,
voxeoblehn
4/14/2010 2:33 PM (EDT)
Hello,

Webservices are rather "heavy" (comparatively speaking), and in most cases not a suitable technique to use for gathering data from an XML nodeset generally speaking. The use of server side scripting or the [link=http://docs.voxeo.com/voicexml/2.0/data.htm]<data>[/link] tag (if client-based scripting is really needed) is in most cases more suitable, let alone much easier to use and a much more proven technique in our environment.

This being said, I do have one example of using SOAP to get at node data, in hopes that it will help:

<?xml version="1.0" encoding="UTF-8" ?>
<vxml version="2.0">

<meta name="maintainer" content="madge@palmolive.com"/>


<form id="health">
<block >
  <script>
  <![CDATA[
  var stockQuoteWS =  Voxeo.SOAPClient.loadWSDL("http://ws.cdyne.com/delayedstockquote/delayedstockquote.asmx?wsdl");
  var stockQuoteAAPL = stockQuoteWS.getQuote("AAPL","0");
  var stockQuoteGOOG = stockQuoteWS.getQuote("GOOG","0");
  ]]>
  </script>

  <prompt>
  Apple is trading at <value expr="stockQuoteAAPL.getLastTradeAmount()"/>.
  <break/>
  Apple P. E. is <value expr="stockQuoteAAPL.getPE()"/>.
  <break/>
  Google is trading at <value expr="stockQuoteGOOG.getLastTradeAmount()"/>.
  <break/>
  Google P. E. is <value expr="stockQuoteGOOG.getPE()"/>.
  </prompt>
</block>
</form>

</vxml>


Two things to keep in mind:


1) Using a methodname within a SOAP request must follow strict ECMA naming conventions. To illustrate, attempting to call a 'stockQuoteWS.GetQuote' method will not be acceptable, and the developer should use a lowercase character for the method, (stockQuoteWS.getQuote)

2) HTTP cookies are not currently supported on SOAP requests. We do plan on addressing this issue in the future, however.

My honest suggestion is to use server side logic if you intend on fetching large amounts of data regularly within the application, just to reduce client-side application overhead, but this decision is ultimately yours to make: you know your goals much better than we would presume to, and the best path to achieving it is the one that feels the most comfortable to you.

Hope this helps.

Brian Lehnen
Voxeo Support
qasimzee
12/6/2010 2:07 AM (EST)
<prompt> tag is not being closed in the top code snippet
voxeomlucas
12/7/2010 2:54 AM (EST)
Hi there,
I am not sure that I fully understand your question.

Are you saying that the code provided above:
[code]
<?xml version="1.0" encoding="UTF-8" ?>
<vxml version="2.0">
<meta name="maintainer" content="madge@palmolive.com"/>
<form id="health">
<block >
  <script>
  <![CDATA[
  var stockQuoteWS =  Voxeo.SOAPClient.loadWSDL("http://ws.cdyne.com/delayedstockquote/delayedstockquote.asmx?wsdl");
  var stockQuoteAAPL = stockQuoteWS.getQuote("AAPL","0");
  var stockQuoteGOOG = stockQuoteWS.getQuote("GOOG","0");
  ]]>
  </script>
  <prompt>
  Apple is trading at <value expr="stockQuoteAAPL.getLastTradeAmount()"/>.
  <break/>
  Apple P. E. is <value expr="stockQuoteAAPL.getPE()"/>.
  <break/>
  Google is trading at <value expr="stockQuoteGOOG.getLastTradeAmount()"/>.
  <break/>
  Google P. E. is <value expr="stockQuoteGOOG.getPE()"/>.
  </prompt>
</block>
</form>
</vxml>
[/code]

has an issue with not closing a <prompt> tag?
I double checked it and tested it in a sample application and it seems to work fine.
Perhaps I mis-understood your question or am testing it differently, please elaborate on this so I can better help you resolve this issue.

Regards,
Matt Lucas
Voxeo Support
ladydozo
3/29/2012 9:28 PM (EDT)
Hello expert: I have 2 questions about calling javascript inside vxml.

Thanks in advance!

1. If inside my java script, I have alert("ss") statement.
how does it handle in vxml?

2. If inside my java script , i have calls like
xmlhttp = new XMLHttpRequest();
    var URL= "http://xxx/xxxx/xxxxx";
            xmlhttp.open('GET',url,true);
            xmlhttp.send(null);
            xmlhttp.onreadystatechange = function() {
                 
            var xmlDoc = xmlhttp.responseXML;
some more processinf of xml and returns some values
etc
          }





Can this be handled by vxml?
 
VoxeoDante
4/3/2012 12:51 PM (EDT)
Hello Ladydozo,

Unfortunately, I do not believe that either of these implementations will work in VXML.  See notes below;

"1. If inside my java script, I have alert("ss") statement.
how does it handle in vxml?"

[li]The alert statement would not produce any result in VXML.  At best you would not get anything, but the more likely scenario would be a failure.[/li]

"2. If inside my java script , i have calls like
xmlhttp = new XMLHttpRequest();
    var URL= "http://xxx/xxxx/xxxxx";
            xmlhttp.open('GET',url,true);
            xmlhttp.send(null);
            xmlhttp.onreadystatechange = function() {
                 
            var xmlDoc = xmlhttp.responseXML;
some more processinf of xml and returns some values
etc
          }

}  "

[li]XMLHttprequest is not supported in VXML and this code would certainly fail.[/li]

I am not exactly certain what you are trying to accomplish here, but if you are looking to pull in some XML data into your application via VXML, you can do this with the VXML <data> element.  It has support for both DOM and E4X and will hopefully fit your needs.

If you can give us any additional information on what you are looking to do here, I can make some more specific comments on the project.

I hope this helps!

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]
yberuh
4/4/2012 1:25 PM (EDT)
I'm trying to construct a Date object representing a particular date. The following is throwing an error:
new Date(79,5,24)

The question is, which constructor should I use to build a date object that represents a date other than the current date, and how?

Thanks
VoxeoDante
4/9/2012 1:35 PM (EDT)
Hello yberuh,

I would actually think what you are doing would work.  Would you be able to send over a sample document for what you are trying to do so that we can determine where the error comes in and what to do about it?

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
  tutorial DTMF Recognition  |  TOC  |  tutorial Subgrammars  

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