AWS’s AI in the Contact Center Pitch: A Swing and a Miss.

Recently AWS released a “Knowledge Brief” illustrating how Fortune 1000 companies are taking a deeper interest in AI related products and services for their contact centers. While I think there are plenty of points which could be argued, for the sake of this post, I will focus on the intro graph as this is the springboard to the whole document created by the Aberdeen Group’s research. Let’s start with the graph:

Capture.PNG

First, I was surprised of the atribution for the spike in contact center solutions research to the Google Duplex presentation during I/O 2018. Second, the report goes on to state that the red line declining off to the right are the search results for PBX because “firms are not as active in researching best practices and trends in use of PBX.” These two points stuck to me as odd specially if you’re building a whole paper on those two premises so I took it upon myself to see if I could indepedently confirm their positions.

Considering the paper states that this is all about research I decided to go to world’s research webpage: Google; specifically Google Trends. Let’s tackle the spike in research due to the announcement of Google Duplex. You will see that Google registered the terms “google duplex” spiking in May which matches with their blog post linked above. The report’s graph has this spike happening in July which is not correct. But let’s give them the benefit of the doubt that the x-axis is mislabled since there certainly was a spike in research on these terms.

Capture.PNG

The papers second point is around the decline of research around the term PBX. The document states “..it’s reflected through the dark red line that’s particularly trending downwards between July and September 2018.” The main reason why this caught my eye is because of the term PBX. As those of you in the conctact center business know the term PBX really has gone out of use in the late 90s and even more today in the 2000s. Mainly because with VoIP the PBX term is not used as broadly. Make no mistake things like Cisco’s CommunicationManager and Asterisks are PBXes, but they are so much more thus why the term has fallen out of favor. Given this information let’s compare how the term PBX and ACD, a more broadly used term to almost mean the same thing, have trended for the time period this report covers.

Capture.PNG

Neither term has really seen a decline. Heck you could argue that PBX saw an increase between May and July while ACD saw an increase after July. Ultimately debunking the premise this whole document stands upon.

AI/ML is the hot new topic, but there’s a time and a place for everything. This paper’s whole premise for an AI future relies on faulty data which causes the whole article to fall apart. This, like may other pieces, are more hype than substance.

~david

 

 

 

 

 

 

 

My take on easily improving your customer’s experience with not a lot of money and without having to hire me.

Recently I was talking to an acquaintance about our top IVR annoyances. While we debated back and forth on the merit of each annoyances it got me thinking about the current wave around customer experience, customer journey, and the amount of money and products some companies are putting in to try and get marginal improvements. While I’ve been working in the contact center for over a decade, I certainly don’t know it all, but I’ve come to realize that before spending a lot of money businesses should do a few small things. These small things will provide small improvements and will set you up to be better prepared for bringing some vendor to help you “revolutionize” your customer experience.

Now there is no data to backup these thoughts, but I like to think my experience should carry a bit of weight. Here we go:

Your IVR should reflect your personality. Every IVR sounds the same, is your business just like every other business? All businesses stress over print ads, color schemes for the website, logos, commercials, but their IVR still feels like every other IVR. Why not carry that stress over to something which can be personalized with just a few words and voice inflection?

Know your callers. We find ourselves in a data rich and information poor world. Are your callers millennials? Are they senior citizens? Is there a specific social economic status which gravitates towards your IVR while others go through a different channel?  All of this information is critical in trying to figure out what options you should be offering in your IVR and what your personality should be.

Make it sound fresh. Has your IVR welcomed every caller with “Thank you for calling…” since the dawn of time? Every modern and not so modern IVR in the world can play an array of greetings, use slightly different language depending on the time of year, and create some personalization without much work. No one likes to talk to that one person who always tells the same stories. Your IVR can easily and cheaply break that monotony, sound fresh, and make the wait seem more engaging.

Don’t make me tell you again. One of the things that’s most annoying is when you call a company to fix a problem, you think it’s solved only to find out a few hours later or a few days later that it’s not resolved. You know what I do, and the rest of the world does? Call right back. It’s very easy for modern IVRs to see that a customer called recently and there’s a very high likelihood they are calling for the same reason again. So why put them through your self-service menu? Get them immediately to an agent, you failed at first call resolution, you know it and they know. Here’s a second shot at making it better. Extra points if you get them to the same agent who will have some context from the first call.

Everyone likes surprises. Every once in a while, have calls be sent to agents without having to go through the full gamut of the IVR. Specially if you know you have agents available. which will increase your agent utilization, but this only works if your agents are able to handle most types of calls. Because if you’re going to have to transfer callers, do not do this!

Don’t pretend to care. Saying that my call is important is such an insult. It’s not, otherwise you would have staffed accordingly and not made me wait. Offer a way to call back a customer instead of having them wait hostage to your queue treatment.

Silence is golden.  If your call center deals with extremely high hold times greater than 15 minutes. Give the caller the option to not hear any music and announcements at all. An occasional beep and maybe a short message on how to enable music again will make the wait time much more enjoyable. If I can detect how often your music on hold loops, I will not be very pleasant when the agent takes my call.

~david

 

 

Connect Squirrel SQL to UCCX DB

I found a good bit of information on this, but none of it was in a single post. Figured it might help to see all the steps in a single spot. This assumes 11.x UCCX from a Windows machine.

  • Download Squirrel SQL https://sourceforge.net/projects/squirrel-sql/.
  • Open a command prompt with Administrator privileges.
  • Move to were the Squirrel jar file is found.
  • Run “java -jar squirrel-sql.XXX.jar”.
  • Besides the standard options add the Informix drivers.
  • Download the latest Informix JDBC driver from https://mvnrepository.com/artifact/com.ibm.informix/jdbc/
  • Place JDBC drive in the Squirrel SQL lib folder. You shoul be able to click on Drivers and scroll down and see a check mark next to Informix.
  • Go to UCCX Administrator > Tools > Password Managenet reset the password for uccxhruser. If you do this and you have a HA setup, make sure that you click on “Check Consistency” to validate that both nodes have the latest password. If they don’t, login to both nodes and do the previous step on each.
  • Connection URL format is: jdbc:informix-sqli://<fqdn or ip>:1504/db_cra:INFORMIXSERVER=<hostname>_uccx
  • Connect and to validate that you get some data go to SQL and run a query like “select contactType, applicationName from ContactCallDetail where ContactCallDetail.startDateTime >= ‘2019-07-01 00:00:00′”

~david

Release Nuance ASR License in Cisco Contact Center Enterprise & Virtual Voice Browser (VVB)

This topic seems to come up everytime I’m on an ASR project. I finally got a definetive answer out of Cisco on the “right” way to do this. The most popular approach to release the Nuance license is to have a dummy label in your ICM script. You can read all the details in this post. However, a much cleaner way of doing it involves adding a CVP collection/capture element, I like to use Digits, set the Input Mode to dtmf, all collection timers to 1, and play a very short silent prompt. Additionaly, add the following VXML property com.cisco.asr-server = Default.

CVP Studio Digits Elements for Nuance Release

How to confirm this actually works? Start Wireshark from one of your Nuance servers and and use the following filter:

(!sip.CSeq.method == "OPTIONS")&&(sip)&&frame.len in {874 504}

The above filter will only show the Invites and Byes to the Nuance service. Which will yield the following output:

"No.","Time","Source","Destination","Protocol","Length","Info"
"100","8.769243","10.10.10.16","10.10.10.17","SIP/SDP","874","Request: INVITE sip:asr@nuancesvr:5060;transport=tcp | "
"3699","95.355613","10.10.10.16","10.10.10.17","SIP","504","Request: BYE sip:mrcpserver@nuancesvr:5060;transport=TCP | "

You should confirm that the IPs in the capture are those of your VVB and Nuance box.

~david

Cisco Finesse Workflows Troubleshooting

I ran into this problem today and I had never really thought about how you could troubleshoot issues where a workflow wasn’t working. It had always been, if it worked it worked. Took a bit of time to figure out how to dig in to the right Finesse logs to see why exactly my workflow was not firing. In my particular case I have a screen pop workflow which is supposed to pop if a call variable contains a specific word. We’re going to figure out why the workflow never worked.

First, you should go to the URL below enable persistent logging and sign in to Finesse as your agent. To be safe you might want to clear the local storage, but that’s not really necessary.

https://fqdn/desktop/locallog

Second, send in a new call which is supposed to trigger the workflow.

Thrid, in a new tab open the locallog URL and let’s walk through what we see.

One of the first things you’ll see is that Finesse pulls all the workflows associated with your team:

2019-02-19T15:46:46.901 -05:00: BF8760: FQDN: Feb 19 2019 12:46:47.214 -0800: Header : [ClientServices] Workflows: requestId='undefined', Making REST request: method=GET, url='https://FQDN:/finesse/api/User/9056/Workflows?nocache=1550609206901'
2019-02-19T15:46:47.227 -05:00: BF8760: FQDN: Feb 19 2019 12:46:47.540 -0800: Header : [ClientServices] Workflows: requestId='undefined', Returned with status=200, content='&lt;Workflows&gt;&lt;Workflow&gt;&lt;name&gt;PARTICIPANT OVERVIEW WORKFLOW&lt;/name&gt;&lt;description&gt;PARTICIPANT OVERVIEW&lt;/description&gt;&lt;uri&gt;/finesse/api/Workflow/1&lt;/uri&gt;&lt;TriggerSet&gt;&lt;name&gt;CALL_ARRIVES&lt;/name&gt;&lt;type&gt;SYSTEM&lt;/type&gt;&lt;triggers&gt;&lt;Trigger&gt;&lt;comparator&gt;IS_EQUAL&lt;/comparator&gt;&lt;value&gt;Voice&lt;/value&gt;&lt;Variable&gt;&lt;name&gt;mediaType&lt;/name&gt;&lt;node&gt;//Dialog/mediaType&lt;/node&gt;&lt;type&gt;CUSTOM&lt;/type&gt;&lt;/Variable&gt;&lt;/Trigger&gt;&lt;Trigger&gt;..

Next you’ll see that Finesse will see if there’s a workflow to run if the agent has logged in or gone ready. So it will evaluate the workflow conditions based on this trigger. This happens always even if you don’t have a workflow with these trigger conditions.

2019-02-19T15:46:47.237 -05:00: BF8760: FQDN: Feb 19 2019 12:46:47.550 -0800: Header : [WorkflowEngine] Entering 'Busy' state, from: 'loggingIn'. Triggering start of queued event processing.
...
2019-02-19T15:46:47.412 -05:00: BF8760: FQDN: Feb 19 2019 12:46:47.725 -0800: Header : [WorkflowEngine] "" IS_EQUAL "Voice" evaluates to FALSE

So far so good, but we’ve not gotten to our workflow which is supposed to launch on call arrival.

2019-02-19T15:48:14.103 -05:00: BF8760: FQDN: Feb 19 2019 12:48:14.419 -0800: Header : [WorkflowEngine] Entering 'Busy' state, from: 'idle'. Triggering start of queued event processing.
...
2019-02-19T15:48:14.191 -05:00: BF8760: FQDN: Feb 19 2019 12:48:14.507 -0800: Header : [WorkflowEngine] Evaluating conditions for workflow: {"workflowName":"CASE SEARCH","eventType":"Dialog","eventUri":"/finesse/api/Dialog/33558863"}
2019-02-19T15:48:14.191 -05:00: BF8760: FQDN: Feb 19 2019 12:48:14.507 -0800: Header : [WorkflowEngine] "ATTORNEY" CONTAINS ""ATTORNEY"" evaluates to FALSE

As you can see in the last line our workflow is supposed to launch if ATTORNEY contains ATTORNEY, but we have “” arround the string which is causing it to not match. By going to Finesse adming and changing your workflow to not contain the quotes fixed the issue right up.

~david

Deploy to Firebase hosting using Bitbucket Pipeline

On and off I’ve played around with Firebase and one thing I had never tried out was the hosting part of Google’s offering. I spent a bit of time a few nights ago getting familiar with it and didn’t like the fact that I had to deploy from the command line as I generally like to do my deployments via git.

This excellent blog post showed me what I needed to do and everything seemed easy enough. Here is my original pipeline.yml

image: node:8.4.0
pipelines:
branches:
master:
- step:
deployment: production
caches:
- node
script:
- npm install -g firebase-tools
- firebase deploy --token=$FIREBASE_TOKEN --project mySite --non-interactive

When my pipeline ran I received the following error.

Error: Authorization failed. This account is missing the following required permissions on project &lt;project&gt;:
firebase.projects.get
firebasehosting.sites.update

The issue was resolved when I looked at the –project parameter. Everything I read said project name, but in reality it needs to be the project ID, which you can get from Firebase project console. Once this was rectified the pipeline ran succesfully.

~david

Upgrading Cisco SG200-26 Smart Switch Firmware and Boot

This took me a bit longer than I expected mainly because the release notes were not clear. Like the title suggests there are two types of upgrades you can do to this device, the firware and the boot file. If you’re going to the latest version released by Cisco which at the time of this post is 1.4.x, you want to start with the boot file and upgrade that to 1.3.x using a TFTP server. After that you’ll want to upgrade the firmware to 1.3.x. After that you’ll be able to upgrade to 1.4.x.

One other thing to note, when reseting the device to factory defaults I could never login to 192.168.1.254 on port 1, I had to move my laptop to port 9 in order to get to the web UI.

~david

Amazon Connect CCP (Agent Desktop) Walkthrough

I was talking to a few people about Connect and we were focusing on the agent desktop. For someone who is coming from Cisco Finesse, CCP is a big departure and I couldn’t find a good resource which showed all the out of the box functionality in a concise way. So, here it is. Everything you need to know about straight out of the box CCP.

CCP Highlights

  • 100% web-based.
  • Uses WebRTC and Opus audio codec.

Login Screen

  • Can be integrated to SSO.
  • Allows for password self-service.

image

Initial Screen

  • Will set you to whatever state you last had before you logged off or killed the client.
  • Transfer buttons are semi context aware (more on this later).
  • Agent status/state menu.
  • Log out is not a state, but a separate button.
  • Ability to get calls via a hard phone/PSTN instead of over the web.
  • Ability to download agent side logs (JSON format) from first login to right now.
  • Multi-lingual support 8 languages.

imageimageimageimageimage

Call Screen

  • Agent whisper of queue name.
  • ANI of caller.
  • Transfer numbers based on queue name.
  • Can transfer to another queue, another agent, or external. Can even transfer to yourself which makes no sense.
  • Multi line support.
  • Can make outbound calls manually.

12

image3image

~david

Continuous deployment to Amazon Lambda using Bitbucket Pipeline

I’m not a developer (more of a hack) so I’m always looking for way to figure out efficiencies in my process when playing around with code as I’m a very slow coder. One of those efficiencies found is around deploying my code to Amazon Lambda.

First, let’s talk about your options when deploying code to Lambda. The easiest way is to just do your development using Amazon’s IDE. The benefit here is that you can manually run some tests to validate what you’re writing, however if you’re using any dependencies the IDE has a size restriction and at some point it’s no longer available to you.

image

The next method is doing local development and creating a zip file of all your code and dependencies. Then manually upload your code. You can then run the same manual tests as before on your code, but the process of zipping and uploading the file is tedious specially when working on large code bases.

image

Next process involves the very good Amazon CLI. Using the CLI you’ll be able to save the manual process of uploading the zip file. Below you’ll find the Windows scripts I use one for small code bases (without dependencies) and one for larger ones.


echo on

del index.zip

echo Deleted index.zip

"c:\Program Files\7-Zip\7z.exe" a index.zip index.js

aws lambda update-function-code --function-name mySmallLambdaFunction --zip-file fileb://index.zip

echo done

[/sourcode]</blockquote>
<blockquote>

echo on

del myZip.zip

echo Deleted myZip.zip

"c:\Program Files\7-Zip\7z.exe" a myZip.zip index.js node_modules

echo Zipped myZip.zip

aws lambda update-function-code --function-name myLargeLambdaFunction --zip-file fileb://myZip.zip

echo done

Finally, the process I’ve come to enjoy the most is deploying from git. The main reason being that it forces you have a bit of a process around using git which is pretty much the standard when collaborating with multiple developers. So if you’re dragging your feet around using git take the plunge it’s worth the learning. My favorite, mainly because they have a very generous free offering is Bitbucket. Besides having private repositories they also give you 50 free build minutes which is where our deployment to Lambda from Bitbucket comes in. To get started you first need to setup a few environmental variables. Go to your repository > settings > environment variables. You’ll need these named exactly this way.

image

The next step can be done in two ways. You can commit a bitbucket-pipelines.yml file to your repository or you can go to your repository > pipelines to have Bitbucket commit one for you. What the original yml file looks like doesn’t matter we’re going to change it specifically for Lambda deployment. Here’s what my file looks like with inline comments.


#I like to use the same version of Node as the Lambda function I’m using.

image: node:6.10

pipelines:

default:

- step:

script: # Modify the commands below to build your repository.

- apt-get update

- apt-get install -y zip

- python –version #From here to there is all to enable the AWS CLI installation

- apt-get install -y python-dev

- apt-get install -y python-pip

- pip install awscli #there

- zip index.zip index.js #this is for a Lambda with a small code base. For something large you can use “zip myZip.zip index.js privatekey.json -r node_modules” notice the –r parameter to zip up folders.

- aws lambda update-function-code --function-name botValidationScheduleMeeting --zip-file fileb://index.zip

Assuming you’ve done everything right you should see something like this under Pipelines.

imageThe last 3 commits were successfully built (sent to Lambda). You can click on the commit and see detailed information on the results of every command in your yml file. You’re done, you’ve developed some code locally, committed to git, and pushed it to Lambda all with a few clicks.

~david

Bringing Amazon Lex into your Amazon Connect flows

In this blog we’ll continue our discussion around Amazon Lex. Talk about a few things to keep in mind when integrating your Amazon Lex bot with your Amazon Connect flow. In my particular use case I wanted to use Amazon Lex to look at my Gmail calendar and book a meeting if I’m available. If you want to skip to the very end you can see the end result via video. You’ll see one video of the voice interaction and one of the Facebook Messenger interaction.

First, you might want to reference my previous post around Lex validation. Now let’s talk about our use case:

  • Lex easily allows you to build a bot which understand both voice and text, so our bot needs to handle calls into our call center as well as Facebook Messenger interactions.
  • Bot needs to to ask a few question in order to find out what time the user would like to meet.
  • Bot should only schedule calls between Monday-Friday and 10 AM – 4 PM Easter Time
  • Bot (using Lambda) should schedule a meeting and if slot already taken then suggest an alternate time to meet.

Second, let’s take a quick look at the Lex screen. The bot I created is very simple and it follows closely the Flowers example provided by Amazon. These are the slots I’m requiring my bot to confirm.

image

I used two different Lambda functions. One for validation and one for fulfillment. While most examples seem to focus on using the same function for both, for me it was easier to have different code bases for each with the added benefit of keeping the code manageable. As it is both validation and fulfillment both came in at around 250 lines of code, but fulfillment had around 9 megabytes of dependencies.

image

Finally, here are sample utterances I used for the main intent.

image

What this gets us is the following. The first video is the voice interaction. I went about it the long way to show some of the validation rules being set by the bot, such as no weekend meetings and no meetings too early in the day. At the end of the video you see I refresh the Gmail calendar to show the new appointment has been saved.

In the second video I go through the same Lex bot using Facebook Messenger and then show the calendar to prove that the appointment was saved.

Ultimately, Amazon makes it extremely easy to create a mutli channel bot, however the integration to back end systems is the tricky part. This bot needs a lot of tuning to make it more natural, but for just a few hours of work there’s very little out there that can get your call center to have some bot integration for self service.

~david