IVR – with ASP.NET

Hi all, Today I would like to show a small example of interacting with VXML (defines a markup based standard for IVR) and ASP.NET. In this post I will create a “create new account” scenario that asks the caller to input Card and Pin Number using his phone. Input modes can be of speech or dtmf (Dual Tone Multi Frequency) i.e. key-press. You can jump start your VXML project by adding an XML file in your existing ASP.NET website. Here is the code from my account.xml

<?xml version=”1.0″ encoding=”utf-8″ ?>
<!– Includig the following DOCTYPE can assist you a lot for writing valid VXML syntax –>

<!DOCTYPE vxml PUBLIC “-//BeVocal Inc//VoiceXML 2.0//EN” “http://cafe.bevocal.com/libraries/dtd/vxml2-0-bevocal.dtd”>

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

<property name=”inputmodes” value=”dtmf” /> <!– set input mode to dtmf only i.e. keypress –>

<var name=”varCardNumber”/> <!– global Variable to store CardNumber entered by caller –>

<var name=”varPinNumber”/> <!– global Variable to store PinNumber entered by caller –>

<!– start of form that contains tags/logic to get Card and Pin number –>

<form id=”frmCreateAccount”>

<!– Card Number form feild that requires 7 sigits –>

<field name=”iCardNumber” type=”digits?length=7″>

<!– Text spoken to the caller in robotic voice using Text-To-Speech engine –>

<prompt>

Enter your new seven digit card number

</prompt>

<!– if user dosent input, this deals with 1st and 2nd attempts –>

<noinput count=”1″>

<prompt>

Your identification number is the seven digit number on the front of your membership card.

</prompt>

<reprompt/>

</noinput>

<!– if user inputs but its not of type digit or less or greater than 7. 1st and 2nd attempt –>

<nomatch count = “1″>

<prompt>

Your identification number must be seven digits. Try again.

</prompt>

<clear namelist=”iCardNumber”/>

<reprompt/>

</nomatch>

<!– This block handles 3 attempts of noinput or nomatch at one place.

We have noinput count=”1″ and nomatch count = “1″ this has: event=”noinput nomatch” count=”3″

2nd false attempts for noinput and nomatch will be handled as 1st attempt

–>

<catch event=”noinput nomatch” count=”3″>

<prompt>

Please try again later. Goodbye

</prompt>

<exit/> <!– exit from System, drop call –>

</catch>

<!– if the user entered valid CardNumber assign value to global cardnumber variable –>

<filled>

<assign name=”document.varCardNumber” expr=”iCardNumber” />

</filled>

</field>

<!– Same procedure for Pin Number –>

<field name=”iPinNumber” type=”digits?length=4″>

<prompt>

Enter your new four digit pin number

</prompt>

<noinput count=”1″>

<prompt>

Your pin number is the four digit number on back of your card.

</prompt>

<reprompt/>

</noinput>

<nomatch count = “1″>

<prompt>

Your pin number must be four digits. Try again.

</prompt>

<clear namelist=”iPinNumber”/>

<reprompt/>

</nomatch>

<catch event=”noinput nomatch” count=”3″>

<prompt>

Please try again later. Goodbye

</prompt>

<exit />

</catch>

<filled>

<assign name=”document.varPinNumber” expr=”iPinNumber” />

</filled>

</field>

<!– Simulate wait –>

<block name=”blkSendData”>

<prompt>

Creating your account. Please wait…

</prompt>

<!– Submit data to the .ASPX page with 2 variables: varCardNumber varPinNumber –>

<submit next=”account.aspx” namelist=”varCardNumber varPinNumber” method=”post” />

</block>

</form>

</vxml>

So our VXML file is complete now let’s have look at the account.aspx code behind first.

using RVDataSetTableAdapters;

public partial class account : System.Web.UI.Page

{

public long lCardNumber = 0;

public int iPinNumber = 0;

public long lUserID = 0;

protected void Page_Load(object sender, EventArgs e)
{

// set the content-type of the page

Response.ContentType = “text/xml”;

Response.AddHeader(“pageheader”, “Content-type: text/xml”);

Response.Write(“<?xml version=\”1.0\”?>\n”);

}

protected bool AddNewUser(long CardNumber, int PinNumber, Guid Greeting)

{

using (UserTableAdapter taUser = new UserTableAdapter())

{

/* call AddNewUser from the UserTableAdapter present in the tpyed-dataset that returns

newly generated UserID */

lUserID = Convert.ToInt64(taUser.AddNewUser(CardNumber, PinNumber, null, Greeting));

if (lUserID > 0) { return true; }

}

return false;

}

protected override void OnInit(EventArgs e)

{

base.OnInit(e);

// get Card and Pin Number from Request and store in publically accessible variables

lCardNumber = Convert.ToInt64(Request.Form["varCardNumber"]);

iPinNumber = Convert.ToInt32(Request.Form["varPinNumber"]);

}

}

The method AddNewUser is called from the .aspx file, that’s where I put all the VXML code that builds up the Create Account functionality with ASP.NET.

<%@ Page Language=”C#” AutoEventWireup=”true” CodeFile=”account.aspx.cs” Inherits=”account” %>

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

<form>

<block>

<%

// Add new user in database and return UserID

if (AddNewUser(lCardNumber, iPinNumber, gGreeting))

{

%>

<prompt>

Congratulations your are all setup with your account.

</prompt>

<%

// create a VXML variable to hold new UserID

Response.Write(“<var name=\”userid\” expr=\” ” + lUserID + ” \” />”);

%>

<!– Another VXML file to display available options for logged-in user –>

<submit next=”MainMenu.aspx” namelist=”userid” method=”post” maxage=”0″ />

<%

}

else

{

%>

<prompt>

Unable to create account

</prompt>

<!– if create user failed then redirect to the starting doc. –>

<goto next=”account.xml” />

<%

}

%>

</block>

</form>

</vxml>

The above code is a mix of VXML and ASP.NET and is fairly simple to understand what’s going on. The code first attempts to create the user if success then stores the new UserID in a VXML variable else it redirects the user back to “account.xml”.

So that was the programming part, question is how can we enjoy the fun? For this you can use free developer account provided by PlumVoice http://www.plumvoice.com or Voxeo http://www.voxeo.com/developers/evolution-ivr-developer.jsp both of them providing free IVR hosting and testing besides some sample applications and a lot of documentation. I am more familiar with Plum right now so after creating an account you will get a phone number to dial at and you can also test your VXML script by using the ScratchPad under Application menu using Skype.

To test the ASP.NET portion you need some hosting provider to host the Website (ASP.NET & .XML) + SQL Database. After that you can point your Application configuration to Remote URL e.g. http://www.mydomain.com/account.xml from Plum’s account.

IVR – My Experience

I dived into IVR recently for a demo application that records voices for further listening, sort of an audio repository. It was fun and a great learning experience. During the phase I learnt VXML and how to navigate users on key-presses from one menu to another etc. I used VXML with ASP.NET (C#) to provide creating new account, login, saving a new audio and listening to it again, with MS SQL 2005 as backend. So here is some information about IVR and how you can start developing.

In the next post insha ALLAH I would share some parts of the script that I used to interact with ASP.NET and VXML.

What is IVR?

Excerpt taken from: http://www.voxeo.com/library/

IVR – short for Interactive Voice Response – is a technology that automates interactions with telephone callers. Enterprises are increasingly turning to IVR to reduce the cost of common sales, service, collections, inquiry and support calls to and from their company.

Historically, IVR solutions have used pre-recorded voice prompts and menus to present information and options to callers, and touch-tone telephone keypad entry to gather responses. Modern IVR solutions also enable input and responses to be gathered via spoken words with voice recognition.

IVR solutions enable users to retrieve information including bank balances, flight schedules, product details, order status, movie show times, and more from any telephone. Additionally, IVR solutions are increasingly used to place outbound calls to deliver or gather information for appointments, past due bills, and other time critical events and activities.

IVR, CTI, and Computer Telephony developers create applications that combine telephone and computer systems. Historically, these applications have been built with a wide variety of telephony APIs, components, and script languages.

These include:

  • Dialogic R4 and GlobalCall - two popular, C-centric APIs that work with Dialogic/Intel telephony cards.
  • TAPI and JTAPI – two abstract telephony APIs for Windows and Java, currently supported by around 20% of the telephony market.
  • ECTF S.100 – a complex but comprehensive telephony API supported by around 10% of the telephony market.
  • ActiveX Controls – such as Visual Voice and VBVoice that simplify Dialogic and TAPI API development complexity.
  • Proprietary IVR languages – each unique to the IVR platform they run on.

All of these telephony programming solutions suffer from three common problems: None are widely adopted standards; all are limited to a subset of platforms and operating systems; and all were designed to requirements that pre-date modern web-based solutions.

Over the last five years, the telephony industry has turned to two XML and web based standards for telephony platforms: VoiceXML and CCXML. VoiceXML and CCXML are industry standards from the World Wide Web Consortium (W3C) – the same successful standards body that created HTML, XML, and HTTP.

VoiceXML defines a markup based standard for Interactive Voice Response (IVR), including prompts, recording, touch-tone entry, voice recognition, and text to speech; while CCXML markup provides the foundation for call initiation, control, switching, routing, conferencing, and call center integration.

VoiceXML and CCXML solutions run on an increasing variety of IVR, CTI, and Computer Telephony servers, products, and boards. Furthermore, because these standards are based on XML and HTTP, they bring with them the immense power and value of web technologies.

Excerpt taken from: http://www.voxeo.com/library/