Table Of Contents
TCL IVR API Version 1.0 Programmer's Guide
Plans for Developing a New Script Format
Writing an IVR Script using TCL Extensions
Testing and Debugging Your Script
Associating Your Script with an Inbound Dial Peer
Displaying Information About IVR Scripts
Tips for Using Your TCL IVR Script
TCL IVR API Version 1.0 Programmer's Guide
Version Date: 03/11/02
This document contains information about the Tool Command Language (TCL) Interactive Voice Response (IVR) application programming interface (API) Version 1.0 commands that you can use to write TCL scripts to interact with the Cisco IVR feature. It provides an annotated example of a TCL IVR script and includes instructions for testing and loading a TCL IVR script.
This document helps developers writing voice application software for Cisco voice interfaces, such as the Cisco AS5x00 series. This includes independent software vendors (ISVs), in-house corporate developers, system integrators, and Original Equipment Manufacturers (OEMs).
This document includes the following sections:
•
Glossary
Overview of IVR and TCL
IVR is a term that is used to describe systems that provide information in the form of recorded messages over telephone lines in response to user input in the form of spoken words, or more commonly dual tone multifrequency (DTMF) signaling. For example, when a user makes a call with a debit card, an IVR application is used to prompt the caller to enter a specific type of information, such as a PIN. After playing the voice prompt, the IVR application collects the predetermined number of touch tones (digit collection), forwards the collected digits to a server for storage and retrieval, and then places the call to the destination phone or system. Call records can be kept and a variety of accounting functions performed.
The IVR application (or script) is a voice application designed to handle calls on a voice gateway, which is a router that is equipped with Voice over IP (VoIP) features and capabilities.
The prompts used in an IVR script can be either static or dynamic. With static prompts, the prompt message is pre-recorded in its entirety and played as a single unit. With dynamic prompts, the prompt message is pre-recorded in pieces and the pieces are assembled dynamically during play. For example, dynamic prompts are used to inform the caller of how much time is left in their debit account, such as:
"You have 15 minutes and 32 seconds of call time left in your account."
The above prompt is created using eight individual prompt files. They are: youhave.au, 15.au, minutes.au, and.au, 30.au, 2.au, seconds.au, and leftinyouraccount.au. These audio files are assembled dynamically by the underlying system and played as a prompt based on the selected language and prompt file locations.
The Cisco IVR (Interactive Voice Response) feature, available in Cisco IOS Release 12.0(6)T and later, provides IVR capabilities using TCL 1.0 scripts. These scripts are signature locked, and can be only modified by Cisco. The IVR feature allows IVR scripts to be used during call processing. The scripts interact with the IOS software to perform various call-related functions. Starting with release 12.1(3), the TCL script lock will be removed, thus allowing customers to create and change their own TCL scripts.
TCL is an interpreted scripting language. Because TCL is an interpreted language, scripts written in TCL do not have to be compiled before they are executed. TCL provides a fundamental command set, which allows for standard functions such as flow control (if, then, else) and variable management. By design, this command set can be expanded by adding "extensions" to the language to perform specific operations.
Cisco has created a set of extensions, called TCL IVR commands, that allows users to create IVR scripts using TCL. Unlike other TCL scripts, which are invoked from a shell, TCL IVR scripts are invoked when a call comes into the gateway.
The remainder of this document assumes that you are familiar with TCL and how to create scripts using TCL.If you are not, we recommend that you read TCL and the TK Toolkit by John Ousterhout (published by Addison Wesley Longman, Inc).
Plans for Developing a New Script Format
Cisco plans to develop a new TCL script format (TCL 2.0) that will address scalability and performance issues.
•
All verbs are non blocking, meaning that they can execute without causing the script to wait, which allows the script to perform multiple tasks at once.
•
The scripts are event-driven and the flow of the call is controlled by a Finite State Machine (FSM), which is defined by the TCL script.
•
Prompt can be played over VoIP and VoFR call legs.
•
Digits can be collected over VoIP and VoFR call legs.
•
Real-Time Streaming Protocol (RTSP)-based prompts are supported (depending on the release of Cisco IOS software and the platform).
•
Scripts can control more than two legs simultaneously.
•
Call legs can be handed off between scripts.
Prerequisites
The Open TCL IVR feature is currently supported on the Cisco AS5300 voice platform only. In order to use the open TCL IVR feature you need the following:
1. Cisco AS5300 (Voice platform) universal access server
2. Cisco IOS Release 12.1(3) or later.
3. TCL version 7.1 or later.
Calls can come into a gateway using analog lines, ISDN lines, a VoIP link, or a VoFR link. TCL IVR scripts can provide full functionality for calls received over analog or ISDN lines. The functionality provided for calls received over VoIP or Voice over Frame Relay (VoFR) links varies depending on the release of Cisco IOS software being used. For example, if you are using Cisco IOS Release 12.0, you cannot play prompts or tones, and you cannot collect tones.
Restrictions
•
The argument av-send, used with the authenticate and authorize commands, is valid on Cisco IOS Release 12.1(2) and later. Refer to the authenticate and authorize for more information.
•
If a TCL 1.0 script is used with the TCL Interpreter 8.0.5, the minimum memory requirement is 64 mbytes for the Cisco 2600 and Cisco 36xx platforms, starting with Cisco IOS Release 12.1(3)T. Additional memory is only needed if one uses TCL 1.0 scripts with TCL interpreter 8.0.5. At this time, the unlocked TCL scripts are not supported on the 2600 and the 36xx platforms. This memory requirement applies regardless of whether the TCL scripts are locked or unlocked.
Developer Support
Developers using this guide may be interested in joining the Cisco Developer Support Program. This new program has been developed to provide you a consistent level of support that you can depend on while leveraging Cisco interfaces in your development projects.
A signed Developer Support Agreement is required to participate in this program. For more details, and access to this agreement, please visit us at: http://www.cisco.com/warp/public/779/servpro/programs/ecosystem/devsup, or contact developer-support@cisco.com
How to Use TCL IVR Scripts
This section of the document includes information on how to create and use TCL IVR scripts. This section includes the following topics:
•
Writing an IVR Script using TCL Extensions
•
Testing and Debugging Your Script
•
Associating Your Script with an Inbound Dial Peer
•
Displaying Information About IVR Scripts
•
Tips for Using Your TCL IVR Script
Writing an IVR Script using TCL Extensions
Before you write an IVR script using TCL, you should familiarize yourself with the TCL extensions for IVR scripts.
You can use any text editor to create your TCL IVR script. Follow the standard conventions for creating a TCL script and incorporate the TCL IVR commands as necessary.
A sample script is provided in this section to illustrate how the TCL IVR commands can be used.
Note
When writing scripts, it's strongly recommended first doing a setupAck or an acceptCall.
Note
If the caller hangs up, the script stops running and the call legs are cleared. No further processing will be done by the script, which means the exit command will not be called.
Standard TCL Commands Used in TCL IVR Scripts
Certain standard TCL commands can be used in TCL IVR scripts. These commands are as follows:
For additional information about the standard TCL commands, see the TCL and the TK Toolkit by John Ousterhout (published by Addison Wesley Longman, Inc).
TCL IVR Commands At-a-Glance
In addition to the standard TCL commands, you can use the TCL extensions for IVR scripts that Cisco has created. Also, Cisco modified two of the existing TCL commands, puts and exit, to perform specific tasks. The TCL IVR commands are as follows:
For more information about these commands, see the "TCL IVR Command Reference" section.
Sample TCL IVR Script
The following annotated example illustrates how the TCL IVR commands can be used.
We start with the header information, which includes the name of the script, the date the script was created and by whom, and some general information about what the script does.
It is also a good idea to include a version number for the script. We recommend that you use a three digit system where the first digit indicates a major version of the script, the second digit should be incremented with each minor revisions (such as a change in function within the script), and the third number should be incremented each time other changes are made to the script.
# Script Loaded by: Dram# Script Version 1.0.1# Script LookDate: Sept. 30 20:58:49 1999#------------------------------------------------------------------# September 1998, David Ramsthaler## Copyright (c) 1998, 1999, 2000 by cisco Systems, Inc.# All rights reserved.#------------------------------------------------------------------## This script authenticates using (ani, dnis) for (account, password). If# that fails, it collects account and pin number, then authenticates# using (account, pin).## If authentication passes, it collects the destination number and# places the call.#Next, we define a series of procedures.
The get_account procedure defines the parameters of the account prompt and collects the account information. In this procedure:
•
The prompt plays an audio file called enter_account, which is stored in Flash memory.
•
The user is allowed to enter information before the prompt message is complete.
•
The user is allowed to abort the process by pressing the asterisk key.
•
The user must indicate that they have completed their entry by pressing the pound (#) key.
•
The input from the user is collected in an array.
•
If the collection of information is successful, the script stores the account number and indicates that the next procedure is to get the personal identification number (PIN).
•
If the user aborts the process, the script indicates that this procedure should be started again.
•
If the account number is not collected, the script indicates that this procedure should be started again.
proc do_get_account {} {global stateglobal accountset prompt(url) flash:enter_account.auset prompt(interrupt) trueset prompt(abortKey) *set prompt(terminationKey) #set patterns(account) .+set event [promptAndCollect prompt info patterns ]if {$event == "collect success"} {set state get_pinset account $info(digits)return 0}if {$event == "collect aborted"} {set state get_accountreturn 0}if {$event == "collect fail"} {set state get_accountreturn 0}set state endreturn 0}The get_pin procedure defines the parameters of the PIN prompt and collects the PIN. In this procedure:
•
The prompt plays an audio file called enter_pin, which is stored in Flash memory.
•
The user is allowed to enter information before the prompt message is complete.
•
The user is allowed to abort the process by pressing the asterisk (*) key.
•
The user must indicate that they have completed their entry by pressing the pound (#) key.
•
The input from the user is collected in an array.
•
If the collection of information is successful, the script stores the PIN and indicates that the next procedure is to authenticate the information.
•
If the user aborts the process, the script indicates that the user should be returned to the account collection procedure.
•
If the user does not enter a PIN within the allotted time, the script indicates that this procedure should be started again.
•
If the PIN entered by the user is invalid, the script indicates that this procedure should be started again.
proc do_get_pin {} {global stateglobal pinset prompt(url) flash:enter_pin.auset prompt(interrupt) trueset prompt(abortKey) *set prompt(terminationKey) #set patterns(account) .+set event [promptAndCollect prompt ReturnInfo patterns ]if {$event == "collect success"} {set state authenticateset pin $info(digits)return 0}if {$event == "collect aborted"} {set state get_accountreturn 0}if {$event == "collect fail"} {# timeoutif {$info(code) == 102} {set state get_pinreturn 0}# invalid numberif {$info(code) == 28} {set state get_pinreturn 0}}set state endreturn 0}The authenticate procedure passes the information collected to a RADIUS server for authentication and waits for a reply. In this procedure:
•
The account number and PIN are passed to the RADIUS server.
•
The response from the RADIUS server is interpreted.
•
If the authentication is successful, the script indicates that the next state is to continue processing the call.
•
If the authentication fails, the script indicates that the next state is to inform the user of the failure.
proc do_authenticate {} {global stateglobal pinglobal accountset event [authenticate $account $pin info]if { $event == "authenticated" } {set state authen_passreturn 0}if {$event == "authentication failed"} {set state authen_failreturn 0}set state endreturn 0}The get_dest procedure defines the parameters of the destination prompt and collects the destination phone number. In this procedure:
•
The prompt plays an audio file called enter_destination, which is stored in Flash memory.
•
The user is allowed to enter information before the prompt message is complete.
•
The user is allowed to abort the process by pressing the asterisk (*) key.
•
The user must indicate that they have completed their entry by pressing the pound (#) key.
•
The destination phone number is collected against the dial plan.
•
If the collection of information is successful, the script indicates that the next procedure is to process the call.
•
If the user aborts the process, the script indicates that this procedure should be started again.
•
If the destination phone number entered by the user is invalid, the script indicates that this procedure should be started again.
proc do_get_dest {} {global stateglobal destinationset prompt(url) flash:enter_destination.auset prompt(interrupt) trueset prompt(abortKey) *set prompt(terminationKey) #set prompt(dialPlan) trueset event [promptAndCollect prompt info ]if {$event == "collect success"} {set state place_callset destination $info(digits)return 0}if {$event == "collect aborted"} {set state get_destreturn 0}if {$event == "collect fail"} {set state get_destreturn 0}set state endreturn 0}The authen_pass procedure determines whether the destination phone number has been provided. In this procedure:
•
If the incoming dial peer is configured for DID operation and there is an incoming called number ($dnislen is not equal to 0), the destination is set to the destination number and the script indicates that the next state is place_call.
•
If the incoming dial peer in not configured for DID operation, the script indicates that the next state is to collect the destination phone number.
proc do_authen_pass {} {global stateglobal destinationset dnislen [string len [dnis]]if { [did] && $dnislen } {set destination [dnis]set state place_call} else {set state get_dest}return 0}The place_call procedure places the call to the specified destination. In this procedure:
•
If the call is successful, the script indicates that the next state is to determine whether the call should be timed.
•
If the call is unsuccessful, the script indicates that the next state is to process the failed call.
proc do_place_call {} {global stateglobal destinationset event [placeCall $destination callInfo info]if {$event == "active"} {set state activereturn 0}if {$event == "call fail"} {set state place_failreturn 0}set state endreturn 0}The active_notimer procedure specifies that no time limit is set on the call. The script waits idly for an event.
proc do_active_notimer {} {global stateset event [waitEvent]while { $event == "digit" } {set event [waitEvent]}set state endreturn 0}The active_last_timer procedure monitors the last few seconds of time allowed for the call to ensure that the user does not exceed their allotted credit time. In this procedure:
•
A final timer is set. The duration of the timer is equal to the number of seconds left in the user's account.
•
If the call exceeds the timer, the script disconnects the outgoing call leg and indicates that the next procedure is to notify the user that they are out of time.
proc do_active_last_timer {} {global stateset event [startTimer [creditTimeLeft] info]while { $event == "digit" } {set event [startTimer $info(timeLeft) info]}if { $event == "timeout" } {clearOutgoingLeg returnInfoset state out_of_time} else {set state end}return 0}The active_timer procedure monitors the amount of time used during the call to ensure that the user does not go past their allotted credit time. In this procedure:
•
The user's remaining amount of credit is determined.
•
If the user has less than ten seconds remaining, the script indicates that the next procedure should be to monitor the last few seconds of the call.
•
If the user has more than ten seconds remaining, a timer is set that equals the user's remaining time minus ten seconds.
•
If the call exceeds the timer, a warning message (beep.au) is played and the script indicates that the next procedure is to monitor the last few seconds of the call.
proc do_active_timer {} {global stateif { [creditTimeLeft] < 10 } {do_active_last_timerreturn 0}set delay [expr [creditTimeLeft] - 10]set event [startTimer $delay info]while { $event == "digit" } {set event [startTimer $info(timeLeft) info]}if { $event == "timeout" } {insertMessage flash:beep.au returnInfodo_active_last_timer} else {set state end}return 0}The active procedure determines whether there is a time limit on the call. In this procedure:
•
If the user has no credit limit, the script indicates that the next procedure is to wait idly for an event.
•
If the user has a credit limit, the script indicates that the next procedure is to start an active timer.
proc do_active {} {global stateif { ( [creditTimeLeft] == "unlimited") ||([creditTimeLeft] == "uninitialized") } {do_active_notimer} else {do_active_timer}return 0}The out_of_time procedure plays a message (out_of_time.au) if the user is out of time.
proc do_out_of_time {} {global stateset prompt(url) flash:out_of_time.auset prompt(playComplete) trueset event [promptAndCollect prompt info ]set state endreturn 0}The authen_fail procedure plays a message (auth_failed.au) if the information that the user provided is not authenticated by the RADIUS server.
proc do_authen_fail {} {global stateset prompt(url) flash:auth_failed.auset prompt(playComplete) trueset event [promptAndCollect prompt info ]set state endreturn 0}The place_fail procedure plays a tone if the call cannot be placed.
proc do_place_fail {} {global stateplayFailureTone 5 returnInfoset state endreturn 0}Finally, we put all the procedures together in a main routine. The main routine passes the origination and destination phone numbers (if available) to the RADIUS server for authentication. If the response from the RADIUS server is "authenticated," the authen_pass procedure is called.
If the response from the RADIUS server is anything other than "authenticated," the get_account procedure is called.
From there, the main routine reads the state as set by each procedure to determine which procedure to call next.
#-------------------------------------------------------# The main routine begins here.#acceptCallset event [authenticate [ani] [dnis] info]if {$event != "authenticated"} {set state get_account} else {set state authen_pass}while {$state != "end"} {if {[info proc do_$state] == do_$state}do_$state}Testing and Debugging Your Script
It's important to thoroughly test a script before it is deployed.
To test a script, you must place it on a router and place a call to activate the script. When you test your script, make sure that you test every procedure in the script and all variations within each procedure. Errors that occur in parts of the script that are not tested will not be found. For example, if you have the following:
if {[dnis]=="1234"} {promptAndcollect prompt infoThe misspelling of the promptAndCollect command will not be detected until the number 1234 is dialed.
You can view debugging information applicable to the TCL IVR scripts that are running on the router. The debug voip ivr command allows you to specify the type of debug output you want to view. To view debug output, enter the following command in privileged Exec mode:
[no] debug voip ivr [states | error | script | dynamic| all]
If you specify "error," output is displayed only if an error occurs in the script. If you specify "states," the output provides information about what is happening in an IVR application. If you specify "dynamic" this shows the dynamic prompt play information. If you specify "all," both error and states information is displayed.
The output of any TCL puts commands is displayed if script debugging is on.
Note
Possible sources of errors are: an unknown or misspelled command (for example, if you misspell promptAndCollect as promptAndcollect), a syntax error (such as, specifying an invalid number of arguments), or executing a command in an invalid state (for example, executing insertMessage when no conference is active). In most cases, an error such as these will cause the underlying infrastructure to disconnect the call and clean up.
Error Handling of TCL IVR Commands
Following are some of the errors that may appear and their causes:
Loading Your Script
To associate an application with your TCL IVR script and load the script, use the following command:
(config)#call application voice script_name url [parameter value]
In this command:
•
script_name specifies the name of the TCL application that the system is to use for the calls configured on the inbound dial peer. Enter the name to be associated with the TCL IVR script.
•
url is the pathname where the script is stored. Enter the pathname of the storage location first and then the script filename. TCL IVR scripts can be stored in Flash memory or on a server that is acceptable using a URL, such as a TFTP server.
•
parameter value allows you to configure values for specific parameters, such as language or PIN length. For more information about possible parameters, see the "Debit Card for Packet Telephony on Cisco Access Platforms" document on CCO.
In the following example, the application named "test" is associated with the TCL IVR script called newapp.tcl, which is located at tftp://keyer/debit_audio/.
(config)#call application voice test tftp://keyer/debit_audio/newapp.tclIf you modify your script, you can reload it using only the script name as shown below:
(config)#call application voice load script_name
Associating Your Script with an Inbound Dial Peer
To invoke your TCL IVR script to handle a call, you must associate the script with an inbound dial peer. To associate your script with an inbound dial peer, enter the following commands in configuration mode:
(config)#dial-peer voice number voip
(conf-dial-peer)#incoming called-number destination_number
(conf-dial-peer)#application application_name
In these commands:
•
number uniquely identifies the dial peer. (This number has local significance only.)
•
destination_number specifies the destination telephone number. Valid entries are any series of digits that specify the E.164 telephone number.
•
application_name is the abbreviated name that you assigned when you loaded the application.
For example, the following commands indicate that the application called "newapp" should be invoked for calls that come in from an IP network and are destine for the telephone number of 125.
(config)#dial-peer voice 3 voip(conf-dial-peer)#incoming called-number 125(conf-dial-peer)#application testFor more information about inbound dial peers, see the Cisco IOS software documentation.
Displaying Information About IVR Scripts
To view a list of the voice applications that are configured on the router, use the show call application voice command. A one-line summary of each application is displayed. The description includes the names of the audio files the script plays, the operation of the interrupt keys, what prompts are used, and the caller interaction.
#show call application voice [ [name] | [summary] ]
In this command:
•
name indicates the name of the desired IVR application. If you enter the name of a specific application, the system supplies information about that application.
•
summary indicates that you want to view summary information. If you specify the summary keyword, a one-line summary is displayed about each application. If you omit this keyword, a detailed description of the specified application is displayed.
The following is an example of the output of the show call application voice command.
router#show call app voice clid_authen_collectIdle call list has 0 calls on it.Application clid_authen_collectThe script is compiled into the imageIt has 0 calls active.The TCL Script is:------------------# clid_authen_collect.tcl#----------------------------------# September 1998, David Ramsthaler## Copyright (c) 1998, 1999 by cisco Systems, Inc.# All rights reserved.#----------------------------------# Mimic the clid_authen_collect script in the SP1.0 release.## It authenticates using (ani, dnis) for (account, password). If# that fails, it collects account and pin number, then authenticates# using (account, pin).## If authentication passes, it collects the destination number and# places the call.## The main routine is at the bottom. Start reading the script there.#proc do_get_account {} {global stateglobal accountset prompt(url) flash:enter_account.auset prompt(interrupt) trueset prompt(abortKey) *set prompt(terminationKey) #set patterns(account) .+set event [promptAndCollect prompt info patterns ]if {$event == "collect success"} {set state get_pinset account $info(digits)return 0}if {$event == "collect aborted"} {set state get_accountreturn 0}if {$event == "collect fail"} {set state get_accountreturn 0}set state endreturn 0}proc do_get_pin {} {global stateglobal pinset prompt(url) flash:enter_pin.auset prompt(interrupt) trueset prompt(abortKey) *set prompt(terminationKey) #set patterns(account) .+set event [promptAndCollect prompt info patterns ]if {$event == "collect success"} {set state authenticateset pin $info(digits)return 0}if {$event == "collect aborted"} {set state get_accountreturn 0}if {$event == "collect fail"} {# timeoutif {$info(code) == 102} {set state get_pinreturn 0}# invalid numberif {$info(code) == 28} {set state get_pinreturn 0}}set state endreturn 0}proc do_authenticate {} {global stateglobal pinglobal accountset event [authenticate $account $pin info]if { $event == "authenticated" } {set state authen_passreturn 0}if {$event == "authentication failed"} {set state authen_failreturn 0}set state endreturn 0}proc do_get_dest {} {global stateglobal destinationset prompt(url) flash:enter_destination.auset prompt(interrupt) trueset prompt(abortKey) *set prompt(terminationKey) #set prompt(dialPlan) trueset event [promptAndCollect prompt info ]if {$event == "collect success"} {set state place_callset destination $info(digits)return 0}if {$event == "collect aborted"} {set state get_destreturn 0}if {$event == "collect fail"} {set state get_destreturn 0}set state endreturn 0}proc do_authen_pass {} {global stateglobal destinationset dnislen [string len [dnis]]if { [did] && $dnislen } {set destination [dnis]set state place_call} else {set state get_dest}return 0}proc do_place_call {} {global stateglobal destinationset event [placeCall $destination callInfo info]if {$event == "active"} {set state activereturn 0}if {$event == "call fail"} {set state place_failreturn 0}set state endreturn 0}proc do_active_notimer {} {global stateset event [waitEvent]while { $event == "digit" } {set event [waitEvent]}set state endreturn 0}proc do_active_last_timer {} {global stateset event [startTimer [creditTimeLeft] info]while { $event == "digit" } {set event [startTimer $info(timeLeft) info]}if { $event == "timeout" } {clearOutgoingLeg retInfoset state out_of_time} else {set state end}return 0}proc do_active_timer {} {global stateif { [creditTimeLeft] < 10 } {do_active_last_timerreturn 0}set delay [expr [creditTimeLeft] - 10]set event [startTimer $delay info]while { $event == "digit" } {set event [startTimer $info(timeLeft) info]}if { $event == "timeout" } {insertMessage flash:beep.au retInfodo_active_last_timer} else {set state end}return 0}proc do_active {} {global stateif { ( [creditTimeLeft] == "unlimited") ||([creditTimeLeft] == "uninitialized") } {do_active_notimer} else {do_active_timer}return 0}proc do_out_of_time {} {global stateset prompt(url) flash:out_of_time.auset prompt(playComplete) trueset event [promptAndCollect prompt info ]set state endreturn 0}proc do_authen_fail {} {global stateset prompt(url) flash:auth_failed.auset prompt(playComplete) trueset event [promptAndCollect prompt info ]set state endreturn 0}proc do_place_fail {} {global stateplayFailureTone 5 retInfoset state endreturn 0}#---------------------------------------# And here is the main loop#acceptCallset event [authenticate [ani] [dnis] info]if {$event != "authenticated"} {set state get_account} else {set state authen_pass}while {$state != "end"} {puts "cid([callID]) running state $state"if {$state == "get_account"} {do_get_account} elseif {$state == "get_pin"} {do_get_pin} elseif {$state == "authenticate"} {do_authenticate} elseif {$state == "get_dest"} {do_get_dest} elseif {$state == "place_call"} {do_place_call} elseif {$state == "active"} {do_active} elseif {$state == "authen_fail" } {do_authen_fail} elseif {$state == "authen_pass" } {do_authen_pass} elseif {$state == "place_fail"} {do_place_fail} elseif {$state == "out_of_time"} {do_out_of_time} else {break}}Using URLs in IVR Scripts
With IVR scripts, you use URLs to call the script and to call the audio files that the script plays. The VoIP system uses IOS File System (IFS) to read the files, so any IFS supported URLs can be used, which includes TFTP, FTP, or a pointer to a device on the router.
Note
Flash memory is limited to 32 entries, so it may not be possible to copy all your audio files into Flash memory.
URLs for Loading the IVR Script
The URL of the IVR script is a standard URL that points to the location of the script. Examples include:
•
flash:myScript.tcl—The script called myscript.tcl is being loaded from Flash memory on the router.
•
slot0:myscript.tcl—The script called myscript.tcl is being loaded from a device in slot 0 on the router.
•
tftp://BigServer/myScripts/betterMouseTrap.tcl—The script called myscript.tcl is being loaded from a server called BigServer in a directory within the tftpboot directory called myScripts.
URLs for Loading Audio Files
URLs for audio files are different from those used to load IVR scripts. With URLs for audio files:
•
For static prompts (used with the playPrompt, insertMessage, and promptAndCollect commands), you can use the IFS-supported URLs as described in the "URLs for Loading the IVR Script" section.
•
For dynamic prompts (used in the playPrompt command), the URL is created by the software using information from the setVariable language and setLocation commands and the language CLI configuration command.
Tips for Using Your TCL IVR Script
This section provides some answers to frequently asked questions about using TCL IVR scripts.
1
How do I get information from my RADIUS server to the TCL IVR script?
After you perform an authentication and authorization, you can use the getVariable command to obtain the credit amount, credit time, and cause codes maintained by the RADIUS server. See the "getVariable" section.
2
How do I keep the network from charging for the incoming call if there is no answer?
Although gateways do not control the charges for each call, in most networks you are only charged for completed calls. Therefore, if the incoming network does not detect a completed call, you are not charged. The placeCall command accepts an incoming call only if it succeeds in placing the call. At that point the incoming network will detect the completed call and charges will begin to accrue.
Normally, if the script is going to play prompts and collect digits, it will need to accept the incoming call by running the acceptCall command. If the script does not accept the incoming call, there may be a relatively short timer on the incoming network.
3
What happens if my script encounters an error?
When an error is encountered in the script, the call is cleared with a cause of TEMPORARY_FAILURE (41). If the IVR application has already accepted the incoming call, the caller will hear silence. If the script has not accepted the incoming call, the caller might hear a fast busy signal.
If the script exits with an error and IVR debugging is on (as described in "Testing and Debugging Your Script" section), the location of the error in the script is displayed at the command line.
TCL IVR Command Reference
This section provides an alphabetical listing of the new TCL IVR commands. The following is provided for each command:
•
Description of the purpose or function of the command
•
Description of the syntax
•
List of arguments and a description of each
•
List of the possible return values and a description of each
•
Whether the command is blocking (meaning the command has some external interaction) or nonblocking
•
Example of how the command can be used
For information about how returns and events are defined in the code, see "Value Definitions" section.
Notes
For the commands that return information, the returnInfo array often contains useful information. However, if the command is returned because the destination (called) party hangs up, then the returnInfo(code) is the failure code.
If you specify an invalid number of arguments for a command, an error will occur and the script will fail.
acceptCall
The acceptCall command is used at the beginning of the main routine in a TCL script. It sends setup acknowledgement, call proceeding, and call connect messages to the incoming call leg. The Gateway is responsible for translating these messages into the appropriate protocol messages (depending on the call leg) and sending them to the caller.
Syntax
acceptCall
Arguments
None
Return Values
None
Blocking or Non Blocking
Non blocking
Example
# Accept a call and then prompt redialer for a patternacceptCallset prompt(url) flash:redialer_tone.auset prompt(interrupt) trueset patterns(accountAndPW) \\*\\*.+#\\*\\*.+#set event [promptAndCollect prompt ret

