Table of Content
Voicent Gateway is a VoiceXML
gateway server. It offers a high-level development platform for
interactive telephony applications.
Our technical breakthroughs allow us to achieve great
reliability and usability using simple voice modems instead of more
expensive telephony cards. With the savings in hardware and
software, it is now feasible to develop and market a wide range of
telephony applications at much lower prices.
Voicent Gateway is also ideal for distributed applications. By
deploying gateways in different geographic locations and connect
them with the internet, there is virtually no limit on
scalability. And as an added benefit, such application can completely
avoid long-distance phone charges.
This tutorial contains step-by-step instructions to develop an
inbound application (timeofday) and a outbound application (callnow).
The rest of the chapter contains:
Voicent Gateway contains five major components:
- Telephony engine
- Speech engine
- VoiceXML interpreter
- Interface module
- Web server (optional)
The telephony engine controls and interacts with telephony
hardware. For example, it answers the phone, initiates a outbound
call, and plays audio over the phone line, etc.
The speech engine converts text to speech and recognizes
speech commands. Current release only supports Microsoft speech
engine.
The VoiceXML interpreter parses VoiceXML files and carries out
instructions in these files.
The interface module interacts with the Gateway
client applications.
An open source web server (Tomcat)
is integrated with Voicent Gateway. It is the default place to
install applications. This is an optional components.
Applications are developed at a higher level
The functionality of each component and their interactions are
complicated, but the complexity is hidden from applications. To
have an interactive telephony application, all you have to do is
provide a set of VoiceXML files, possibly dynamically generated,
to Voicent Gateway. The gateway takes care of the rest.
VoiceXML
is a
specification for making Internet content and information
accessible via voice and phone. For more
information, such as tutorial, specifications, presentations, and
news, please visit
VoiceXML Forum.
One key technical advantage of using VoiceXML is its high level
interface for developing interactive telephony applications. Since
VoiceXML gateways take care the complexity of call control, speech
synthesis, speech recognition, and other low level issues,
application developers can focus on their application
specific issues.
Unlike almost all other VoiceXML gateway vendors, Voicent's
gateway product is specifically designed for a simple voice modem
instead more expensive telephony cards. Our goal is to make this
technology affordable to all businesses and consumers.
In addition to the basic VoiceXML gateway features, Voicent
Gateway provides application management, license management, an
integrated web server, and outbound call and scheduling, etc,
making it even easier for application developers.
Voicent Gateway SDK contains documentation, client library, and
tools.
- Documentation
- Voicent Gateway Client Library
- Tools
This chapter illustrates how to create a simple inbound
application that provides a time-of-day service over the
telephone.
Voicent Gateway by default does not pick up inbound calls.
Please make sure to uncheck the "Do not pickup inbound call" tab
in the options dialog (invoked from the Setup main menu -->
options). Once enabled, you can call in and hear a default
message.
The simplest application for Voicent Gateway is a single vxml
(VoiceXML file extension) file and a configuration file. Our first
version of the time-of-day service just informs the caller the service
name.
Please note this sample requires Voicent
Gateway 1.5 or later.
1. Create application directory structure
First create a new project directory (will be referred to as
<tddir>) in your file system. Under the project directory
create two sub-directories: conf and webapps.
2. Create application vxml file
Create a file named timeofday.vxml under <tddir>/webapps
and type-in or copy-paste the following to the file:
- <?xml
version="1.0"?>
<vxml version="1.0">
- <form
id="td">
<block>
Hello, this is Time of Day service.
</block>
</form>
- </vxml>
The format of the file is VoiceXML.
3. Create application configuration file
A configuration file is needed to install your application to
the gateway. This configuration file specifies the start and exit
vxml files, the application type (inbound or outbound), and choice
of password protection, etc.
Create a file named timeofday.conf under <tddir>/conf
and copy the following information to the file.
- name =
Time of Day
keyword = Time of day
inbound = 1
outbound= 0
appurl = /td/timeofday.vxml
webappname=/td
4. Check your directory structure
Now you should have a directory structure like this:
- <tddir>
+ conf
timeofday.conf
+ webapps
timeofday.vxml
What we created so far is a minimum application, a "Hello
World" application for Voicent Gateway.
To install the application to the gateway, follow these steps:
1. Install application to the gateway
Invoke the Application Setup dialog from the Application main
menu. You should see the default Call Scheduler is installed
already. Click the Install button and then select your
timeofday.conf file. Once installed, you should see the
following. Click OK and the gateway will restart automatically.
2. Now call in to hear your first application working
Once the gateway pickup the phone, you should hear "Hello,
this is Time of Day service" after the general gateway
message.
There are two types of prompts in VoiceXML:
- Prompt using text-to-speech
- Prompt using pre-recorded audio message
The message between <block> and </block> in our timeofday
example is the first type. The gateway reads in the text and
automatically converts it to speech and plays it over the phone.
It is usually nice to have a pre-recorded audio message if the
message does not change. The rest of this section shows how to do
this.
1. Record and save an audio file
Use any recording tool, such as the Sound Recorder, to
record your message. Make sure to save it using the correct audio
format suitable for telephone. Voicent Gateway only supports "PCM
8 KHz, 16 bit, mono" wave format.
Create a sub-directory under <tddir>/webapps/audio, and
save your recording as welcome.wav.
For commercial products, it is strongly
recommended that you use professional recording studio to create
your audio prompts. The sound quality recorded by a regular
computer microphone is usually poor, as you can tell from the wave
files included in the sample code.
2. Change your vxml file
- <?xml
version="1.0"?>
<vxml version="1.0">
- <form
id="td">
<block>
<audio src="audio/welcome.wav"/>
</block>
</form>
- </vxml>
3. Call in to check your new timeofday service
Now instead of hearing the text-to-speech voice, you should
hear your own recording.
The timeofday application requires dynamically generate vxml
file based on the time of the call. Voicent Gateway has
incorporated
Tomcat
as its default web server. The application installed to the
gateway is similar to any Tomcat web application, except the file
format is VXML instead of HTML. If you are new to Java servlet and
JSP technology, please take some time to get yourself familiar
with these technologies.
It is not necessary to use the default web server. Actually you
can use any web server of your choice. However, the discussion is
beyond the scope of this tutorial.
1. Create application jsp file
Rename timeofday.vxml to timeofday.jsp under <tddir>/webapps
and type-in or copy-paste the following to the file:
- <?xml
version="1.0"?>
<vxml version="1.0">
<%@ page import="java.util.Date" %>
<%@ page import="java.text.SimpleDateFormat" %>
- <%
response.setHeader("Cache-Control","no-cache");
Date d = new Date(System.currentTimeMillis());
SimpleDateFormat f = new SimpleDateFormat("hh:mm a");
%>
<form
id="td">
<block>
<audio src="audio/welcome.wav"/>
<%= f.format(d) %>
</block>
</form>
- </vxml>
2. Re-record the audio prompt
Re-record the audio message such that it ends with "... The
current time is".
3. Create web.xml file
Under <tddir>/webapps, create a directory named
WEB-INF. Under WEB-INF, create a file named web.xml
with the following content.
- <?xml
version="1.0" encoding="ISO-8859-1"?>
<!DOCTYPE web-app PUBLIC "-//Sun Microsystems, Inc.//DTD Web
Application 2.3//EN" "http://java.sun.com/dtd/web-app_2_3.dtd">
<web-app>
<servlet>
<servlet-name>timeofday</servlet-name>
<servlet-class>timeofday</servlet-class>
</servlet>
- <servlet-mapping>
<servlet-name>timeofday</servlet-name>
<url-pattern>/timeofday.jsp</url-pattern>
</servlet-mapping>
</web-app>
4. Compile the vxml file
The jsp file you created in the previous step is the source
code for time-of-day service. The Tomcat server incorporated in
the gateway only takes compiled jsp files.
To compile the jsp file, you need the jspc compiler
included in the
Tomcat
release. You also need Java SDK (J2SE)
from Sun Microsystems. Please download and install these two
programs before continue.
To compile, use
- <Tomcat
dir>/bin/jspc.bat timeofday.jsp
The jspc compiler should generate a file called
timeofday.java. If the program complains about JASPER_HOME and
JAVA_HOME, please set these environment variables to their
corresponding values. For details, please refer to Tomcat
document.
Create a directory named classes under <tddir>/webapps/WEB-INF.
Now compile it using the javac compiler.
- <JDK
dir>/bin/javac -classpath <Tomcat dir>/lib/jasper-runtime.jar;<Tomcat
dir>/common/lib/servlet.jar -d ./WEB-INF/classes timeofday.java
Now you should have the compiled java class file called
timeofday.class under WEB-INF/classes.
5. Changed the configuration file and re-install the
application
Change the following line in timeofday.conf
- appurl = /td/timeofday.vxml
to
- appurl = /td/timeofday.jsp
Invoke the application setup dialog from Voicent Gateway,
remove the Time of Day application and install it again. The
gateway should restart automatically.
6. Call in to hear the timeofday service
The basic timeofday service is complete. When you call in, you
should hear the current time of the day.
The next section contains some information for you to test
dynamically generated vxml files.
Applications installed to the gateway are no different from
other Tomcat web applications. To develop and test these
applications, you can use any servlet/JSP tools you are using.
List below are some simple tips for testing.
1. Check the gateway log file
The gateway log file (output.log) is under <install
dir>/voicent/gateway/logs. Inside the log file, you should see
a few lines about the initialization of the /td application.
-
WebappLoader[/td]: Deploying class repositories to work
directory C:\Program Files\Voicent\Gateway\work\_\localhost\td
StandardManager[/td]: Seeding random number generator class
java.security.SecureRandom
...
All Tomcat log messages go to this log file. If your jsp file
contains runtime errors, please check this log file for more
information.
2. Use a web browser to test dynamically generated pages first
You can use a web browser to test you application first. Tomcat
server inside the gateway uses the default port of 8155. If you
point your browser to
-
http://localhost:8155/td/timeofday.jsp
you should see the generated vxml file.
3. Use the command line simulator
For more elaborate applications, a simulator is necessary to
have a fast turn around time for development. This command line
tool is included in Voicent Gateway SDK.
Voice command is the main method to develop an interactive
telephony application. It has many advantages over traditional
DTMF tone based applications.
Suppose we want to enable user to get the time of day of a
specific time zone, we can change the timeofday.jsp file to
the following.
- <?xml
version="1.0"?>
<vxml version="1.0">
<%@ page import="java.util.Date" %>
<%@ page import="java.text.SimpleDateFormat" %>
<%@ page import="java.util.TimeZone" %>
- <%
response.setHeader("Cache-Control","no-cache");
Date d = new Date(System.currentTimeMillis());
-
- String tz = request.getParameter("tz");
TimeZone timez = null;
if ("pacific time".equals(tz))
timez = TimeZone.getTimeZone("America/Los_Angeles");
else if ("mountain time".equals(tz))
timez = TimeZone.getTimeZone("America/Denver");
else if ("central time".equals(tz))
timez = TimeZone.getTimeZone("America/Chicago");
else if ("eastern time".equals(tz))
timez = TimeZone.getTimeZone("America/New_York");
SimpleDateFormat f;
-
if (timez != null) {
f = new SimpleDateFormat("hh:mm a,
zzzz");
f.setTimeZone(timez);
}
else {
f = new SimpleDateFormat("hh:mm a");
}
- %>
<form
id="td">
<field name="tz">
<prompt timeout="10s">
<block>
<audio src="audio/welcome.wav"/>
<%= f.format(d) %>
<audio src="audio/which_timezone.wav"/>
</block>
</prompt>
<grammar>
pacific time | mountain time | central time |
eastern time
</grammar>
<filled>
<submit next="/td/timeofday.jsp" namelist="tz"/>
</filled>
</field>
</form>
- </vxml>
Compile the file using jspc and javac.
Also, record additional voice prompt "To get time of day again,
please tell me the time zone" and save it as <tddir>/webapps/audio/which_timezone.wav.
Restart the gateway. Call in and test the service.
An example of the service interaction is shown below:
- User:
dial the service number
Service:
..., Hello, this is the time of day service. The current time is
... To get time of day again, please tell me the time zone
User:
pacific time
Service:
... The current time is ... Pacific standard time. ...
As you can see in this example, combining JSP and VXML is
flexible and quite powerful.
DTMF tones are the tones used in telephones for tone dialing.
Traditionally, they are the only means user can interact with a
telephony application.
The following provides the same functionality as the one in
previous section except it uses DTMF tones for time zone
selection.
- <?xml
version="1.0"?>
<vxml version="1.0">
<%@ page import="java.util.Date" %>
<%@ page import="java.text.SimpleDateFormat" %>
<%@ page import="java.util.TimeZone" %>
- <%
response.setHeader("Cache-Control","no-cache");
Date d = new Date(System.currentTimeMillis());
String tz = request.getParameter("tz");
TimeZone timez = null;
if ("1".equals(tz))
timez = TimeZone.getTimeZone("America/Los_Angeles");
else if ("2".equals(tz))
timez = TimeZone.getTimeZone("America/Denver");
else if ("3".equals(tz))
timez = TimeZone.getTimeZone("America/Chicago");
else if ("4".equals(tz))
timez = TimeZone.getTimeZone("America/New_York");
-
SimpleDateFormat f;
-
if (timez != null) {
f = new SimpleDateFormat("hh:mm a,
zzzz");
f.setTimeZone(timez);
}
else {
f = new SimpleDateFormat("hh:mm a");
}
%>
<form
id="td">
<field name="tz">
<prompt timeout="10s">
<block>
<audio src="audio/welcome.wav"/>
<%= f.format(d) %>
<audio src="audio/which_timezone_dtmf.wav"/>
</block>
</prompt>
<dtmf>
1 | 2 | 3 | 4
</dtmf>
<filled>
<submit next="/td/timeofday.jsp" namelist="tz"/>
</filled>
</field>
</form>
- </vxml>
Save the content as timeofday.jsp. It is OK to overwrite
the original content, we'll visit that again later. Also record a
new voice prompt, such as "press 1 for pacific time, ..., press 4
for eastern time", and save it as which_timezone_dtmf.wav
under <tddir>/webapps/audio.
Restart the Gateway and call in the test again.
Suppose you want to give your customers the choice of whether
to use the voice commands version or the DTMF commands version.
With Voicent Gateway, you can easily add a web-based setup page to
your application. You can also add a custom menu to Voicent Gateway
for your application.
1. Create a setup jsp page
This page reads the user choice and saves the result to a file.
- <%@ page
import="java.io.FileWriter" %>
<%
response.setHeader("Cache-Control","no-cache");
String vcmd = request.getParameter("vcmd");
if (vcmd != null) {
String webappDir =
application.getRealPath("/");
FileWriter fw = new
FileWriter(webappDir + "/setup.txt");
fw.write(vcmd);
fw.close();
}
%>
<html>
<body>
<h1>Time of Day Service Setup</h1>
<a href="setup.jsp?vcmd=yes">Click here to use voice version</a>
<br>
<a href="setup.jsp?vcmd=no">Click here to use dtmf version</a>
</body>
</html>
Save the content to setup.jsp file under <tddir>/webapps.
2. Install the setup page
The steps are the same as installing the timeofday.jsp file.
- Compile the setup.jsp to setup.java using jspc
- Compile the setup.java to setup.class using
javac
- Add the following to web.xml
Add after other <servlet> definition
<servlet>
<servlet-name>setup</servlet-name>
<servlet-class>setup</servlet-class>
</servlet>
- Add after other <servlet-mapping> definition
- <servlet-mapping>
<servlet-name>setup</servlet-name>
<url-pattern>/setup.jsp</url-pattern>
</servlet-mapping>
Now, restart the gateway and test this page with a web browser.
The url should be
http://localhost:8155/td/setup.jsp
3. Use the setup information in timeofday.jsp
- <?xml
version="1.0"?>
<vxml version="1.0">
<%@ page import="java.util.Date" %>
<%@ page import="java.text.SimpleDateFormat" %>
<%@ page import="java.util.TimeZone" %>
<%@ page import="java.io.*" %>
- <%
response.setHeader("Cache-Control","no-cache");
Date d = new Date(System.currentTimeMillis());
String tz = request.getParameter("tz");
TimeZone timez = null;
if ("1".equals(tz) || "pacific time".equals(tz))
timez = TimeZone.getTimeZone("America/Los_Angeles");
else if ("2".equals(tz) || "mountain time".equals(tz))
timez = TimeZone.getTimeZone("America/Denver");
else if ("3".equals(tz) || "central time".equals(tz))
timez = TimeZone.getTimeZone("America/Chicago");
else if ("4".equals(tz) || "eastern time".equals(tz))
timez = TimeZone.getTimeZone("America/New_York");
-
SimpleDateFormat f;
-
if (timez != null) {
f = new SimpleDateFormat("hh:mm a,
zzzz");
f.setTimeZone(timez);
}
else {
f = new SimpleDateFormat("hh:mm a");
}
-
boolean useVcmd = false;
try {
String webappDir =
application.getRealPath("/");
FileReader fr = new
FileReader(webappDir + "/setup.txt");
BufferedReader br = new
BufferedReader(fr);
String line = br.readLine();
if ("yes".equals(line))
useVcmd =
true;
}
catch (IOException e) {
}
%>
<form
id="td">
<field name="tz">
<prompt timeout="10s">
<block>
<audio src="audio/welcome.wav"/>
<%= f.format(d) %>
<% if (useVcmd) { %>
<audio src="audio/which_timezone.wav"/>
<% } else { %>
<audio src="audio/which_timezone_dtmf.wav"/>
<% } %>
</block>
</prompt>
-
<% if (useVcmd) { %>
<grammar>
pacific time | mountain time | central time |
eastern time
</grammar>
<% } else { %>
<dtmf>
1 | 2 | 3 | 4
</dtmf>
<% } %>
<filled>
<submit next="/td/timeofday.jsp" namelist="tz"/>
</filled>
</field>
</form>
- </vxml>
Compile and jsp file and generated java file.
3. Install Application Menu to Voicent Gateway
Add the following line to timeofday.conf file.
- ctxmenu =
TimeOfDay ...
ctxmenulocalurl = td/setup.jsp
Reinstall the timeofday.conf file. Now you should see the new
menu is added to Voicent Gateway's Application main menu. You can
also use right mouse click on the gateway icon to access the
application menu.
The sample code download corresponds to this step.
The outbound call capability of Voicent Gateway is quite
powerful and flexible. It contains a call scheduler for making and
schedule outbound calls. Voicent AutoReminder and Voicent
BroadcastByPhone are both outbound call applications.
The callnow sample presented in this chapter is similar
to the
callpad sample for AutoReminder. However, callpad sample does
not directly communicate with Voicent Gateway, instead it relies
on AutoReminder for the communication. AutoReminder interface is
much easier to use but less flexible.
It is assumed that you have read Part I of this tutorial.
You will need to have the gateway client library (part of the
gateway SDK) for the later half of this chapter.
The first version of the callnow sample is the "Hello
World" example of outbound call application for Voicent Gateway --
it calls a user specified number and plays a pre-recorded message.
1. Prepare the outbound call files
- <?xml
version="1.0"?>
<vxml version="1.0">
- <form
id="td">
<block>
<audio src="callnow/hello.wav"/>
</block>
</form>
- </vxml>
Save it as callnow.vxml. Use Windows Sound Recorder or
your favorite recording software to record your message and save
it as hello.wav. (Make sure the format is PCM 8 KHz, 16
bit, mono).
2. Install these files to Call scheduler
Voicent Gateway contains an integrated call scheduler. The top
directory for call scheduler is under <Voicent Install
Dir>/Gateway/outcall.
Create a directory named callnow under <Voicent
Install Dir>/Gateway/outcall/webapps. Move the callnow.vxml
and hello.wav files to the callnow directory.
3. Post call request to the Call Scheduler
To make call, simply send HTTP post request to the call
scheduler. The url is
http://localhost:8155/ocall/callreqHandler.jsp. The phone
number, call time, and other information are sent in the post
request. Once the call scheduler gets the request, it will make
the call at the specified time.
Since the interface for outbound call is HTTP, you can write
your application in any programming language you prefer. Here we
are going to create a HTML page and let the browser send the call
request.
- <html>
<body>
-
<form action="/ocall/callreqHandler.jsp"
method="post">
<input type="hidden" name="info" value="callnow sample">
<input type="hidden" name="firstocc" value="10">
<input type="hidden" name="startvxml"
value="[callnow
dir]/callnow.vxml">
Phone Number: <input name="phoneno" value=""><br>
<input type="submit" name="s" value="Call now">
</block>
</form>
</body>
- </html>
Please replace [callnow dir] with
the real directory name. Save the content to callnow.htm
under <Voicent Install Dir>/Gateway/outcall/webapps/callnow.
4. Test the application
Point your browser to
http://localhost:8155/ocall/callnow/callnow.htm. Since the
callnow is installed to the call scheduler web applications,
you can access the file from any machine on your network. (Just
replace the localhost to your real machine name)
Next section shows a few tips for testing outbound
applications.
Testing outbound application is similar to testing inbound applications. Here we
list a few more tips specific for test outbound applications.
1. Outbound call log file
The outbound call log file is under <Voicent
Dir>/Gateway/outcall/logs.
2. Outbound call request files
When the call scheduler receives a call request, it will save
it to a file. These files are under <Voicent
Dir>/Gateway/outcall/reqs. Files with extension .log
are calls already made, and files with extension .req are
calls to be made. Please note the format of these files are
subject to change and might not be backward compatible.
During debugging, it is nice to clean up the request directory
from time to time. To do that, stop the gateway, remove all
unwanted request files, and start the gateway again.
The rest of this chapter requires you have the gateway SDK.
To help developers to create more complex outbound applications
such as Voicent AutoReminder and Voicent BroadcastByPhone, Voicent
offers a MFC based gateway client library. In fact, these two
applications are built on top of the client library.
In the rest of this chapter, we'll enhance the callnow
sample such that the call message includes additional message
typed in from the application GUI.
Click here to
download the callnow sample.
1. Compile and test the downloaded sample
First, you need to set the correct include directory and
library directory of the gateway client library for the sample
project.
Client library include file is
vgClient.h and library is
vgateclient.lib.
The following sections explain the usage of the client library
of the sample code.
The following code register the client with the gateway.
- if (!
VgateClient::RegistClient("callnow")) {
AfxMessageBox(VgateClient::GetLastError());
}
- Usually, this is a good time to prepare the client, such as
sending pre-recorded audio files to the gateway. In this
example, we skip this step. It is assumed that you still have
the audio file hello.wav installed under the call
scheduler directory from previous steps. Otherwise, please see
The "callnow" application
section.
Since the call message includes dynamic information, we cannot
pre-install the vxml file to the gateway as we did in the first
version of the sample.
1. Generate the vxml file
In callnowDlg.cpp, the method GenerateVxml()
generates the vxml file based on the message in the dialog. The
result vxml is like the following:
- <?xml
version="1.0"?>
<vxml version="1.0">
- <form
id="td">
<block>
<audio src="callnow/hello.wav"/>
...
message in the dialog box ...
</block>
</form>
- </vxml>
2. Send the vxml file to the gateway
The following code creates a directory under the gateway call
scheduler directory and sends the newly created vxml file over.
- CString
targetdir = "\\outcall\\webapps\\" + GetClientName() + "\\";
VgateClient::CreateDir(targetdir);
if (! VgateClient::SendFile("callnow.vxml",
targetdir + "\\callnow.vxml",
false))
{
AfxMessageBox(VgateClient::GetLastError());
return;
}
The following code schedule the call with the gateway.
-
CMapStringToString nvpairs;
nvpairs["info"] = "CallNow Sample";
nvpairs["phoneno"] = m_phone;
nvpairs["firstocc"] = "0";
nvpairs["startvxml"] = VgateClient::GetRemoteDir(targetdir) +
"\\callnow.vxml";
CString callId;
if (! VgateClient::ScheduleCall(nvpairs, callId)) {
AfxMessageBox(VgateClient::GetLastError());
return;
}
The ScheduleCall sends the call request to the gateway, it returns
the callId of the phone call. The callId can be used later for
getting the call status.
To get the call status, use the following:
- if (!
VgateClient::GetCallStatus(callId, log, true)) {
AfxMessageBox(VgateClient::GetLastError());
return;
}
if (log.GetSize() == 0)
continue; // still in progress
// last one is the final status
rec = (VgateCallRecord*)log.GetAt(log.GetSize()-1);
The call status and message can be accessed from the
VgateCallRecord. There might be more than one call records because
of retries.
Once the call is made or failed, you should clean up the call
request and other call specific files on the gateway.
-
VgateClient::RemoveCall(callId);
VgateClient::RemoveFile(targetdir + "\\callnow.vxml");
Since the gateway interface is based on HTTP, it is programming
language independent. However, we are planning to add these
interfaces to further simplify application development. The
following sections are part of the gateway Reference.
|