This guide provides an extremely high-level overview of openVXML, and how it fits into the context of a voice platform; it then introduces the openVXML Designer and describes the components used in voice application design. After that, it provides a detailed walk through of the steps involved in creating and deploying an application.
This diagram illustrates the basic components of an IVR as it is configured when using the open source version of openVXML. The application is first created with the openVXML Designer; it is then exported and uploaded (as a Web ARchvie, or WAR file) to an Apache Tomcat installation (although it could be any valid Java servlet container). The voice browsers are typically configured to request VXML from the webserver when a caller dials into the system. The VXML instructs the voice browser to play the configured audio files and TTS prompts for the caller, what to expect from the caller as input, and subsequent actions to take based on the caller's response.
Within the openVXML Designer there are two main components, the Voice and the Application. The idea is to keep the logic separate from the presentation. The Application handles the logic – decisions to be made, any sort of database or webservice queries, transfers, the attachment of data, and more generally the basic layout of a callflow. The Voice contains all interface elements – all audio and grammar files. The Voice is also responsible for playing dynamic data (like an account balance or a date) back to the caller. A Voice is language-specific; an application can be made multilingual by adding a second Voice for the new language.
Installing the openVXML Designer requires two steps. First, install the JRE if it's not already. Check to see if you already have the current version of the JRE installed by looking in your Programs menu or folder first. You can also find out if you have java installed and what version it is by running the following at the command prompt:
If the JRE needs to be installed, download it from Sun here. On this web page, look for the Java Runtime Environment (JRE) section. Follow the link, and then download and install the JRE for your platform (Windows, Linux, SPARC or Solaris).
Second, run the openVXML installer. A dialog box will prompt you to choose the location of the installation. This step takes a few minutes when run for the first time. The progress bar will indicate the status of installation.
The first time openVXML Designer is run, a dialog will appear asking which workspace is to be used. The workspace in Eclipse is the location where all of the voice application data used to develop your voice application will be stored – the callflows, audio files, grammar files, etc. It can be anywhere that makes sense for you. Whichever location you chose, Eclipse will remember this the next time you run the openVXML Designer and suggest it as the workspace to use. If you don't plan on using more than one workspace, you can check the Use this as the default and do not ask again option to skip this screen from now on.
Once Eclipse has started, you may see the Welcome screen. If so, click the 'Go to the Workbench' image on the right.
After clicking the 'Go to the Workbench' icon, your screen may look like this:
If so, it means you're in the default Java perspective. To change this, click Window -> Open Perspective -> Other'
Select the OpenVXML Perspective and then click OK.
You'll know you're ready to go when you see something that looks a lot like this:
A Voice project contains all of the audio and grammar files necessary for an application. The Voice also manages the combination of prerecorded audio files to playback dynamic data, such as dates, account balances, phone numbers, etc. A Voice is created for a particular language; this is because the ways in which the audio files are combined to represent things like dates and dollar amounts are different for different languages.
The first step in developing an application with the openVXML Designer is to create a Voice for the language to be used in the application. Of course, an application can have more than one language, but we'll only be choosing one here for purposes of demonstration. There are two ways to create a project in Eclipse:
We'll use the context menu as many other features of the Designer can be accessed in this way.
Note: The Voice name can be any combination of letters, numbers, <space>, or '_'. The name you choose must also be unique compared to the other (both Voice and application) projects in your workspace.
An error message will be displayed if the name does not satisfy these requirements.
A Voice can contain any number of pre-recorded audio files. These files are placed into the Media Files folder of the Voice project. Subfolders can also be created under the Media Files folder to help organize the audio files. Subfolders are also a key requirement of Magic Filenames – the ability of openVXML to automatically understand and use prerecorded audio snippets when playing back dynamic data, such as dates and numeric amounts.
A new subfolder can be created by Right-clicking on the Media Files folder under your recently created Voice folder.
Note: The folder name can only contain letters, numbers, and _. The name must also be unique amongst the other folders and files in its parent folder. An error will be displayed if any of these requirements are not satisfied.
Files can be added by dragging the files or folders you want to add into the destination folder.
The type of audio files required depends on the voice browser you're using, not OpenVXML Designer. Consult your voice browser's documentation. Generally speaking, Dialogic's Vox format (u-law, 8KHz, 64 kbps, mono) tends to work. There are many programs available for converting and editing audio files; one we're fond of is the GoldWave Digital Audio Editor (www.goldwave.com).
Grammar files tell the speech recognition engine what to be listening for. They are generally either written to listen for DTMF tones or speech. There are several different grammar file formats available; consult the documentation for your speech recognition engine (which may be bundled with your voice browser) for details. A common format is GRXML, which is easy to create in the OpenVXML Designer:
<!--Insert your grammar structure here-->
between the <rule> tags with something like this, for example:
<one-of> <item> general information </item> <item> information </item> <item> general info </item> <item> hear information </item> </one-of>
One of the most useful aspects of OpenVXML is its ability to render dynamic values using TTS or audio files, such as an account balance. In English, the value $123.50 might be represented as "one hundred twenty-three dollars and fifty cents". The rendering of dynamic values is performed by the VoiceFormatter associated with the voice project.
The most VoiceFormatters will use audio files if available in preference to TTS. The formatter locates the audio files it needs by searching the files available in the voice project for specific file names. The directory structure and exact file names used by the VoiceFormatter can differ from one formatter to another. To illustrate how this might be set up, the following is the general structure used by the SimpleEnglishFormatter distributed with OpenVXML:
Shared content is effectively a predefined prompt which can be invoked at any point in the application. It's handy for standardized prompts (like a greeting or some sort of obligatory legalese); when the time comes to change the prompts, they can be modified in one place and instantly update throughout the system.
Shared content exists in the Voice Project, in the Voice.xml file. Double-click this to see the Voice Project Editor, which is the interface for adding, editing or deleting shared content. To add shared content,
To use shared content within a prompt in the application, select a content type of Reference, and then pick the shared content from the static value list.
An application project organizes the call flow and configuration information into a simple structure. The call flow is stored in the CallDesign.xml document. The Databases, Business Objects, and Web Services folders contain information used for data access using the built-in components. The Dependencies folder contains external libraries that extend the application's functionality. An application must be configured to use a Voice for each language it supports. Branding can also be applied, providing a simple mechanism for caller experience differentiation within the application.
Note: Creating an Application requires the creation of a Voice first; if you haven't already done this, go back and create a Voice project now.
There are three ways to create a project in Eclipse:
For this example, we'll use the context menu.
Note: The application name can be any combination of letters, numbers, <space>, or _. The name you choose must also be unique compared to the other (both persona and voice application) projects in your workspace. An error message will be displayed if the name does not satisfy these requirements.
Note: Some may argue that it doesn't make much sense to provide another name for the Voice project, and they'd be right. This step is provided as groundwork for future functionality which will give the designer an enormous amount of control over how the Voices and brands interact, but which isn't completely implemented in this version.
The application editor is made up of two primary elements:
The Canvas Browser (on the left) is a handy graphical representation used for navigation between the canvases that make up the application.
The Design Area (in the middle) shows the call flow of the currently selected canvas. Below that is another way to both indicate the current canvas and to select another canvas to view: the Canvas Tabs.
Note: Incidentally, in the Projects sidebar on left: little green "D" stands for dialog and little purple "P" stands for profile. – I don't think this is still true.
The Voice Pallet (on the right) displays the available building blocks for the application. This includes the primitive objects (prompts, decision blocks, database queries, etc.) as well as the more complex structures (dialogs, application fragments, and custom integrations).
There are two ways to add a new module to the selected canvas: dragging from the Voice Pallet or right-clicking the Design Area and selecting Add. For this example, we'll use the Voice Pallet to add a PlayPrompt.
Select the PlayPrompt module from the Voice Pallet; drag this onto the canvas and then drop it. The new PlayPrompt module should appear on the canvas. To connect it to the Begin block, click the arrow in the bottom right corner of the Begin block and then drag the arrow over to the new Greeting block and drop it. The Connector dialog will appear.
This dialog will display the exit points of the source module that have not been assigned to a connector yet. In this case, the Begin block only has a single exit point – Continue. Select Continue from the list and then click OK.
Note: The newly added module would display an icon on the top right hand corner indicating that it needs to be configured. This icon would later change or disappear based on the state of the module.
The application design canvas offers several options for formatting the call flow for readability. First, using the pointer tool select the module(s) you wish to move or format. Multiple modules can be selected by either holding down the <shift> key and clicking on the modules independently, or by clicking in an open (white) area of the canvas and drawing a box around the items you want to select.
You can move the selected module(s) by clicking on them and dragging them to the desired location. Right-clicking on one of the selected modules to open a context menu with additional formatting options when multiple modules are selected. The formatting options are:
Very often, you as the designer would like to end the clutter of one canvas and, finding a natural break in the flow, would like to skip to another canvas both to separate the type of work being done on each as well as to reduce the sheer number of modules and connectors on each canvas. To do this, you need to create a new canvas and to use both the Portal Entry Module and the Portal Exit Modules, covered in the next few steps.
The Canvas Browser displays an iconic version of all the design canvases of the application. You can navigate to other design canvases by clicking on its iconic representation. The currently selected canvas will have a blue border around its iconic representation. The Canvas Browser is also used to create new canvases and clear, delete, or rename an existing canvas.
To create a new design canvas in the application,
You can delete an existing design canvas and all of its contents from an application by right-clicking on the canvas you wish to delete and selecting Delete Design Canvas. You will be asked to confirm the action as it cannot be undone. You cannot delete the initial canvas that contains the Begin module.
To rename an existing canvas, simply click its name in the Canvas Browser. The text will become editable. When the new name has been entered, press Enter.
Note: As with new design canvases, the new design canvas name cannot be the same as another canvas.
The PlayPrompt is the most basic unit of the IVR – it simply cues up audio to be played by the voice browser. This can be TTS, pre-recorded audio, or dynamic combinations of prerecorded audio snippets to play dynamic data.
A Question module is used when you would like to ask something simple of the user, not present them with several options that all require their own prompts and grammars. This could be a yes or no, a phone number, desired pizza toppings, etc.
There are two out-of-the-box ways to add a menu-like offering to your project: Option Set and Menu Dialog. The Option Set is the simpler of the two, but is also more limited in its built-in capabilities, such as error handling. It simply provides the menu of options to the caller (along with the associated prompts and grammars for each option), and results in a branch, with one path for each option and then two more paths to handle caller errors. All error handling and retry functionality must be provided by the callflow author. For a more standardized, pre-packaged approach which includes the error handling and retry functionality, try the Menu Dialog.
To add an Option Set,
When you wish to record a Caller's input verbatim instead of using speech recognition or checking for a DTMF value, you need a Record Module. This records the caller's speech into an audio file that can be archived, transcribed, emailed, etc.
When you would like to enter some custom scripting of your own to the flow:
Note: Callflow variables can be referenced in the script modules by preceding them with 'Variables'. For example, if the callflow variable 'TotalFailures' were being used to track the number of user errors happening at a menu, the line
would increment this count by one.
For examples of the script module in action, take a look at the pre-built Menu and Field dialogs.
Any Java object that's available to the JVM can be invoked from within a script block; it just needs to be done explicitly. For example, here's how to use the Java date object:
var d = new java.util.Date(); Log.info('date: ' + d);
Note that Java classes which are automatically imported in a normal Java environment aren't in this case. For example, the String object can still be used, it just needs an explicit declaration:
var str = new java.lang.String(Variables.myOldString); Log.info('substring: ' + str.substring(2,3));
For the sake of this section, let's assume that a business object has been created called 'widget' that has these fields:
If this business object had already been created in the callflow with the variable myWidget, it could be accessed in a Script Module with this:
So a log statement might look like this:
Log.info('got the widget: ' + Variables.myWidget.name + ' at $' + Variables.myWidget.price);
For the sake of bevity, a local variable can be created to access the callflow variable. With this in mind, the previous line could be rewritten like this:
var wdgt = Variables.myWidget; Log.info('got the widget: ' + wdgt.name + ' at $' + wdgt.price);
This technique also works to simply accessing elements of an Array of Business Objects. For example, if you had an array of Business Objects called 'accounts', you could extract a single reference to the array like this:
var acct = Variables.accounts; Log.info('got this account: ' + acct.name);
which of course works exactly the same as
Log.info('got this account: ' + Variables.accounts.name);
You might have need to create your own Business Object in a script block. To do this, you'd use the helper function 'create' of the Variables object. The code example below assumes that a Business Object variable for the widget Business Object exists, but is uninitialized (i.e., the Business Object variable is empty and doesn't actually point to a Business Object). The business object is created, a local variable is made for easier access, and then all of the properties are filled out.
Variables.myNewWidget = Variables.create('widget'); Variables.myNewWidget.name = 'test widget';
var wdgt = Variables.myNewWidget; Log.info('name: ' + wdgt.name);
wdgt.dateMade = '1/2/2010'; wdgt.numAvailable = 200; wdgt.price = 12.50; wdgt.exists = false; wdgt.attributes = Variables.create('Array'); wdgt.attributes = 'very big';
Note the exception for the 'attributes' field. This is an array, and so it's initialization begins by creating a new Array object; once this is done, the first element of the array is assigned. (the Array object handles its resizing transparently, so you can add elements as needed. Remember, array indicies start at 0).
SelectedBrand is an object that has the property 'value'. Brands' is an object that exposes all existing brands as properties. In an application that had a Gold brand, the brand could be changed from whatever it is to Gold with
SelectedBrand.value = Brands.Gold;
The Subdialog module is used to invoke a VXML subdialog. This allows an openVXML application to seamless integrate certain kinds of existing VXML constructions into an application. For example, you could use the Subdialog module to utilize a Nuance OSDM.
The Transfer module transfers the caller to the specified
The Variable Assignment module assigns static values to variables. It also lists all variables available at that point in the callflow and can be used to create variables (for more information about variable propagation, see Appendix B). Any change made to a variable listed (either the creation of a new variable or the assignment of a value to an existing variable) is indicated by a * in the leftmost column. A listing of 'N/A' in the Value column means that variable will not be altered. To use a Variable Assignment module:
There are 6 types of comparisons:
Any expressions used in the comparison needs to be surrounded with single quotes. To use a Decision module:
The Portal Exit module is half of the link between two canvases; specifically, it is used on the destination canvas where it marks the exit of the portal. A Portal exit must be created before their corresponding module, the Portal Entry, can be configured. A Portal Exit can have more than one Portal Entry, but a Portal Entry can only have one Portal Exit. To use a Portal Exit:
The Portal Entry module is half of the link between two canvases; specifically, it I used on the originating canvas where it marks the entrance of the portal. A Portal Exit must have already been created to use a Portal Entry. To use a Portal Entry:
The End Call module provides a graceful way to end the caller's session. This module has no properties and no exit paths.
The openVXML platform has built in support for simple JNDI and JDBC database queries. There are several steps that must be performed before this capability can be leveraged in the voice application.
The first step is to create a database object to represent the database that will house the desired information. To create a database object:
Note: The name given here does not need to be the same as the actual database the application will connect to.
The second step in this process is to define the structure of the database table which stores the needed information. To create a new database table object:
Note: Unlike the database object, the name of the table object must exactly match the name of the actual database table that stores the required information. This can usually be obtained from your IT administrators.
After creating the table object, you will have to specify the columns of the database table. These can also be obtained from your IT administrator.
Note: To remove a column, right-click the column name and select Remove Column from the context menu. The list of columns does not have to contain all the columns of the real database table, but all columns listed must be in the table. The column names must match the database table's column names exactly. We will finalize the database tie-in in the deployment section of this document. Databases, Tables and Database Objects and Fields cannot be renamed. Be sure of the name the first time, or delete them and recreate them to give them different names.
The final task in setting up support for built in database queries is to define a business object that will be used to hold the data retrieved from the database query. To create a new Business Object:
A business object will usually have the same field names as the columns from the database table it will hold the data for. To remove a field, right-click on the field name and select Remove Field from the context menu.
You need to add a Database Query Module if you intend to hit a database with your application. A Database Object will already need to be created to be referenced in this Module. Adding the Module is covered in these steps. Creating the necessary Database and Business Objects is covered in the sections above.
Applications developed in the OpenVXML Development Environment may be exported as web applications and deployed in any Java Servlet 2.3 compatible server. The exported application can be run by accessing the URL:
Note: All of the listed libraries are required for the web application to work, so only exclude libraries that are already deployed to your servlet container in a shared area (see your application server vendor documentation on how this is done). By default, all libraries will be included in the application archive.