Einstein Sentiment Analysis

In the world of Artificial Intelligence technology, the Einstein Sentiment is a way to forecast whether a sentence is positive, negative, or neutral. 

We shall see a use case where the customers sentiment is predicted for a Case record in Salesforce and specifically, we are going to analyze the Description field which contains the details about the Case. 

Steps to be Followed: 

Step 1: we must create an Einstein Platform Services Account using the link https://api.einstein.ai/signup  and for more detailed info follow the steps in this link https://metamind.readme.io/docs/what-you-need-to-call-api#section-get-an-einstein-platform-services-account

Step 2: Follow this link  https://metamind.readme.io/docs/upload-your-key and Upload the Key which we have retrieved in step 1. 

Step 3: We must add the API endpoint as a remote site so create a Remote Site Setting by following the link https://metamind.readme.io/docs/apex-qs-create-remote-site.  

Step 4: From the Git Repo replicate the (JWT.cls and JWTBearer.cls) Apex Classes – https://github.com/salesforceidentity/jwt

Step 5: By referring to the below screenshot, create a Custom Setting to store the Endpoints. 

Step 6: Create a Lightning Component ‘getSentiments’ and calling it with Quick Action ‘getCustomerSentiments’ button, it will send the text in the ‘Description’ field to Einstein API Analysis and return the sentiment & its probability which we are capturing using two new fields. Find the sample screenshot of the sentiment analysis as below. 

The Code for this implementation follows: 

getSentiments.cmp 

<aura:component implements=”force:hasRecordId,force:lightningQuickAction” access=”global” controller=’EinsteinAPI’> 

    <aura:handler name=”init” value=”{!this}” action=”{!c.doInit}” /> 

    <aura:attribute name=”ShowSpinner” type=”Boolean” default = “true” /> 

    <div class=”slds-text-heading_small”> Your request is in Progress.Please wait.  

    </div> 

    <div class=”exampleHolder”> 

        <lightning:spinner alternativeText=”Loading” size=”small” /> 

    </div> 

</aura:component> 

getSentimentsController.js 

({ 

    doInit : function(component, event, helper) {  

        helper.getSentiments(component, event, helper); 

    }   

}) 

getSentimentsHelper.js 

({ 

    getSentiments : function(component, event, helper) { 

        var action = component.get(‘c.getCaseStatus’); 

        action.setParams({ 

            CaseId : component.get(‘v.recordId’) 

        }); 

        action.setCallback(this, function(response) { 

            if(response.getState() === ‘SUCCESS’) { 

                $A.get(“e.force:closeQuickAction”).fire(); 

                $A.get(‘e.force:refreshView’).fire(); 

            }else { 

                console.log(‘error’); 

            } 

        }); 

        $A.enqueueAction(action);     

    } 

}) 

EinsteinAPI.apxc 

global class EinsteinAPI { 

    public Static String caseText = ‘ ‘; 

    public Static String updateCaseId; 

    @AuraEnabled 

    public Static void getCaseStatus(string CaseId){ 

        updateCaseId = CaseId; 

        for(Case selectedCase : [SELECT Id,Description FROM Case WHERE ID =: CaseId]){ 

            caseText += selectedCase.Description; 

        } 

        findSentiment(caseText); 

    } 

    public Static String tokenEndpoint{ 

        get { 

            Einstein_API_Settings__c settings = Einstein_API_Settings__c.getInstance( UserInfo.getOrganizationId() ); 

            return settings.Token_Endpoint__c; 

        } 

    } 

    public Static Decimal tokenExpirationSeconds{ 

        get { 

            Einstein_API_Settings__c settings = Einstein_API_Settings__c.getInstance( UserInfo.getOrganizationId() );     

            return settings.Token_Expiration_Seconds__c; 

        } 

    } 

    public Static String registeredEmail{ 

        get { 

            Einstein_API_Settings__c settings = Einstein_API_Settings__c.getInstance( UserInfo.getOrganizationId() );         

            return settings.Registered_Email__c; 

        } 

    } 

    public Static String sentimentEndpoint{ 

        get { 

            Einstein_API_Settings__c settings = Einstein_API_Settings__c.getInstance( UserInfo.getOrganizationId() ); 

            return settings.Sentiment_Endpoint__c; 

        } 

    } 

    public Static String sentimentModelId{ 

        get { 

            Einstein_API_Settings__c settings = Einstein_API_Settings__c.getInstance( UserInfo.getOrganizationId() ); 

            return settings.Sentiment_Model_Id__c; 

        } 

    } 

    public Static String getAccessToken() { 

        ContentVersion base64Content = [ 

            SELECT  Title 

            ,VersionData 

            FROM    ContentVersion 

            WHERE   Title = ‘einstein_platform’ 

            OR      Title = ‘predictive_services’ 

            ORDER BY Title 

            LIMIT 1 

        ]; 

        String keyContents  = base64Content.VersionData.tostring(); 

        keyContents         = keyContents.replace( ‘—–BEGIN RSA PRIVATE KEY—–‘, ” ); 

        keyContents         = keyContents.replace( ‘—–END RSA PRIVATE KEY—–‘, ” ); 

        keyContents         = keyContents.replace( ‘\n’, ” ); 

        JWT jwt             = new JWT( ‘RS256’ ); 

        jwt.pkcs8           = keyContents;  

        jwt.iss             = ‘developer.force.com’; 

        jwt.sub             = registeredEmail; 

        jwt.aud             = tokenEndpoint; 

        jwt.exp             = String.valueOf( tokenExpirationSeconds ); 

        String access_token = JWTBearerFlow.getAccessToken( tokenEndpoint, jwt ); 

        return access_token; 

    } 

    public Static void findSentiment( String text ) { 

        String key = getAccessToken(); 

        Http http = new Http(); 

        HttpRequest req = new HttpRequest(); 

        req.setMethod( ‘POST’ ); 

        req.setEndpoint( sentimentEndpoint ); 

        req.setHeader( ‘Authorization’, ‘Bearer ‘ + key ); 

        req.setHeader( ‘Content-type’, ‘application/json’ ); 

        String body = ‘{\”modelId\”:\”‘+ sentimentModelId + ‘\”,\”document\”:\”‘ + text.trim().replace(‘\n’, ”).replace(‘\r’, ”) + ‘\”}’; 

        req.setBody( body ); 

        try{ 

            HTTPResponse res = http.send( req ); 

            SentimentResponse resp = ( SentimentResponse ) JSON.deserialize( res.getBody(), SentimentResponse.class ); 

            Map<Double,String> mapProbablity = new Map<Double,String>(); 

            Map<String,Double> mapLabel = new Map<String,Double>(); 

            List<Probabilities > labelWithProb = new List<Probabilities >(); 

            for(Probabilities prob : resp.Probabilities){ 

                Probabilities newProb = new Probabilities(); 

                newProb.label = prob.label; 

                newProb.probability = prob.probability; 

                mapProbablity.put(newProb.probability,newProb.label); 

                mapLabel.put(newProb.label,newProb.probability); 

                labelWithProb.add(newProb); 

            } 

            if(labelWithProb.size()>0){ 

                case updateCase = new case(); 

                updateCase.Id = updateCaseId; 

                updateCase.Einstein_Sentiment__c =mapProbablity.get(labelWithProb[0].probability); 

                updateCase.Sentiment_Probability__c =mapLabel.get(labelWithProb[0].label); 

                update updateCase;  

            }  

        } 

        Catch(exception e){ 

            System.debug(‘ Callout Error ‘+e.getMessage()); 

        }                        

    }    

    global class SentimentResponse { 

        webservice List<Probabilities> probabilities { get; set; } 

    } 

    global class Probabilities { 

        webservice String label { get; set; } 

        webservice Double probability { get; set; } 

    } 

Summary: 

The Einstein Sentiment is very much helpful in analyzing the customers feelings or emotions which therefore benefits the companies to focus on the unsatisfied customers and resolve their issues with a higher attention; so that; they can maintain the customer relationship in future. The JWT apex classes helps in making a call to token endpoint; so that; tokens get generated to proceed further making request to other Einstein services and finally returns the sentiment & its probability which get updated in the Case fields created specifically for this purpose and then we can report based on this fields to categorize the cases based on sentiment we have received and act upon it by transferring those cases with negative emotions to a special department for extra care and support. 

About MST

At MST Solutions our cornerstone is to adapt, engage and create solutions which guarantee the success of our clients. The talent of our team and experiences in varied business verticals gives us an advantage over other competitors.

Recent Articles

Harnessing Generative AI in Healthcare Insurance: Streamlining Operations and Enhancing Member Insights

Healthcare insurance providers are navigating new ground and capitalizing on new opportunities made possible through artificial intelligence. AI can be utilized to lower costs for payers and improve the member experience as well as the overall health and well-being of members, leading to greater member satisfaction and improving trust and reputation for the payer’s brand.

Read Article »

Work with us.

Our people aren’t just employees, they are key to the success of our business. We recognize the strengths of each individual and allow them time and resources to further develop those skills, crafting a culture of leaders who are passionate about where they are going within our organization.