Coders Corner Blog Image Main

Coder’s Corner: Create A Self-Service App That Doesn’t Suck

Let Customers Be “In The Know”

It’s no secret that the majority of people prefer, and even expect self-service options nowadays. Why, you may ask? Because self-service is a constant. No matter what or where someone is they can pick up the call and make a payment because there’s no need for people to be on the other end of the phone. When done right, it’s also really fast. Speed and customer service go together like peanut butter and chocolate.

Now you might be a bit skeptical of self-service considering the bad rap that automated phone systems have gotten over the years, but more often than not those issues extend from design, not the technology itself.

Refine For Simplicity

Think about the minimum amount of information you need from a customer in order to complete a transaction. For instance, if your company deals with pre-paid credit cards and someone wants to check their account balance, what does the information exchange look like in that situation?

You want to boil down this process to its simplest form because the fewer menus and prompts a caller goes through the faster they get the information they need. And if that transaction is fast and easy, well, then you’ve got a satisfied customer on your hands.

Write The Code

Creating a positive self-service customer experience isn’t rocket science. Here’s an example of some code that you could use for checking an account balance. There are two components to this code: 1. the main menu, and 2. a subdialog that queries a backend database for dynamic, up-to-date information.

[code lang="xml" toolbar="false"]
<vxml version="2.0">
   <property name="inputmodes" value="dtmf"/>
   <form>
      <block>
         Hello
      </block>
      <field name="main_menu">
         <grammar type="application/x-jsgf" mode="dtmf">
            ( 1 | 2 )+
         </grammar>
         <prompt>
            To retreive your account balance, press 1. To exit, press 2.
         </prompt>
         <filled>
            You entered <value expr="main_menu"/>
            <if cond="main_menu==1">
               <goto next="#account"/>
            </if>
            <if cond="main_menu==2">
               <goto next="#exit"/>
            </if>
         </filled>
         <noinput>
            <reprompt/>
         </noinput>
         <nomatch>
            <prompt>
               I'm sorry, I didn't understand that.
            </prompt>
            <reprompt/>
         </nomatch>
      </field>
   </form>
   <form id="account">
      <field name="account_number" type="digits?length=10">
         <prompt>
            Please enter your 10 digit account number.
         </prompt>
         <filled>
            <assign name="account_num" expr="account_number"/>
            You entered <value expr="account_num.replace(/(.)/g, '$1, ')"/>
         </filled>
         <noinput>
            <reprompt/>
         </noinput>
         <nomatch>
            <prompt>
               Your account number must be 10 digits.
            </prompt>
            <reprompt/>
         </nomatch>
      </field>
      <subdialog name="account_info" src="subdialog.php" namelist="account_number" method="post"/>
      <block>
         Your account balance is <value expr="account_info.balance"/>
         <goto next="#exit"/>
      </block>
   </form>
   <form id="exit">
      <block>
         Thank you. Goodbye.
      </block>
   </form>
</vxml>
[/code]

As you can see, the call flow here is pretty simple. When the call connects callers are told to press 1 for account balance or press 2 to exit. This is the first <prompt> tag in the main menu section.

The next section, which consists of the <filled> tag, verifies the caller’s selection. It’s worth pointing out that this is the type of thing you can A/B test. Do you need verification at this point in the call flow? The VoiceTrends call analytics toolkit can provide you with the data you need about whether to retain or remove this.

There is some standard error correction to account for mistakes, but then callers are prompted to enter an account number. (The code here has another <filled> verification section, but that can also be A/B tested and optimized.)

Once the caller enters a valid account number the call-flow runs a subdialog.

[code lang="xml" toolbar="false"]
&amp;lt;?php
&amp;nbsp;&amp;nbsp;&amp;nbsp;header("Content-type: text/xml");
&amp;nbsp;&amp;nbsp;&amp;nbsp;echo("&amp;lt;?xml version=\"1.0\"?&amp;gt;\n");
&amp;nbsp;&amp;nbsp;&amp;nbsp;$account_number = $_POST['account_number'];
&amp;nbsp;&amp;nbsp;&amp;nbsp;$db_host = &amp;lt;-my-db-host-&amp;gt;;
&amp;nbsp;&amp;nbsp;&amp;nbsp;$db_username = &amp;lt;-my-db-username-&amp;gt;;
&amp;nbsp;&amp;nbsp;&amp;nbsp;$db_password = &amp;lt;-my-db-password-&amp;gt;;
&amp;nbsp;&amp;nbsp;&amp;nbsp;$db_name = &amp;lt;-my-db-name-&amp;gt;;
&amp;nbsp;&amp;nbsp;&amp;nbsp;$db = mysqli_connect($db_host, $db_username, $db_password, $db_name);
&amp;nbsp;&amp;nbsp;&amp;nbsp;$query_result = mysqli_query($db, "SELECT `account_balance` FROM `account_info` WHERE `account_number`='".mysqli_real_escape_string($db, $account_number)."'");
&amp;nbsp;&amp;nbsp;&amp;nbsp;$result_array = mysqli_fetch_array($query_result);
&amp;nbsp;&amp;nbsp;&amp;nbsp;$account_balance = $result_array['account_balance'];
&amp;nbsp;&amp;nbsp;&amp;nbsp;mysqli_close($db);
?&amp;gt;
&amp;lt;vxml version="2.0"&amp;gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;lt;form&amp;gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;lt;block&amp;gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;lt;var name="balance" expr="'&amp;lt;?php echo(htmlspecialchars($account_balance))?&amp;gt;'"/&amp;gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;lt;return namelist="balance"/&amp;gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;lt;/block&amp;gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;lt;/form&amp;gt;
&amp;lt;/vxml&amp;gt;
[/code]

Here you can see that the application will pull through the account number and query the connected database for account balance information associated with it. The $db_xxxxx values would be replaced with an actual business database on your end, but this at least gives you an idea of what the code would look like and what fields you may need for a successful operation.

After the subdialog runs and obtains the account balance it’s back to the main menu, where that information is then presented to the caller and the call is disconnected.

Note: You might want to A/B test giving callers the option to have their account balance repeated here.

Don’t Forget To Optimize

Overall, this is a very simple and very fast process: the call connects, the caller enters their account number, the application queries a database, gets the account information, and displays it to the caller. All told a call like this could take 30 seconds or less. Plus, there are a number of items present that you could test to make the process even faster or user-friendly.