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='<Workflows><Workflow><name>PARTICIPANT OVERVIEW WORKFLOW</name><description>PARTICIPANT OVERVIEW</description><uri>/finesse/api/Workflow/1</uri><TriggerSet><name>CALL_ARRIVES</name><type>SYSTEM</type><triggers><Trigger><comparator>IS_EQUAL</comparator><value>Voice</value><Variable><name>mediaType</name><node>//Dialog/mediaType</node><type>CUSTOM</type></Variable></Trigger><Trigger>..

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

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

Cisco Spark Webhooks using Node.js

I’ve been trying to come up with a reason to play around with node.js. I’ve also been trying to make some time to play around with the Cisco Spark API. So I figured I would merry the two of them. My intention was to setup a webhook on a channel, then in my node application display the messages being posted in my room. Pretty simple example, but it touches a few different things.

First, you need to setup your webhook to point to your server.

Second, you need to have node installed, in this case I’m using Ubuntu 16.04.

Third, write some code. Check out my comments to follow along.

//will use these for the POST request

var express = require("express");
var myParser = require("body-parser");
var app = express();

//will use this for the GET request

var http = require(‘https’);

app.use(myParser.json());
app.post("/", function(request, response){

console.log(request.method);

//console the webhook name as well as the name of the author of the message
console.log(‘Webhook:’+request.body.name);
console.log(‘Email:’+request.body.data.personEmail);

//setup your GET request to find out the actual message posted by the author

var options = {
host: ‘api.ciscospark.com’,
path: ‘/v1/messages/’+request.body.data.id,
headers: {
  ‘User-Agent’: ‘request’,
  ‘Authorization’: ‘Bearer MyAuth’
}
}

//make the request

http.request(options, OnResponse).end();
});

//capture the request response

function OnResponse(response){
var data = ”;
response.on(‘data’, function(chunk){
  data += chunk;
});

response.on(‘end’, function(){
  data = JSON.parse(data);

//console out the actual text
  console.log(data.text);
});
}

app.listen(8080);

~david

Cisco Finesse Desktop Tabs for Supervisors

This came up on this thread and figured I would post something about it is an easy mistake. The Finesse layout is devided into an Agent and Supervisor section. So adding a tab to the top of the default layout will only add it to the Agent view. You can tell the layouts apart by the following tags:

<layout>
    <role>Agent</role>
    <page>

</layout>

or

<layout>
    <role>Supervisor</role>
    <page>
</layout>

~david

Another star!

A lot of people run into me in the Cisco Support Forums as I try to keep pretty active not only to keep my memory fresh on some stuff I don’t touch much but to also keep a pulse on what the world is working on. The forum allows other users to provide you with points based on how they find your answers useful. Just got to the next level based on points awarded, a lovely shade of blue.

image

The breakdown:

image

Find UCCE agents and their assigned attributes and level

Maybe I should have checked CUIC to see if there was something, but I don’t remember something like this available. All I wanted was to see all my agents their attributes and levels.

SELECT [lab_awdb].[dbo].[Agent].EnterpriseName
      ,[lab_awdb].[dbo].[Attribute].EnterpriseName
      ,[AttributeValue]
  FROM [lab_awdb].[dbo].[Agent_Attribute]
JOIN [lab_awdb].[dbo].[Agent] ON [lab_awdb].[dbo].[Agent_Attribute].[SkillTargetID] = [lab_awdb].[dbo].[Agent].[SkillTargetID]
JOIN [lab_awdb].[dbo].[Attribute] ON [lab_awdb].[dbo].[Attribute].AttributeID = lab_awdb.dbo.Agent_Attribute.AttributeID

~david

Finesse Error: The device associated with that extension or dial number is invalid.

This is the first time I’ve used an 8945 phone as an agent phone and while the documentation states it’s supported, I kept getting the above error which made no sense to me as everything looked right. Checked out the jtapi logs and this is what it said:

16:48:24:420 PG1A-jgw1 Trace: MsgAddCallObserver:  Addr: 7778 Remote Addr: 0 InvID: 8380 CallDeliveryMode ID: 0.
16:48:24:420 PG1A-jgw1 Trace: Adding Call Observer to: 7778.
16:48:24:420 PG1A-jgw1 Trace: Address Name: 7778IP Addressing Mode:IP_ADDRESSING_MODE_IPV4.
16:48:24:420 PG1A-jgw1 Trace: AddCallObserver address validation failed – Address Name: 7778, error code: 154.
16:48:24:420 PG1A-jgw1 Trace:   MsgAddCallObserverResponse:  Addr: 7778 Succeeded: 0 InvID: 8380 Cause: 154.

Which then let me to this link. The problem was something I’ve never had to set in the UCM before. Join And Direct Transfer Policy.

image

Once that was changed the the phone recycled, everything worked. Go figure.

~david

Add Connection Profiles to Cisco AnyConnect Secure Mobility Client

I enjoy the new VPN client, it’s small and fast, however I hated that you can’t save profiles in the drop down list like you could in the traditional VPN client.

VPNNoProfile

This has been bothering for a long time and kept finding conflicting information on if this was possible or not. Finally got it to work.

VPNProfiles

This is for version 3.1x and Windows 7 let me know if this works for your version and OS.

  • Create a preferences.xml file in C:\ProgramData\Cisco\Cisco AnyConnect Secure Mobility Client\Profile\
  • Use this format

<?xml version="1.0" encoding="UTF-8"?>

<AnyConnectProfile xmlns="http://schemas.xmlsoap.org/encoding/">
<ServerList>
     <HostEntry>
          <User>dclouduser</User>
          <SecondUser></SecondUser>
          <ClientCertificateThumbprint></ClientCertificateThumbprint>
          <ServerCertificateThumbprint></ServerCertificateThumbprint>
          <HostName>dCloud</HostName>
          <HostAddress>dcloud-rtp-anyconnect.cisco.com</HostAddress>
          <Domain></Domain>
          <Group>ssl_url</Group>
          <ProxyHost></ProxyHost>
          <ProxyPort></ProxyPort>
          <SDITokenType>none</SDITokenType>
          <ControllablePreferences>
          <LocalLanAccess>true</LocalLanAccess></ControllablePreferences>
     </HostEntry>

     <HostEntry>
          <User>dmacias</User>
          <SecondUser></SecondUser>
          <ClientCertificateThumbprint></ClientCertificateThumbprint>
          <ServerCertificateThumbprint></ServerCertificateThumbprint>
          <HostName>Speech-Soft</HostName>
          <HostAddress>vpn.dmacias.com</HostAddress>
          <Domain></Domain>
          <Group>ssl_url</Group>
          <ProxyHost></ProxyHost>
          <ProxyPort></ProxyPort>
          <SDITokenType>none</SDITokenType>
          <ControllablePreferences>
          <LocalLanAccess>true</LocalLanAccess></ControllablePreferences>
     </HostEntry>
</ServerList>

</AnyConnectProfile>

  • Save the file.
  • Restart the connectivity client.
  • Enjoy

~david

EDIT 01/18/2017: This also works with Cisco AnyConnect 4.x!