PowerApps Webinar: Achieving Greater Productivity

A great webinar was posted recently by Joshua Greenbaum, Principal, Enterprise Application Consulting, & Co-Founder, ProQ Inc., titled Achieving Greater Business Productivity with PowerApps. The webinar was recorded and is available for public viewing at https://t.co/H0AeFLZ2kx. You will need to register, but I think you will definitely enjoy it. Give it a watch and let me know what you think!


LinkedIn Connector for PowerApps

Just saw this nugget of information from the LinkedIn website:

LinkedIn Sales Navigator + Microsoft: Phase 2

The part that struck me was this:

New Sales Navigator Integration with PowerApps

One of the requests we’ve commonly heard from enterprise customers is the ability to display Sales Navigator data within their own internal applications. PowerApps is a platform that enables you to build and deploy custom business applications for web and mobile across Office 365, Dynamics 365 and beyond – with little to no coding required. We are working on a set of Sales Navigator controls for PowerApps that will allow you to embed profiles of people and companies from Sales Navigator directly into your custom applications, with just a few clicks.

This is going to enable some really amazing role-tailored experiences for our sales customers!

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 = "https://westus.api.cognitive.microsoft.com/text/analytics/v2.0/sentiment";

	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!


10 Tips to Empower Customer Service Agents

Great new article from the Microsoft Dynamics blog on Ten Tips to Empower Customer Service Agents. Enjoy!


We’ve got some great new offerings that speak to #3 on this list – Provide Agents with a Centralized Knowledgebase.  The new Knowledge Management features in Dynamics CRM enable agents to find what they’re looking for faster than ever, and enable customers to participate in their own customer self-service requests. Having a single knowledgebase that spans internal and external users is a powerful tool for any call center.

Check out more great features in the latest version of Dynamics CRM by visiting our website at http://crm.dynamics.com.



Ready to learn about CRM?

Interested in learning more about Dynamics CRM? Not sure where to start? No worries!  There are tons of learning resources available online to help you get started on your learning journey. Here’s a short list our team has compiled:

Learning Resources:

Dynamics Learning Portal (Introduction & Getting Started):

Blogs – General:

Blogs – Dynamics Team members: 

Blogs – Dynamics CRM Partners:


Dynamics CRM Community Blogs:  https://community.dynamics.com/crm/b
This site includes aggregated content from the following sources:

  • CRM Software Blog
  • MSDynamicsWorld.com CRM News
  • Dynamics CRM User Group (CRMUG)
  • CRM Tip of the Day
  • Tips, Tricks, and Add-Ons from Inogic
  • Hosk’s Dynamic CRM Blog (Ben Hosking)
  • Customer Effective Blog
  • Jason Lattimer’s Blog (Jason Lattimer, MVP)
  • Scott Durow’s Dynamics CRM Blog (Scott Durow, MVP)
  • Innovating on CRM (Jerry Weinstock, MVP)
  • Donna Edwards – MSCRM Dynamics (Donna Edwards, MVP)
  • PowerObjects – Bringing Focus to Dynamics CRM
  • Magnetism Solutions Dynamics CRM Blog
  • Frank Lee’s Microsoft CRM and CRM Online Blog (Frank Lee, MVP)
  • Sonoma Partners Microsoft Dynamics CRM Blog
CRM, Videos

New – CRM Video Library

Just to make it easy for everyone, I’m capturing all of the CRM promotional, instructional and training videos from YouTube, and various places, and creating a Video Library on my blog. You can find that library on the main toolbar, or clicking here:


If you know of great videos – particularly those produced by partners, please drop me a line and let me know.


CRM, Videos

New CRM Videos

The CRM Support Team at corp has just released a BUNCH of new videos outlining some of the new features in CRM 2015 Update 1, which was just released this week. You can get to all of the CRM training videos on our YouTube channel at https://www.youtube.com/user/msdyncomm/DynamicsCRM, but here’s a full list of the Spring 2015 videos to make it easy for you to pick and choose:


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:


Read more at http://www.cio.com/article/2843013/cortana-to-give-voice-and-ears-to-dynamics-crm.html