Contents |
Many times the IVR will require us to get a string and either break it into usable subparts, or sometimes, insert other characters, including spaces, into the string.
The tools we will use for this are three Java functions, '.split()', '.join()', and '.substring()'.
'.split()' breaks apart the string at the spot described in the argument. For example, '.split("")' says to break apart the string between every element; '.split("|")' says to break it apart every time it reaches the "pipe" character ( | ); '.split(",")' says to break it apart every time it reaches a comma.
'.join()' puts the string back together with whatever character is indicated by the argument inserted between the previously split elements. For example, '.join("|")' puts the string back together with the "pipe" as a delimiter;
'.join(" ")' puts the string back with a space between the elements. This is used to "explode" a number for correct text-to-speech playback (see below).
'.substring()' grabs a particular part of the string. The argument should say which place in the string to start with, and how many places to grab. Keep in mind that when counting places in strings or arrays, you always start with '0' (zero). So,
'.substring(0,3)' would begin with the first element of a string, and grab the first three elements. An example would be the area code from a ten-digit phone number. See below for the real-world examples.
The last piece of coding associated with this is the array place reference. You can grab a particular part of a string array by referencing its place in the array in brackets following the split argument. For example, '.split(",")[1]' says to split the array at the comma delimiter and take the second item in the array (since the count starts with "0", "1" is the second place).
Here are some real-world examples:
To "explode" a number for correct TTS playback, we would need to split each element (number) in the string and insert a space between them. Assuming our "number" is the variable 'acctNum', our tag would look like this:
<setvar name="setvar_explNum" varname="explAcctNum">${acctNum}.split("").join(" ");</setvar>
(The semicolon ';' is used to end a Java command.)
Suppose we sent an Account ID using a Get Tag, and got back a variable ('myResult') that contained three elements -- the user name, account balance, and due date -- separated by a 'pipe' ( | ) delimiter. We could take the results of the Get Tag ('myResult') and split it into the three elements at the pipe delimiter, and place each element into its own variable:
<setvar name="setvar_user" varname="userName">${myResult}.split("|")[0];</setvar>
<setvar name="setvar_balance" varname="acctBal">${myResult}.split("|")[1];</setvar>
<setvar name="setvar_dueDate" varname="dueDate">${myResult}.split("|")[2];</setvar>
To grab the area code from the caller ID, do the following:
<setvar name="setvar_areaCode" varname="areaCode">${call.callerid}.substring(0,3);</setvar>
Occasionally the IVR collects sensitive data that must be protected. Examples might include Credit Card Data -- Card Numbers, Expiration Dates, CVN Codes -- or medical data. Both PCI compliance and HIPAA require that sensitive information NOT be stored if not necessary. In order to comply, you can now turn off logging for the IVR responses.
Logging is turned on or off as an attribute at the "Dialplan" level, as follows:
<dialplan name="myDialplan" loggingEnabled="false">
The default value for "loggingEnabled" is "true" -- change this to "false" for sensitive IVRs.
CallFireXML uses Java Scripting at certain points in the IVR -- particularly in Setvar Tags and in If Tag comparison expressions. Here are some of the standard Boolean (Logical) Operators you can use:
The relational operators are for comparisons. Please note that the single equal sign (=) defines the contents of a variable. For example, the statement "x = 1" populates the variable x with the number 1. The statement "x = 'elephant' " puts an elephant (or at least the string 'elephant') into the variable x. So a single equal sign does not mean "equals." For that we use the double equal sign (==).
So the relations operators are:
<, <=, >, >=, !=, ==
These are 'less than', 'less than or equal to', 'greater than', 'greater than or equal to', not equal to', (more about that one in a moment), and 'equal to', respectively. Look again at 'not equal to' (!=) -- the exclamation point means "not," so technically, '!>' would mean "not greater than'. The ! is useful in the following multiple-condition scenarios.
Now, what if a particular action is to be taken only if several conditions are true? You can use logic operators to handle multiple conditions. There are three logic operators: &&, || and !.
'&&' is logical 'and' -- && combines two boolean values and returns a boolean which is true if and only if both of its operands are true. For instance:
b = 3 > 2 && 5 < 7; // b is true b = 2 > 3 && 5 < 7; // b is now false
'||' is logical 'or' -- || combines two boolean variables or expressions and returns a result that is true if either one or both of its operands are true. For instance:
b = 3 > 2 || 5 < 7; // b is true b = 2 > 3 || 5 < 7; // b is still true b = 2 > 3 || 5 > 7; // now b is false
The last logic operator is ! which means 'not' (see above). It reverses the value of a boolean expression. Thus if b is true !b is false. If b is false !b is true.
b = !(3 > 2); // b is false b = !(2 > 3); // b is true
These operators allow you to test multiple conditions more easily. For example, we can write an If Tag as follows:
<if expr="${myVariable} == 2 && ${yourVariable} != 2">
<goto>myNextModule</goto>
</if>
A real world example might use the global time stamp to define an "after business hours" action:
<if expr="${global.time.military.hour} < 7 || ${global.time.military.hour} > 18">
<goto>menu_answeringMachineModule</goto>
</if>
In the above example '< 7' means 'less than (earlier than) 7:00 AM' and '> 18' means 'greater than (later than) 6:00 PM.'
At the heart of an IVR system is the question and response. Basically, the system requests responses from the customer and the customer presses keys in response. This may be in the form of an actual question and instructions for response -- "Would you vote for Homer Simpson? Press 1 for Yes or 2 for No." -- and sometimes it's just a simple declaration -- "Please enter your 5-digit account number, followed by the pound sign."
In either case, the question-response clearly consists of a play tag stating the instructions and some keypresses getting the responses. Something needs to tell the IVR System that this particular Play Tag and its Keypress Tags all work together. The Press Menu Tag provides this function -- think of it as an envelope "containing" the play tag and keypresses. As a matter of fact, when you drag a Press Menu Tag into the work space, you will see that it automatically creates two dependent tags, a Play Tag and a Keypress Tag (dependent tags are indented from, and hang down from, their 'parent' tags). The Press Menu Tag knows that it needs at least one each of these tags. The whole thing works as follows:
<menu name="myMenu" maxDigits="1" timeout="3500">
<play name="play_Q1" type="tts" voice="male1">
Would you vote for Homer Simpson for President?
Press 1 for yes or 2 for no.
</play>
<keypress name="keypress_Q1R1" pressed="1">
<stash name="stash_Q1R1" varname="Q1R">1-Yes</stash>
</keypress>
<keypress name="keypress_Q1R2" pressed="2">
<stash name="stash_Q1R2" varname="Q1R">2-No</stash>
</keypress>
</menu>
<!-- The menu here defines how many keypresses constitute an answer -- in this case,
one. Also, how long they have to enter a response, here 3-1/2 seconds -->
<!-- The play tag defines Question 1 (Q1) and describes how to respond. -->
<!-- The first keypress tag gets the digit-2 response for Question 1
(Q1R2 and pressed="2")
and stores it in the report as "2-No" under the Variable Name "Q1R" -->
<!-- The second keypress tag gets the digit-1 response for Question 1
(Q1R1 and pressed="1")
and stores it in the report as "1-Yes" under the Variable Name "Q1R" -->
<!-- Notice that the variable name is the same for both responses:
only the value changes -->
Learn to think of the above as a single unit -- "the Question and Response."
When naming variables, try to follow standard programming rules. That way, your variables will be usable within any programming language you need to send them to, whether php, .Net, Java, C++, C#, etc. Variables should begin with a letter, and are case-sensitive. Variables cannot have spaces. And many languages do not accept odd characters -- stick with alphanumeric variable names. Other allowable characters include the underscore ( _ ) or the dot ( . ).
There are two main "naming conventions" for multi-word variable names. The first is to use underscores in between the words (in both cases, use abbreviations where possible):
"my_first_variable" or "user_app_no" (for "user application number").
The second convention uses run-on words, all lowercase, except capitals for all initial letters except the first:
"myFirstVariable" or "userAppNo"
In naming the IVR nodes, We at CallFire recommend following variable name standards, combining the two methods, as follows (again, using abbreviations as possible):
nodetype_usefulName (node name, underscore, useful name as run-on word)
Examples:
menu_Q1 (menu, question 1) menu_getUserID play_verifyUserID
One of the simpler things we can do with the IVR Designer is construct a phone tree for incoming calls to your small business. In this example, we will greet the customer, offer them three routing possibilities, and offer a recording option if our agents are not available.
The finished IVR will look like this. Below, we will discuss the tags and how they work:
<dialplan name=”root”>
<play name=”play_greeting” type=”tts” voice=”female2”>
Hi. Welcome to ABC Company.
</play>
<menu name=”menu_main” maxDigits=”1” timeout=”3500”>
<play name=”play_main” type=”tts” voice=”female2”>
Press 1 for Sales. Press 2 for Support. Press 3 for Billing.
</play>
<keypress name=”kp_sales” pressed=”1”>
<stash name=”stash_sales” varname=”dept”>Sales</stash>
<transfer name=”transfer_sales” callerid=”${call.callerid}”
whisper=”Sales Call” timeout=”20”>2135551212</transfer>
</keypress>
<keypress name=”kp_support” pressed=”2”>
<stash name=”stash_ support” varname=”dept”>Support</stash>
<transfer name=”transfer_ support” callerid=”${call.callerid}”
whisper=”Support Call” timeout=”20”>2135551212</transfer>
</keypress>
<keypress name=”kp_ billing” pressed=”3”>
<stash name=”stash_ billing” varname=”dept”>Billing</stash>
<transfer name=”transfer_ billing” callerid=”${call.callerid}”
whisper=”Billing Call” timeout=”20”>2135551212</transfer>
</keypress>
</menu>
<play name=”play_leaveMessage” type=”tts” voice=”female2”>
All of our agents are busy helping other customers.
If you would like us to call you back,
please leave your message after the beep, and press pound when finished.
</play>
<record name=”record_message” varname=”custMessage”> </record>
<hangup name=”hangup_recording” />
</dialplan>
· The “Dialplan” is the root tag – every CallFire IVR is contained by a Dialplan tag.
· The first “Play” tag is simply the greeting – it doesn’t ask questions or get back responses. A play tag can play a pre-recorded sound file or a text-to-speech (tts) voice.
· The “Menu” tag acts as a “container” for a question and its answers, or an instruction and the various possible keypress responses. The menu tells the IVR engine how many digits to expect as a response (maxDigits=”1”). The “Timeout” attribute, in milliseconds, says how long to allow for a response – 3500 milliseconds equals 3-1/2 seconds.
· The Menu tag MUST contain at least one Play tag (to explain what is required at that point) and one keypress (to get back at least one response). In our example, the “play_main” explains the call routing options.
· Each “Keypress” tag gets back the response and contains two dependent tags: a Stash tag to save the department name in the report (so we can track which department had the most calls that day) and a Transfer tag to actually transfer the call.
· Note that all three Stash tags have the same variable name (“dept”) – this serves as a header name in the report for the value (“Sales”, “Support”, “Billing”).
· The Transfer tag has several attributes. The variable reference “${call.callerid} sends the incoming callerID to our agent’s phone. The Whisper Sound plays for our agent so they know how to answer the call. The timeout limits how long we will ring the agent’s number.
· If the agent doesn’t answer within the timeout period (in this case, 20 seconds) the IVR will play the “All agents busy” message and ask the customer to leave a message.
This completes our simple inbound phone tree. Additional options could include individual extensions, individual voice mails modules, the ability to press “zero” at any time for an operator, or repeating sections for invalid responses. A member of CallFire’s IVR Design Team will be glad to help you with these or any other options, and many of these topics will be covered in future blogs.
