VoiceXML

 

Using Cookies Page 5 of 6

From a developer perspective, you can think of the Tellme VoiceXML interpreter as a Web browser for the telephone. At a fundamental level, both a Web browser and the Tellme VoiceXML interpreter share the following characteristics:

In addition to these similarities, both types of browsers can exchange bits of information known as cookies. This article details how to use cookies and their limitations with respect to the Tellme VoiceXML interpreter.

Understanding HTTP

HTTP is a text-based, stateless request/response protocol. The client, typically a Web browser, sends a request, and the server, typically referred to as a Web or HTTP server, returns a response. Both the request and response include some headers as well as some additional data.

In the Web browser paradigm, the request data from the client might include the values a user entered into the fields of a form. The response data from the server typically includes HTML. That HTML might include another form, and the cycle starts all over again.

In the Voice browser paradigm, the request data from the VoiceXML interpreter might include the values a user uttered in response to one or more prompts in a dialog. The response data from the server typically include more VoiceXML to be executed by the VoiceXML interpreter.

Regardless of the type of client browser - Web or Voice, and regardless of the type of data returned by the server - HTML or VoiceXML - if the client and server communicate via HTTP, the headers are largely identical.

Understanding cookies

Cookies are an extension to the HTTP protocol whereby a Web server requests that the client, traditionally a Web browser, store a small amount of information on the machine on which the client is running. Each time the client sends another request to the server, it checks its jar of cookies, and sends the applicable cookies along with the request.

A cookie is a formatted string consisting of a name/value pair and some additional, optional attributes delimited by semi-colons. The following snippet shows three cookies. They each expire on July 18, 2001. The expires attribute will be further described below.

user_fname=Noah; expires=Wed, 18 Jul 2001 07:42:30 UTC
user_lname=Harris; expires=Wed, 18 Jul 2001 07:42:30 UTC
user_id=12345; expires=Wed, 18 Jul 2001 07:42:30 UTC

A name should not begin with a dollar sign ($). Both the name and value should be URL-encoded.

The name/value pairs are transmitted with the HTTP headers along with the Cookie or Set-Cookie header.

Cookie attributes

In addition to establishing a set of name/value pairs, you can also set a number of other attributes in association with a cookie. The following is a list of optional cookie attributes.

expires
The date and time when the cookie expires in Greenwich Mean Time (GMT). The format is: Wdy, dd-mmm-yyyy hh:mm:ss GMT. For example, "Mon, 16-07-2001 13:30:00 GMT." On the Tellme Platform, a cookie expires when the user's session ends, essentially when the user hangs up.
path
The subset of URLs to which the cookie applies. The cookie is sent if a substring of the requested URL matches the specified path.
domain
The domain in which the cookie is valid, beginning with a dot (.).
secure
A secure protocol is used to transfer the cookie data between the client and the server.
Usefulness of cookies

Not only can cookies be used to automatically share data between the client and the server, they can be used to share data between applications. If the applications reside on the same domain, you may have to set the path attribute. If the applications reside on a different domain, you will have to set the domain attribute to allow the alternate domain to access the cookie data.

Setting and retrieving cookies from VoiceXML

The Tellme VoiceXML interpreter exposes cookie functionality via JavaScript. The setCookie function allows you to set a cookie, and the getCookies function allows you to retrieve the collection of cookies applicable to the current document.

Setting cookies from VoiceXML

The Tellme VoiceXML interpreter exposes the setCookie function via JavaScript to allow the VoiceXML developer to add a cookie to the cookie jar applicable to the current domain or document. If the VoiceXML interpreter encounters an element such as submit or goto that sends data to the server, it checks the cookie jar and sends the appropriate cookies along with the request.

The setCookie function implemented by the Tellme VoiceXML interpreter allows you to set only a single name/value pair at a time. The following code example includes a helper function SetCookies that hides that implementation detail and allows you to call the function once with common values for the expires, domain, and path attributes if you choose to specify them. The example sets three cookies - a user identifier, a user password, and the user's automatic number identification (ANI).

<vxml>
<form id="add_cookies">
<block>
   <audio>setting cookies...</audio>
   <script>
      // create a hash table containing the name/value pairs to be transmitted 
      // by the VoiceXML interpreter as a cookie.
      var hCookies = {"user_id" : "12345", 
               "user_pin" : "4321", 
               "user_phone" : session.telephone.ani};

      SetCookies(hCookies); // call helper

      // Adds the contents of the hash (hCookies) to the cookie collection
      // dExpires - (optional) JavaScript date when the cookies are to expire.
      // sDomain - (optional) the domain to which the cookie applies
      // sPath    - (optional) the path to which the cookie applies
      function SetCookies(hCookies, dExpires, sDomain, sPath, bSecure)
      {
         var sExpires;
         if (dExpires)
         {
            sExpires = dExpires.toGMTString();
         }
   
         for (var sKey in hCookies)
         {
  	        var sCookie = escape(sKey) + "=" + escape(hCookies[sKey]);
  	        if (sExpires)
  	        {
  	           sCookie += ("; expires=" + sExpires);
  	        }
  	        if (sDomain)
  	        {
  	           sCookie += ("; domain=" + sDomain);
  	        }
   	        if (sPath)
  	        {
  	           sCookie += ("; path=" + sPath);
  	        }
  	        if (bSecure)
  	        {
  	          sCookie += ("; secure");
  	        }
 	  
            setCookie(sCookie);
         }
       }
   </script>
</block>
</form>
</vxml>

Getting cookies from VoiceXML

The Tellme VoiceXML interpreter exposes the getCookies function via JavaScript to allow the VoiceXML developer to retrieve the collection of cookies applicable to the current document.

The following code example retrieves the cookies applicable to the current document and prints them to the log:

<vxml>
<form id="dump_cookies">
<block>
   <audio>printing cookies to the log...</audio>
   <log><value expr="unescape(getCookies())"/></log>
</block>
</form>
</vxml>

The following helper function returns the specified cookie's value by name. If the cookie is not found, the function returns null.


function GetCookie(name)
{
   var cookies = getCookies();
   var search = name + "=";
   var iLen = cookies.length;
   if (iLen > 0) 
   {
      // find where cookie begins
      var begin = cookies.indexOf(search);
      if (begin != -1)
      {          
         begin += search.length;
         // search for the end of the value
         var end = cookies.indexOf(";", begin);
         if (end == -1)
         {
            // delimiter not found, so eat rest of cookie string
            end = iLen;
         }

         return unescape(cookies.substring(begin, end));
      }
   }

   return null; // cookie not found
}

Updating cookies from VoiceXML

Once you've established a cookie, you may need to update its value during the running of your application. To do so, simply call the setCookie function with the new value as shown in the following example.

<vxml>
<form id="update_cookie">
<block>
   <audio>updating cookie...</audio>
   <script>
     setCookie(escape("user_phone") + "=" + escape("6509309000"));
   </script>
</block>
</form>
</vxml>



    

Deleting cookies from VoiceXML

Although the Tellme VoiceXML interpreter automatically deletes cookies when the user's session ends, essentially when the user hangs up, you may need to delete a cookie during the course of your application. If, for example, during a session, your application navigates to another application within the same domain or with a another domain that you allow access to your cookie data, you may delete some cookies while saving others for use by the other application.

To delete a cookie, you need to specify its name and a value and the expires attribute with a value in the past.

The following example deletes the cookie named user_phone by calling a helper function named DeleteCookie:

<vxml>
<form id="delete_cookie">
<block>
   <audio>Deleting cookie...</audio>
   <script>
      DeleteCookie("user_phone");

      // delete the named cookie
      function DeleteCookie(sName)
      {
         // generate a GMT date in the past 
         var sPast = new Date("01/01/1980").toGMTString();
         // the value of the cookie is unimportant since it's to be deleted
         var sDelete = escape(sName) + "=0;expires=" + sPast;
         setCookie(sDelete);
      }
   </script>
</block>
</form>
</vxml>

Manipulating cookies on the server

Server-side architectures and APIs vary greatly. Most provide a cookie API that automatically format the Set-Cookie header when setting cookies and parse the Cookie header when retrieving cookies. You should consult the documentation for your server-side framework for details.

Setting cookies on the server

CGI scripts are the most fundamental API available for implementing functionality on the server. The following example demonstrates a Perl CGI script setting two cookies on the server and retrieving them using the getCookies function exposed by the VoiceXML interpreter.


# /usr/local/bin/perl -w
print "Content-type: text/xml\n";
print "Set-Cookie: user_fname=noah\n";
print "Set-Cookie: user_id=99999\n\n";
print <<EOF;
<vxml>
<form>
<block>
   <audio>Retrieving cookies</audio>
   <log><value expr="getCookies()"/></log>
</block>
</form>
</vxml>
EOF

While the example is contrived, it demonstrates how the client, the VoiceXML interpreter, and the server automatically handle transferring the specified data across the network. Other documents in the application can easily access the cookie collection by calling the getCookies function.

Retrieving cookies on the server

The following example demonstrates a Perl CGI that uses theCGI Cookie module to retrieve a cookie that was previously established on the client (via a call to setCookie from VoiceXML) or the server. In this example, the GetBalance function returns a fake balance. A real implementation might use the user id as a key in a database lookup.


# /usr/local/bin/perl -w
use CGI::Cookie;
# retrieve the cookie collection
my %cookies = fetch CGI::Cookie;
# retrieve the user_id cookie from the collection
my $user_id = $cookies{"user_id"};

# lookup some user data (e.g. account balance) based on the user's id
my $balance = GetBalance($user_id);

# return the data to the user
print "text/xml\n\n";
print <<EOF;
<vxml>
<form>
   <block>
      <audio>Your balance is $balance</audio>
      <goto next="main.vxml"/>
   </block>
</form>
</vxml>
EOF

# retrieve the user's account balance given their id
sub GetBalance
{
  my $user_id = @_;
  return "10000.00";
}



Cookie limitations

When accepted by Web browsers, cookies take up physical disk space and memory on the user's computer. As a result, Web browsers set limits on the size of a cookie, the total number of cookies, and the number of cookies allowed per domain. In addition, typical Web servers limit the amount of cookie data that can be passed between it and the Web browser.

The Tellme VoiceXML interpreter runs on hardware maintained by Tellme Networks, and while these machines have more resources available than your typical personal computer, Tellme must set cookie limits to ensure that those resources are available and evenly distributed. As a consequence, Tellme sets the following limitations on cookies:

 

Using Cookies Page 5 of 6