Salesforce Contact Personality Insights with Watson

1. Introduction

In this blog, I am going to explain how to use contact personality insight by using contact twitter handler to Predict personality characteristics by using the twitter timeline. but you can leverage the Personality Insights other aspects based on the user profile information or Facebook post or even you can use Salesforce chatter post it self to understand.

2.What is Personality Insight?

Personality Insights extracts and analyzes a spectrum of personality attributes to help discover actionable insights about people and entities, and in turn guides end users to highly personalized interactions. The IBM Watson Personality Insights service provides an API that enables applications to derive insights from social media, enterprise data, or other digital communications. The service uses linguistic analytics to infer individuals’ intrinsic personality characteristics, including Big Five, Needs, and Values, from digital communications such as email, text messages, tweets, and forum posts.The service can automatically infer, from potentially noisy social media, portraits of individuals that reflect their personality characteristics. It can also determine individuals’ consumption preferences, which indicate their likelihood to prefer various products, services, and activities.As a core service of the IBM Watson platform, the Personality Insights service can help businesses understand their customers at a deeper level. It can help businesses learn their clients’ preferences, improve customer satisfaction, and strengthen client relations. Businesses can use these insights to improve client acquisition, retention, and engagement, and to guide highly personalized engagements and interactions to better tailor their products, services, campaigns, and communications for individual clients.

3. Create a custom field on Contact

Create a new text field on the contact twitter_handler__c text of 255 on contact object. we will use this to store the contact twitter handler.  We are going to see the personality insight sunburst Chart which contains all the insights of the contacts

4. Making API calls to twitter / Connected App in twitter.

Go to https://apps.twitter.com/ and create an app from the twitter. After this, you are going to get the OAuth details which we will make an API call to the twitter timeline. Here is the below code which we will use to make an API call to twitter

 String oauthVersion = '1.0';
        String oauthConsumerKey = 'dEa7ZayYR6gnvdMMMDHhSXwX';        
        String oauthConsumerSecret = '0lQeueBZgm1cGIQIwEgaOveEN3JYEsNDRr9gWeVo1Cmovme9Z';
        String baseUrl = 'https://api.twitter.com';
        String oauthSignatureMethod = 'HMAC-SHA1';
        String strTwitterId = twitterHandler;
        String pictureURL = '';
        String twitterAcct = twitterHandler;
        String keyencoded = EncodingUtil.urlEncode(oauthConsumerKey, 'UTF-8');
        String secretkeyencoded = EncodingUtil.urlEncode(oauthConsumerSecret, 'UTF-8');
        //Create Final Key String
        String sFinal = keyencoded + ':' + secretkeyencoded;
        //Convert to Blob
        Blob headerValue = Blob.valueOf(sFinal);
        //Build Request
        HttpRequest req = new HttpRequest();
        req.setEndpoint('https://api.twitter.com/oauth2/token');
        req.setMethod('POST');
        //Add Auth Header
        String authorizationHeader = 'Basic ' + EncodingUtil.base64Encode(headerValue);
        req.setHeader('Authorization', authorizationHeader);
        req.setBody('grant_type=client_credentials');
        Http http = new Http();
        HTTPResponse res = http.send(req);
        String responseBody = res.getBody();
        String stoken;
        JSONParser parser = JSON.createParser(res.getBody());
        while (parser.nextToken() != null) 
        {
            if (parser.getCurrentToken() == JSONToken.FIELD_NAME && parser.getText() == 'access_token')
            {
                parser.nextToken();
                stoken = parser.getText();
            }
        }
        HttpRequest req2 = new HttpRequest();
        String endpoint90 = 'https://api.twitter.com/1.1/statuses/user_timeline.json?screen_name='+ twitterAcct + '&count=240' ;
        req2.setEndpoint(endpoint90);
        req2.setMethod('GET');
        String authorizationHeader2 = 'Bearer ' + stoken;
        req2.setHeader('Authorization', authorizationHeader2);
        Http http2 = new Http();
        HTTPResponse res2 = http2.send(req2);
        String sBody2 = res2.getBody();
        String responseBody2 = res2.getBody();
        JSONParser parser2 = JSON.createParser(res2.getBody());
        System.JSONToken token;
        List<TwitterResponse> twitterResponse = (List<TwitterResponse>)JSON.deserialize( res2.getBody() , List<TwitterResponse>.class);

5. Create a Services in IBM Watson console.

Go to IBM Watson console and create a new Personality  insight services and obtain the service credentials

Click on Create and Get the Service Credentials as shown below

6. Created Named Credential in Salesforce

Create a named credential in Salesforce with the IBM Watson personality insight API authentication which we will use for call out with Watson Personality services.

7. Finally, Visualforce Page and Controller to make API call

Here is the apex controller that calls IBM Watson personality services.

public class IBMWatsonPersonalTwitter {
    Private String userIds {get;set;}
    public Contact c{get;set;}
    public String jsonData{get;set;}
    public JSON2Apex apexCls{get;set;} 
    public IBMWatsonPersonalTwitter(ApexPages.StandardController con){
        userIds = con.getId() ; 
        c =[Select Id , Name,Twitter_Name__c from Contact where id=:userIds] ;
        callWatsonToneAnalyser(c);
        apexCls = parse(jsonData);
    }
    public static String createAuthHeader(String username, String password){
        Blob headerValue = Blob.valueOf(username + ':' + password);
        String authorizationHeader = 'Basic ' + EncodingUtil.base64Encode(headerValue);
        return authorizationHeader;
    }
    public  void callWatsonToneAnalyser(Contact c) {
        HttpRequest req = new HttpRequest();
        req.setEndpoint('callout:IBM_Watson_Personality_Insight/v3/profile?version=2016-10-20&consumption_preferences=true&raw_scores=true');
        req.setHeader('Content-Type', 'application/json');
        req.setBody(stringToJSON(c.Twitter_Name__c));
        req.setMethod('POST');
        Http http = new Http();
        HTTPResponse res = http.send(req);
        jsonData = res.getBody();
    }
    
    private String stringToJSON(String  userTweets) {
        List<TwitterResponse> responce = TwitterHandler.getTwitterDetails(userTweets);
        List<ContentItemsJSON.contentItem> contentItems =  new List<ContentItemsJSON.contentItem>();
        for(TwitterResponse tweet : responce){
            ContentItemsJSON.contentItem contentItem = new ContentItemsJSON.contentItem();
            contentItem.id = tweet.id_str;
            contentItem.userid = userTweets;
            contentItem.sourceid = 'twitter';
            contentItem.created = (Integer)Datetime.now().getTime();
            contentItem.updated = (Integer)Datetime.now().getTime();
            contentItem.contenttype = 'text/plain';
            contentItem.charset = 'UTF-8';
            contentItem.language = 'en-us';
            contentItem.content = tweet.text;
            contentItem.parentid = '';
            contentItem.reply = false;
            contentItem.forward = false;
            contentItems.add(contentItem);
        }
        
        
        
        JSONGenerator generator = JSON.createGenerator(true);
        generator.writeStartObject();
        generator.writeObjectField('contentItems', contentItems);
        generator.writeEndObject();
        String body = generator.getAsString();
        jsonData = body;
        System.debug('body'+body);
        
        
        return body;
        //  return TwitterHandler.getTwitterDetails(c.Twitter_Name__c);
    }
    //
    // Generated by JSON2Apex http://json2apex.herokuapp.com/
    //
    
    
    
    public class Consumption_preferences {
        public String consumption_preference_id;
        public String name;
        public Double score;
    }
    
    public class JSON2Apex {
        public Integer word_count;
        public String processed_language;
        public List<Personality> personality{get;set;}
        public List<Children> needs;
        public List<Children> values;
        public List<Behavior> behavior{get;set;}
        public List<Consumption_preferences_Z> consumption_preferences{get;set;}
        public List<Warnings> warnings;
    }
    
    public class Consumption_preferences_Z {
        public String consumption_preference_category_id;
        public String name;
        public List<Consumption_preferences> consumption_preferences;
    }
    
    public class Personality {
        public String trait_id;
        public String name{get;set;}
        public String category{get;set;}
        public Double percentile{get;set;}
        public Double raw_score{get;set;}
        public List<Children> children;
    }
    
    public class Children {
        public String trait_id;
        public String name;
        public String category;
        public Double percentile;
        public Double raw_score;
    }
    
    public class Behavior {
        public String trait_id {get;set;}
        public String name {get;set;}
        public String category {get;set;}
        public Double percentage {get;set;}
    }
    
    public class Warnings {
    }
    
    
    public static JSON2Apex parse(String json) {
        return (JSON2Apex) System.JSON.deserialize(json, JSON2Apex.class);
    }
    
    
}

This is the visualforce page

<apex:page standardController="Contact" extensions="IBMWatsonPersonalTwitter" sidebar="false" showHeader="false">
    <head>
        
        https://code.jquery.com/jquery-2.2.0.min.js
        https://cdnjs.cloudflare.com/ajax/libs/d3/3.5.17/d3.min.js
        https://unpkg.com/personality-sunburst-chart@2.0.4/dist/index.js
        https://d3js.org/d3-color.v1.min.js
        <link href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.5/css/bootstrap.min.css" rel="stylesheet" />
        <style>
            #profile pre {
            max-height: 400px;
            }
            #textSummary {
            font-size: 1.2em;
            }
        </style>
    </head>
    <body>
        
        <div class="container">
            <div class="row">
                <div class="col-sm-6 col-xs-12">
                    <div id="sunburstChart"></div>
                </div>
            </div>
        </div>
        
        <script>
        $(document).ready(function(){
            
            var chart = new PersonalitySunburstChart({
                'selector':'#sunburstChart',
                'version': 'v3'
            });
            
            // Render the sunburst chart for a personality profile (version as specified in creating the chart)
            // and optionally a profile photo.  The photo will be inserted into the center of the sunburst chart.
            chart.show({!jsonData});
        });
        </script>
        
    </body>
    
</apex:page>

You can find the complete code in this GitHub URL https://github.com/rajamohanvakati/Personality-Insights-