Cognitive Services, CRM, USD

Adding a Sentiment Widget to USD

Recently, Microsoft announced a partnership with the good folks over at CafeX around bringing their Chat and Co-browse capability called LiveAssist to be a part of our Dynamics 365 patform.  This exciting new partnership extends our platform’s ability to engage customers across additional channels, with “built-in” support for multi-session Chat and Co-browse today, and video & voice support coming soon. Having these new features at our disposal also opens up new opportunities to extend them in combination with some of our other key platform features.

Microsoft Cognitive Services, as an example, provides a rich platform for extending our applications to take advantage of a number of interesting services like sentiment analysis, facial recognition, translation and more. In this article I’m going to show you how to leverage the sentiment analysis API to build a simple widget for Unified Service Desk that will display the sentiment for incoming chat messages from our LiveAssist platform and track themm for the current session, on a graph.

NOTE: This work is heavily based on some great stuff already produced by my teammates Geoff Innis and Kate Michel – all I’ve done is built on what they’ve already outlined to an evolutionary “next step”. I greatly appreciate everything they have already done in this area, and am pleased to be able to leverage some of their great work, including Kate’s idea to capture sentiment over time in a chart visualization, as a foundation to build on for this solution example.

ALSO NOTE: This article contains SAMPLE CODE – not production-ready code, bug-free code, nor any guaranteed code. You are free to use this software to enhance your Unified Service Desk experience AT YOUR OWN RISK, with NO WARRANTIES EXPRESSED OR IMPLIED. If something goes wrong, I warned you 🙂

Now that I think I’ve covered all those bases, let’s get started with an overview of this solution.

Part 1 – Cognitive Services

We start out with a Cognitive Services account – if you don’t have one, you can get one for free at the following location:

For sentiment analysis, we’ll be leveraging the Text Analysis API to capture the sentiment for incoming chat messages. Although this API is a paid service, there is a “Free Tier” you can sign up for that allows you to develop and test your components with reasonable limits applied to the API.

Once you get signed up for this API, you’ll want to capture your API Key – this will be used later in the code we’ll write to request the sentiment for a given incoming message.


The widget I’ve created is a simple HTML document that has some JS code to fetch the sentiment score for a given incoming text message and display it a couple of different ways. The sample code can be downloaded at the following link:

As of this writing, this coincides with my original “v4” of this component (that note is more for my benefit, than for yours).

The steps to leverage this component are pretty simple:

  1. Either point to or download the above file. You can put it in a CRM Web Resource, or you can, as I have done, leverage it from an Azure Blob Storage location so all of your instances can have easy access to it.
  2. Set a few query string parameters to configure the component
  3. Update the Unified Service Desk configuration to define a new Hosted Control for the chart, and a set of actions on top of the LiveAssist chat control to connect the chats to the sentiment chart.

I will breifly go through each of these areas in the sections below.

Pulling parameters from the Query String

In order to support multiple users, and multiple languages, I’ve included query string parameter support allowing users to configure the core behavior of the component. Those parameters are outlined below:

  1. Language (l) – This is a two-letter abbreviation for the language upong which to base the sentiment analysis. The codes are listed in the Text Analytics API documentation page. As of this writing, there are 4 supported languages:English (en)
    Spanish (sp)
    French (fr)
    Portuguese (pt)
  2. Sentiment Key (s) – this is the key you saved in the step above from registering for the API. My key is 30 characters of mixed letters and numbers.

When fully assembled, the url will look something like this:


The Code for the Chart

The chart is essentially an HTML, JavaScript and CSS component that leverages the Text Analytics API to derive a sentiment score for an incoming text message, and display it as a raw score, adds it to a historical sentiment score chart of the current conversation and adds in a moving average of the overall conversation sentiment.

The HTML and CSS are pretty straight-forward, but I’ll outline a couple of interesting aspects of the JavaScript here:

First, the code that is used to capture the Sentiment from the API. It’s a simple POST back to the Text Analytics API, with the addition of some specific headers to define the structure of the call and supply the authentication token. There is also a payload sent to the API that follows a specific structure.

function getSentimentForText(inputText) {

	// display the incoming chat message in a hidden area for debugging
	// HACK: there is currently a bug in the Chat control where all messages
	//       coming from either the Agent or the Customer are sent through
	//       the Chat Control's "ChatMessageReceived" event. This will be 
	//       fixed in the future, but we're doing this now to compensate
	if (inputText == lastChat) {
		// do nothing

	lastChat = inputText;

	// URL for the Text Analytics API
	var url = "";

	var inputData = {
		"documents": [{
			"language": languageKey,
			"id": "1",
			"text": inputText

	var stringData = JSON.stringify(inputData);

		type: "POST",
		beforeSend: function(request) {
			request.setRequestHeader("Accept", "application/json");
			request.setRequestHeader("Content-Type", "application/json");
			request.setRequestHeader("Ocp-Apim-Subscription-Key", sentimentApiKey);
		url: url,
		data: stringData,
		success: function(outputData, textStatus, jqXHR) {
			var score = outputData.documents[0].score;
			var roundedScore = Math.round(score * 100) / 100;
			updateSentiment(inputText, roundedScore);
		error: function(jqXHR, textStatus, errorThrown) {
			alert("ERROR: " + errorThrown);


Note that the header section includes a Ocp-Apim-Subscription-Key header – this value is the API Key supplied in through the “s” parameter, as well as the language key (which my code defaults to “en”, for English) to specify the source language for your incoming text.

For the chart, I opted to use the free Combo Chart component from our friends at Google Charts. This chart component accomplished exactly what I was looking for – a bar chart for the individual sentiment scores combined with a line chart for displaying the average. You can review the code for the updateSentiment() method in the downloaded component. Basically it accomplishes a couple of things:

  1. Display the sentiment score along with an accompanying graphic indicating the overall sentiment of the message (in my case, it’s a smile, “meh” or frowny face icon, courtesy of the guys and gals over at Font Awesome)
  2. Update the Average Sentiment score for the whole of the converation
  3. Update the chart with both the latest score (bar) and the updated average (line)

Oh, and before I forget – for retrieving the query string parameters, I leveraged some community-edited code from Stack Overflow to make this job really easy:

 function getParameterByName(name, defaultValue, url) {
	// process defaults and initialize
	if (!defaultValue) defaultValue = "";
	if (!url) url = window.location.href;
	name = name.replace(/[[]]/g, "\$&");
	// set up regex and retrieve values 
	var regex = new RegExp("[?&]" + name + "(=([^&#]*)|&|#|$)"),
		results = regex.exec(url);
	if (!results) return defaultValue;
	if (!results[2]) return defaultValue;
	return decodeURIComponent(results[2].replace(/+/g, " "));

Configuring Unified Service Desk

This is the most complex part of implementing this solution, but only because it has the most steps:

  1. Define the Hosted Control for the Chart component
  2. Define an action to load the hosted control when a new session starts
  3. Define the unexposed event on the Chart control to capture incoming chat messages
  4. Define an action to call into the Chat component to retrieve the last message received and put it into the session context
  5. Define an action that passes the most recent chat message from the Chat component to the Chart component

Define the Hosted Control

The hosted control definition is pretty straight-forward. This is a webpage, so we’ll use Standard Web Application. We want it to be part of the Session, so it’s marked as dynamic, but not global. I’ve also placed it in the LeftPanel1 location, but you can put it wherever you like.

New Session Action

Once the Hosted Control is defined, we now need to show it when a new session is created. This is done through a simple Action Call triggered on the CRM Global Manager’s NewSession event:

Set Size of Sentiment Chart

You’ll also (potentially) need to set the size of the Sentiment Chart window, depending on which panel you place it in. Here’s a quick sub-sction for LoadSentimentChart that you can use to accomplish this:

Get Last Chat Message From Chat Control

This action call retrieves the last message retrieved from the Chat Control and puts it where USD can leverage it. We have to ask for it specifically because there could be multiple chat sessions currently active, and we need to make sure we’re pulling the chat message from the correct session:

Call Sentiment Chart Component

Now that we have the chat message safely in session, we can push it into the Chart control through a “send” sub-action assigned to the previous “get” action.

Note: For those new to USD, each action can have a set of sub-actions defined. The first picture below is the definition for the sub-action’s Action Call, and the second picture is the inclusion of that sub-action call to the parent Get Sentiment for Last Chat Message. More information about Sub-Action calls can be found here.

This Action Call deserves a little explanation:

This Action is defined as a RunScript command that basically executes JavaScript inside the target panel. This allows us to call functions, change CSS properties, get HTML attribute values, and more.  In our case, we’re pulling the last chat message out and sending it to the getSentimentForText method which is where all the magic happens.

ChatMessageReceived Event

Finally, we can wire up the last two actions we created to the missing Event definition from the Chat control. The component does raise this event when new messages are received, but if it’s not defined in the Events list in USD, you can’t respond to it. So, we add it with very little configuration, which enables us to wire up the last two Actions.


The new LiveAssist chat and co-browse capabilities are a great addition to our arsenal of tools in Dynamics 365 and the Unified Service Desk. Extending their functionality with our Azure-hosted Cognitive Services adds additional value to chat-based interactions with customers. The range of applications here are virtually endless – everything from agent training based on their tracked sentiment scores, to auto-routing of chat requests for historically “difficult” customers, and everything inbetween.

So – what are you going to build? Try something crazy and let me know what you’ve done – I’d love to see it in action!


Cortana to Give Voice and Ears to Dynamics CRM 2015

Cortana on Windows Phone 8.1 devices interacting with Dynamics CRM? That’s a #win

Dynamics CRM 2015 will ship next month with multiple enhancements, including one literally audible: using Cortana on Windows Phone 8.1 devices, users will be able to talk to the customer relationship management suite.

– via CIO Magazine

How great will it be to be able to just ask Cortana to schedule a meeting for me, or record a note in one of my opportunities. Interacting via voice will make it a lot more convenient to keep my opportunities updated, especially when I’m driving and shouldn’t have my hands on the keyboard 🙂

Here’s a cool video showing off some of these features:





Development, WP8

Check out these Windows Phone apps!

Here’s a list of neat Windows Phone apps for you to check out:

Name Link
Quick Run
How To Create Apps
Notes Man
Movie Collection
Numbers and Genius
C Sharp Instructional Videos
Game maker Tutorias
ASP.NET Tutorials
My Minutes
Tally Tool
Car Locator
The Escape
Piggy Banker
Time Attack
Applause Light


Give them a try, and let the author know what you think!

Development, Students, Windows, Windows 8, Windows Azure Mobile Services, WP7, WP8

Code to Win!

Our team at Microsoft is excited to announce the return of the Windows 8 Student App Madness Challenge! Create and publish a Windows 8 app by April 14th, 2014 and you could win* a $50 gift card. Promote your app and receive 100 downloads for the chance to win* an additional $50 gift card. Microsoft will provide you with all the software, resources and support you need to get started, build your app, and publish it to the Windows Store. This is a great opportunity for you to get some app building experience, and win prizes while doing it!

There are two ways you can win:

What could be easier!  There are a lot of helpful tools to get you started including some great app templates, like the SUPER-AMAZING Cross-platform Cloud Kit, advice on building great app logos for your new apps, and great training available online to help you build out the next great app.

As always, reach out to me if you have any question about building apps for Windows 8 and Windows Phone, or if you’re interested in learning more about Windows Azure. Our team is here to help you whenever you need us!


MoDev Windows $10K App Contest

Just this week on 10/1, some of our friends over at MoDev announced a contest, for a chance to win cash prizes, totaling $10K.  My favorite part, is that you can actually control whether or not you win, with a public vote, which will occur after the contest entry period ends on 12/31.  You just have to get your friends (and their friends) to vote for your app! Helps drive awareness for your published app & increase your downloads, but also increases your chance to win!  Check out the details below:

The Modev Windows $10k App Contest

We’re looking for those game changers, industry disruptors—denizens of creative awesome from across the developer community. We’ll award prizes two ways:

  1. An impartial panel of judges will pick the top three apps from among the entries and award prizes
  2. We’ll put the pool of entries up for a public vote, and encourage some healthy competition between entrants to promote your app and get the public to vote for you

To qualify, entrants need to submit new Windows 8 or Windows Phone apps to the Windows Store or Windows Phone Store between October 1 and December 31, 2013, and fill out the Contest Entry form. Judging and public voting will begin in January 2014, with winners announced by January 31st.

Cloud, Development, ITPro, Product Announcements, USCloud

VMware or Microsoft? – The Complete Series

Some of the guys on my team have created an AMAZING series of blog posts comparing Windows Server and Hyper-V to VMWare’s offerings. Here’s a complete list of the entire series – you should DEFINITELY take a look…

Date Article Author
Aug 12, 2013 Series Introduction Kevin Remde@KevinRemde
Aug 13, 2013 What is a “Purpose-Built Hypervisor? Kevin Remde@KevinRemde
Aug 14, 2013 Simplified Microsoft Hyper-V Server 2012 Host Patching = Greater Security and More Uptime Chris Avis@ChrisAvis
Aug 15, 2013 Reducing VMware Storage Costs WITH Windows Server 2012 Storage Spaces Keith Mayer@KeithMayer
Aug 16, 2013 Does size really matter? Brian Lewis@BrianLewis_
Aug 19, 2013 Let’s talk certifications! Matt Hester@MatthewHester
Aug 20, 2013 Virtual Processor Scheduling Tommy Patterson@Tommy_Patterson
Aug 21, 2013 FREE Zero Downtime Patch Management

Keith Mayer@KeithMayer

Aug 22, 2013 Agentless Protection Chris Avis@ChrisAvis
Aug 23, 2013 Site to Site Disaster Recovery with HRM Keith Mayer@KeithMayer
Aug 25, 2013 Destination: VMWorld Jennelle Crothers@jkc137
Aug 26, 2013 Get the “Scoop” on Hyper-V during VMworld Matt Hester@MatthewHester
Aug 27, 2013 VMWorld: Key Keynote Notes Kevin Remde@KevinRemde
Aug 28, 2013 VMWorld: Did you know that there is no extra charge? Kevin Remde@KevinRemde
Aug 29, 2013 VMWorld: A Memo to IT Leadership Yung Chou@YungChou
Aug 30, 2013 Moving Live Virtual Machines, Same But Different Matt Hester@MatthewHester
Sep 2, 2013 Not All Memory Management is Equal Dan Stolts@ITProGuru
Sep 3, 2013 Can I get an app with that? Matt Hester@MatthewHester
Sep 4, 2013 Deploying Naked Servers Matt Hester@MatthewHester
Sep 5, 2013 Automated Server Workload Balancing Keith Mayer@KeithMayer
Sep 6, 2013 Thoughts on VMWorld Jennelle Crothers@jkc137
Sep 9, 2013 Shopping for Private Clouds Keith Mayer@KeithMayer
Sep 11, 2013 Dynamic Storage Management in Private Clouds Keith Mayer@KeithMayer
Sep 12, 2013 Replaceable? or Extensible? What kind of virtual switch do you want? Chris Avis@ChrisAvis
Sep 13, 2013 Offloading your Storage Matt Hester@MatthewHester
Sep 16, 2013 VDI: A Look at Supportability and More! Tommy Patterson@Tommy_Patterson
Sep 17, 2013 Agentless Backup for Virtual Environments Special Guest Chris Henley@ChrisJHenley
Sep 19, 2013 How robust is your availability? Kevin Remde@KevinRemde
Sep 20, 2013 VM Guest Operating System Support Brian Lewis@BrianLewis_
Sep 23, 2013 How to license Windows Server VMs Brian Lewis@BrianLewis_
Sep 24, 2013 Comparing vSphere 5.5 and Windows Server 2012 R2 Hyper-V At-A-Glance Keith Mayer@KeithMayer
Sep 25, 2013 Evaluating Hyper-V Network Virtualization as an alternative to VMware NSX Keith Mayer@KeithMayer
Sep 26, 2013 Automation is the Key to Happiness Matt Hester@MatthewHester
Sep 27, 2013 Comparing Microsoft’s Public Cloud to VMware’s Public Cloud Blain Barton@BlainBar
Sep 30, 2013 What does AVAILABILITY mean in YOUR cloud? Keith Mayer@KeithMayer

App Enthusiasts

Today marks the launch of the App Enthusiasts application for Windows Phone and Windows 8!

App Enthusiasts showcases applications created by developers around the world on Windows Phone and Windows 8. Stay up to date with the coolest creations by students, indie developers, and companies in your area. App Enthusiasts can filter apps by region, country, state and city, and it even keeps track of the apps you’ve seen across all of your devices! Microsoft employees are using App Enthusiasts to showcase apps at local events around the world, so if you’re interested in having your application promoted or if you’d like to find out about Enthusiast events in your area, please email”

What is exciting is that App Enthusiasts is more than just an app, it is a movement to bring visibility to applications created by Windows Phone and Windows 8 devs.  Microsoft field employees are planning to host events at Microsoft retail stores across the U.S.  At these events, developers featured in App Enthusiasts share their creations and speak to the audience about their inspiration.  We believe that an application like this can help create a community of supportive developers and fan interest alike.  I certainly suggest reaching out to if you have an app that you would like featured in this program!  Seriously, we want your best work to shine!

Let’s take a look at the app itself:

Upon launching either version of the app, the user is asked to authenticate with their Microsoft Account and is then greeted with a listing of applications organized by date:


Users can see at a glance what City, State, and Country an app has been published in.  Upon clicking an item, the user will be brought to the download page in the marketplace for the selected app.  When an item has been viewed, a checkmark appears next to the item indicating that it has been seen.


With these applications I found it really easy to discover cool apps coming from my geographical region. By setting the filter to my city I was able to see creations from people in my area.  From here I could easily install apps built by people I’ve actually met in the field.  Being able to curate and find their work made it incredibly easy for me to provide feedback and ratings.  It is a really great way for me to keep in touch with my community and help promote the Windows ecosystem.  If you want to know more about the upcoming events and how to showcase your app, send an e-mail to


BootCamp, CodeCamp, Development, Events, Featured, Students, Training, Windows, Windows 8, Windows Azure Mobile Services, WP8

Upcoming Microsoft Events

Hey all – the team is starting up a new round of Microsoft events – they’re similar to what we used to do with DevCares and MSDN Events (if you can remember back that far) but all have an education + hands on component to them.  This schedule is for all of Central Region, and although we unfortunately can’t visit every city in the region, hopefully you can find a city near you so that you can attend!

Build 2013 Highlights – The Best of Build!

Were you unable to attend Build 2013 and hear about the latest Microsoft product announcements for software developers? Never fear! In this session, we will give you the best of Build, covering the major announcements and technology innovations you need to know as a developer. We will show code and demos to get you up to speed on the latest with Windows 8.1, XAML, WinJS, Bing, Windows Azure, and Visual Studio.


  • Windows 8.1 and Windows Store changes
  • What’s new in XAML and WinJS
  • Introducing the Bing Platform
  • What’s new in Windows Azure
  • What’s new in Visual Studio and web
Date City
Sept. 24 Houston, TX
Sept. 24 Southfield, MI
Sept. 24 Indianapolis, IN
Sept. 25 Columbus, OH
Sept. 27 Overland Park, KS
Oct. 3 Edina, MN
Oct. 9 Austin, TX
Oct. 15 St. Louis, MO
Oct. 17 Irving, TX
Oct. 29 Chicago, IL
Nov. 14 Waukesha, WI
Nov. 22 Independence, OH


Monetization of Real-World Windows Apps

Often, as developers, we think of our pet software projects as a hobby. As it turns out, we have one of the most profitable hobbies in the history of hobbies! Billions of dollars have already been made by developers just like you that built an app for a mobile platform, and monetized it effectively. In this one-day event, we will share with you some modest and extreme success stories, some strategies for making money from your apps, and some technical instruction on exactly how to make that happen in your code. We will also demonstrate how easy it is to build one unified codebase that can used on Windows 8, Windows 8.1, and Windows Phone.


  • Overview of the platforms, success stories.
  • Monetization Strategies (trial, paid, ads, IAP)
  • Hands-on Labs
  • Implementing Pre-Lunch Strategies in App & Store
  • Using PCLs to share code and increase success
Date City
Oct. 15 Houston, TX
Oct. 17 Indianapolis, IN
Oct. 22 Detroit, MI
Nov. 6 Chicago, IL
Nov. 6 Dallas, TX
Nov. 6 Kansas City, MO
Nov. 6 Columbus, OH
Nov. 12 Edina, MN
Nov. 13 Austin, TX
Dec. 4 St. Louis, MO
Dec. 4 Cleveland, OH


Windows 8 + Windows Phone: Better Together

Trying to wrap your head around app development across multiple platforms? Trying to capitalize on the opportunities in both the Windows 8 and Windows Phone 8 marketplaces? Want to maximize your design and development resources and get to market better, faster, and stronger? Then come to this session and learn some real world techniques to maximize your efficiency of developing for both Windows 8 and Windows Phone 8. See how you can minimize your development costs by maximizing sharing and reuse between the two platforms.


  • Designing for sharing
  • Developing and sharing
  • Tips and Tricks / Architecture
  • And then there was 8.1… A quick tour of the new stuff
Date City
Nov. 5 Houston, TX
Nov. 14 Downers Grove, IL
Dec. 3 Indianapolis, IN
Dec. 10 Detroit, TX


Hands-on Labs: Windows 8 & Windows Phone

Build your first Windows 8 apps with an accompanying app on Windows Phone! We will start from scratch to create a Windows 8 app that is powered by the cloud AND includes a Windows Phone version too!


  • Window 8 + Cloud
  • Windows Phone
Date City
Nov. 15 Irving
Nov. 20 Columbus
Nov. 22 Chicago
Nov. 22 Houston
Nov. 22 Edina
Nov. 22 Austin
Nov. 22 St. Louis
Nov. 22 Southfield
Nov. 22 Indianapolis

Game On!

Want to quickly build and publish a Windows 8 game? Here’s your chance!


Whether you’re a novice or a seasoned pro, the Game On Virtual Event is for you. This FREE event covers everything you need to develop, upload and publish a Windows 8 game to the Windows Store. With GameMaker: Studio from YoYo Games, it’s easy to create an amazing game in record time. Thanks to built-in design options and drag-and-drop tools, you don’t need development experience to participate or build a Windows 8 game! Pro developers can also dig deep into the code to create a one-of-a-kind game experience.

Join us for this FREE virtual event kickoff on June 15 from 10:00am to 2:00pm (PDT), and then over the next seven days, build your game fast with individual help from the experts. All week long, we’ve got your back with one-on-one support, GameMaker forums, and an online Help Center that’s ready and willing to answer your questions. So if you’ve been thinking about building a game for Windows 8, now is the perfect time to make it happen.

Register for the Game On Virtual Event today.

Featured, Product Announcements, WP8

Windows Phone 8 Starter Kit for WordPress

After many emails, and much procrastination, I finally had a chance tonight to update the Windows Phone Starter Kit for WordPress over to Windows Phone 8 and update it to support WordPress 3.5.1.

For those of you running the old WP7 version, the changes you need to make to support WordPress 3.5.1 are pretty simple, but do require a bit of code writing.  To make it as easy as possible, this set of steps *should* work for a simple update:

  1. Open your Starter Kit in Visual Studio 2012 (this is now a Windows Phone 8 project, not a Windows Phone 7 project, so Visual Studio 2012 is now required).
  2. Copy all the code from and paste over the top of the existing code in your Visual Studio project.
  3. Recompile and test locally

Basically what I had to do was add a variable parameter to each of the query strings on the URIs requesting data from the WordPress site as it seems that WP3.5+ is caching the data based on the query string parameters now, which it didn’t used to do before.

If this doesn’t work, let me know and I’ll try to help walk you through it.