Developers / Admins / Tutorials

How to Build a Flow to Perform Emotion Analysis

By Shruti Sridharan

What is Emotion Analysis?

According to Wikipedia:

“Emotion recognition is the process of identifying human emotion, most typically from facial expressions as well as from verbal expressions. This is both something that humans do automatically but computational methodologies have also been developed.”

In this post, I will show you how to perform an analysis of emotions based on the verbal expressions that customers make every day with your organisation – more specifically in the context of customer service and case management. But first, let’s look at the background of Emotion Analysis and options for integrating it with your Salesforce instance.

How do I Start with Emotion Analysis?

Automatic analysis of emotions from verbal expressions uses techniques from Machine Learning (a subset of Artificial Intelligence). Of course, we are not Machine Learning scientists, so we need ready-made options; this is where FREE API platforms come to our rescue.

I guess that some Admins reading this blog might have lost a little interest when I mentioned APIs. Isn’t API a developer’s remit? Well, not anymore – trust me and continue reading! We will be accomplishing this without writing a single line of Apex.

Free APIs that Perform Emotion Analysis

There are numerous APIs that offers freemium based Emotion Analysis. In fact, Salesforce does offer one and it is called Einstein Sentiment (https://einstein.ai/products/community-sentiment).

Some notable ones are –

  1. IBM Watson Tone Analyzer (https://www.ibm.com/watson/services/tone-analyzer/)
  2. Amazon Comprehend (https://aws.amazon.com/getting-started/tutorials/analyze-sentiment-comprehend/)
  3. Google Cloud Natural Language API (https://cloud.google.com/natural-language/docs/sentiment-tutorial)
  4. Microsoft Text Analytics API (https://azure.microsoft.com/en-in/services/cognitive-services/text-analytics/)
  5. Indico (https://Indico.io/docs)

There are many other platforms that offer similar Emotion Analysis services. It’s important to note that these do have their own limits (Freemium subscriptions). For example, the Einstein Sentiment allows you to analyze only 1000 times per month. The others which include IBM Watson, Google Cloud, Amazon Comprehend, Microsoft etc. offers only a limited period of usage such as for a year, 3 months etc. The fifth one, which is called Indico offers up to 10,000 free Emotion Analysis every month.

So let’s explore the Indico Text Analysis APIs.

Note: I am not associated with Indico or any of their services. Indico was chosen since they provide higher and relaxed limits for usage and they are very easy to use.

Indico APIs for Emotion Analysis

Now, what is an API? In simple words, it provides a way through which two or more remote or disparate systems/entities can talk to each other. In our case, the two systems/entities involved are Salesforce and Indico.

In short, Salesforce would need to send a block of text to the Indico servers which would then perform the Emotion Analysis (employing AI) and return the significant emotions deduced from the text.

So, how do I send the block of text to Indico servers? That’s exactly when APIs would come in handy. APIs exist in several different formats but for our use case, we will utilize Indico’s REST APIs to both send, and analyze the emotion.

Generating API Keys

The first step that we need to perform before consuming the Indico REST APIs is to sign-up and generate an API Key. The API Key will be supplied along with our block of text to the Indico REST APIs. API Keys will be used by Indico to validate and authenticate the requests. You can visit the link: https://auth.Indico.io/ to sign-up and generate an API Key.

Sneak Peek at the Indico Text Analysis APIs

Let’s take a look at how the Emotion Analysis APIs of Indico looks like. The API endpoint/address is as shown below –

POST https://apiv2.indico.io/emotion

Fig. 1

Overwhelmed? Hang on! Let’s dive a little deeper. As mentioned before, the Salesforce would need to send the block of text along with the API Key to the Indico servers in order to perform the Emotion Analysis. Now how would one send the data to another server (i.e., Indico) ? That’s when we use the REST APIs.

The REST APIs will typically have an endpoint or address (similar to our Web Addresses or URIs). Figure 1 is the endpoint or address that is provided by Indico APIs, that will be utilized to detect the emotion in a given block of text. All we have to do is to send (technically called POST in the world of Web Programming) the text along with the API Key to this endpoint and it will, in turn, return the emotions deduced.

We humans talk to each other using a language, so the language is our medium of conversation. Similarly, in order to talk to the APIs, we need to send the data (i.e., the API Key and the block of text) in a specific format or say a language. Most of the REST APIs employs JSON (JavaScript Object-oriented Notation) format as the medium of conversation (or the format).

The Indico REST APIs (Emotion) expects the data to be formatted as shown below –

{

api_key: ‘YOUR_API_KEY’,

data: ‘I am so happy because I am going to learn about APIs.’

}

Fig. 2

This format (or method of writing) is called JSON. If you notice, all it contains is simple key-value pairs written on different lines separated by a comma.

The response or the analysis results returned by the Indico REST API (Emotion) will also be in the same format (JSON).
{

“results”: {

“anger”: 0.1694016456604004,

“fear”: 0.1427430659532547,

“joy”: 0.37557002902030945,

“sadness”: 0.20160073041915894,

“surprise”: 0.11068451404571533

}

}

Fig. 3

You can notice that the emotion with highest value/degree was Joy for the block of text that was supplied (shown in figure 2).

That was not tough. Correct? Now, what’s tricky is when you have to write all that Apex code in order to POST or send the data in the JSON format to the Indico REST APIs (Emotion). Wait! That’s not it. You will also have to write code to decipher the JSON results and process them accordingly.

But luckily, not any more! Let’s welcome – External Services.

Using External Services to Integrate Emotion Analysis APIs

External Services is a feature within Salesforce that leverages declarative tools to connect to an external endpoint/web address (such as the Indico REST API in our use case). In simple words, you no longer need to write Apex to do API Integrations. Under the hood, the External Service Builder automatically generates the Apex Class(es) for you which are concealed, and as an Admin, you really don’t need to worry about it.

If you want to read more about External Services, then I would highly recommend you to complete this excellent module on Trailhead.

Note: External Service is ONLY available in Lightning Experience.

Writing a Swagger Definition

This is that ONE place where you might feel a little giddy. But, not to worry!

In order for Salesforce to generate the Apex Classes automatically, you need to tell the External Service Builder, the details about your REST API (which in our case is the Indico REST API).

POST https://apiv2.indico.io/emotion

1. What’s the host?

apiv2.Indico.io

2. What’s the protocol?

https

3. What’s the path?

/emotion

4. etc.

The details about your API is written in a special format called Swagger Definition. Think of it like the language that External Service Builder understands. Most of the REST APIs on the Web today provides the Swagger Definition out of the box. This means that you do not have to write it by yourself but simply download it.

But unfortunately, Indico REST APIs did not have one. So, let’s see what it would look like.

{

“swagger” : “2.0”,

“info” : {

“description” : “Predicts the emotion expressed by an author in a sample of text.”,

“version” : “1.0.0”,

“title” : “indico API Text Analysis – Emotion”

},

“host” : “apiv2.indico.io”,

“schemes” : [ “https” ],

“paths” : {

“/emotion” : {

“post” : {

“summary” : “This function returns a dictionary that maps from 5 emotions (anger, fear, joy, sadness, surprise) to the probability that the author is expressing the respective emotion.”,

“parameters” : [ {

“in” : “body”,

“name” : “emotionAPIRequest”,

“schema” : {

“$ref” : “#/Definitions/EmotionAPIRequest”

}

}],

“responses” : {

“200” : {

“description” : “OK”,

“schema” : {

“$ref” : “#/Definitions/EmotionAPIResponse”

}

}

}

}

}

},

“Definitions” : {

“EmotionAPIRequest”: {

“properties”: {

“api_key”: {

“type”: “string”

},

“data”: {

“type”: “string”

}

}

},

“Results” : {

“properties” : {

“anger” : {

“type” : “number”,

“format”: “float”

},

“fear” : {

“type” : “number”,

“format”: “float”

},

“joy” : {

“type” : “number”,

“format”: “float”

},

“sadness” : {

“type” : “number”,

“format”: “float”

},

“surprise” : {

“type” : “number”,

“format”: “float”

}

}

},

“EmotionAPIResponse” : {

“properties” : {

“results” : {

“$ref” : “#/Definitions/Results”

}

}

}

}

}

Fig. 4

Yes, I agree that it might look a little intimidating. But, all it does is explain the details about the Indico REST APIs (Emotion) with the details as shown below in a JSON format.

  1. Title
  2. Description
  3. Host
  4. Scheme
  5. Request Format (see Figure 2)
  6. Response Format (see Figure 3)

You can find a downloadable version of the Swagger Definition here.

Creating a Named Credential

The next step is creating a Named Credential. A Named Credential is where we specify the endpoint/URI and the authentication details. Luckily, the Indico REST API doesn’t have a sophisticated authentication mechanism (it doesn’t mean it’s not secure though!). It uses an API Key based authentication mechanism and the same is sent along with the block of text. So we really don’t need to specify any authentication parameters but just the endpoint/URI like as shown below.

To create a Named Credential, start typing “Named” in the Setup and then click on New Named Credential.

Fig. 5

Registering the External Service

Let’s register the External Service. In order to do the same, start typing “External” in the Setup explorer. Then, click on the Add an External Service button. Type in a Name and select the Named Credential that we created in figure 5.

Fig. 6

Now copy the Swagger Definition from figure 4 and paste it in the Service Schema Complete JSON text area as shown above and click Save.

You will notice that the External Service was registered and the POST/send action was identified successfully.

Fig. 7

Building a Flow to Perform the Emotion Analysis

How do we use the External Service that we just registered?

The External Service that was registered can be used as an Apex Action inside a Flow. So in other words, we will be building a Flow that in turn would use the Apex Action (created as a result of the External Service registration) to make the call to the API.

Creating Fields to Store Analysis Results

But before we start developing the Flow, we have a bit of housekeeping that needs to be completed. As described in figure 3, Indico REST APIs (Emotion) returns the degree or a value that maps to five different emotions – Anger, Fear, Joy, Surprise and Sadness. Thus, we need to create 5 Custom Fields to store these 5 values corresponding to different emotions.

Let’s take a look our use case.

Use Case

Here is the use case for how we want to enable our support representatives. We will tackle the use case in two parts: the first part (in bold) in the remainder of this post, and the second in a follow-up post.

As a Support Representative, I need to analyze the emotion of the text in the Description field of a Case record created via Email to Case or Web to Case. Depending on the emotion, I want to automatically present to the Support User, Recommendations or the Next Best Actions that need to be executed.

Well, let’s create the 5 Custom Fields on the Case object.

Fig. 8

Let’s also create 2 Formula Fields that would display the highest emotion and it’s description respectively.

Fig. 9

Fig. 10

Developing the Flow

Let’s start building the Flow. Here is how our Flow would look like in the end:

Fig. 11

Don’t panic. We will go through each one of the nodes in detail.

DF 1.1

  1. Drag in a Screen Element on to the canvas.
  2. Add a Display Text component as shown above.

Then add a Toggle component with the Label and API Name as displayed in figure DF 1.1. Also add a Boolean Variable named isReadyToDetect in the Value field.

  1. Drag in a Decision Element on to the canvas.
  2. Add a Default Outcome with Label/API Name – Yes/Yes.
  3. Add a Criteria like as shown below –

{!tgglDetectEmotion.value} Equals {!$GlobalConstant.True}

Connect nodes on the canvas: [1] ➜ [2]

  1. Drag in a Get Records Element on to the canvas.
  2. Setup the Condition Requirements as shown above (see figure DF 3.1). Note: You will need to create a text variable named recordId as shown above. It’s very important to make the checkbox – Available for input checked as shown in figure DF 3.3.

Id equals {!recordId}

  1. Create a Record Variable named case and specify the Case Fields that need to be stored as shown in figure DF 3.2. Ensure that the Case Description field is selected. We will be sending the text contained in this field to the Indico REST API for Emotion Analysis.

Connect nodes on the canvas: [2] ➜ [3]

  1. Create a variable with name – apiRequest as shown in figure DF 4.1. The type of the variable will be Apex-Defined. This is the interesting part. If you click on the drop-down to select the Apex Class, you will notice that a class with name – ExternalService_IndicoAPI_EmotionAPIRequest was generated automatically and is available for selection. This was as a result of the External Service Registration. This Apex Class represents the JSON format (Request Body) that we discussed in figure 2. Thus, we really didn’t have to write any Apex at all!
  2. Now drag in an Assignment Element on to the canvas.
  3. Set the Variable Values as shown in figure DF 4.2. Note: The apiKey contains the API Key that we generated from the Indico website. You can store this as a Custom Setting (Hierarchy) and reference the same in your Flow as shown in figure DF 4.3.

Connect nodes on the canvas: [3] ➜ [4]

  1. Drag an Action Element on to the canvas.
  2. Filter By Type and select External Service. You will notice that the External Service that we had registered is now available for selection i.e., postEmotion (see figure DF 5.1).
  3. Click on the Set Input Variables tab and select the variable that we had created in step 4 (see figure DF 4.1).
  4. Click on the Store Output Values Now, in the input box labelled as 200, click New Resource to create an Apex-Defined type variable as shown in DF 5.3. This will hold the response from the API that we had discussed in figure 3 (at the beginning of the blog). Again, we never had to create the Apex Classes!

Connect nodes on the canvas: [4] ➜ [5]

  1. Create another Apex-Defined type variable named emotions as shown in figure DF 6.1. This will store the 5 different emotions and their respective value/degree that we discussed in figure 3.
  2. Now drag an Assignment Element on to the canvas.
  3. Set Variable Values as shown in figure 6.2.

Connect nodes on the canvas: [5] ➜ [6]

  1. Drag another Assignment Element.
  2. Set Variable Values for the Case Fields (for the respective emotions) as shown in figure DF 7.1. Note: Use the same Record Variable that was created in step 3.

Connect nodes on the canvas: [6] ➜ [7]

  1. Drag a Record Update element on to the canvas.
  2. Specify the Record to update as {!case}.

Connect nodes on the canvas: [7] ➜ [8]

  1. Finally, add a Screen Element with a Display Text as shown in figure DF 9.1.
  2. Connect nodes on the canvas: [8] ➜ [9]
  3. Activate the Flow.

Ouch! I know that was a lot of work. But you will realize that the effort was worth it when you finally test it.

Adding the Flow to the Record Page

Now, add the Flow to your Case Record Page using the Flow Lightning Component like as shown below –

Fig. 12

1. Add the Detect Emotion Flow to the Record Page as shown above.

2. Make sure that the checkbox – Pass record ID into this variable is checked. This ensures that the Id of the Case Record is passed into the recordId variable inside Flow.

Testing the Flow

Let’s have a look at the Flow in Action.

Fig. 13

Summary: Take a deep breath!

Now, take a deep breath. You have accomplished something commendable!

In this post, I have shown you how to perform an analysis of emotions in the context of customer service and case management. Remember this is only half of our full use case; in my next post, I will walk through how to then “show Recommendations or the Next Best Action” to your support users using Einstein Next Best Action, integrated with emotion analysis.

The Author

Shruti Sridharan

is a Senior Salesforce Developer. She is an Einstein Champion and a speaker at IEEE CSI Symposiums and Official SF APAC Webinars. She leads the WIT UG & blogs @shrutisridharan

Comments:

    jeff sumption
    March 26, 2020 9:41 pm
    I am trying to implement this and the json provide is incorrect. Would love some help since this is above my skill set

Leave a Reply