Categories
Salesforce

Integrating eCommerce & Other Platforms with Salesforce — Part 2

This is the second part of the Salesforce integration series post which covers integration of LiveChat and Help Scout with Salesforce.

Integration with LiveChat:

LiveChat is an online customer service software with live support, help desk software and web analytics capabilities. It was first launched in 2002 and since then it is developed and offered in SaaS (software as a service) business model by LiveChat Software.

Documentation: https://developers.livechatinc.com/rest-api/

Request to get all chats:

Livechat give the response in pages so intially we need to make request with page=1 and get a total number of pages. Do the requests till you reach the last page.

[php]integer intPageCountFromBatch = 1;

Http objHttp = new Http();
HttpRequest request = new HttpRequest();
request.setMethod('GET');
Blob headerValue = Blob.valueOf('Livechatusername/email:apikey');
String authorizationHeader = 'Basic ' +    EncodingUtil.base64Encode(headerValue);
request.setHeader('Authorization', authorizationHeader);
request.setHeader('Content-Type', 'application/json');
request.setHeader('X-API-Version','2');
request.setEndpoint('https://api.livechatinc.com/chats?page='+intPageCountFromBatch);
request.setTimeout(120000);
HttpResponse res = objHttp.send(request);  

if (res.getStatus() == 'OK') {
    Map<String, Object> mapResponse = (Map<String, Object>)JSON.deserializeUntyped(res.getBody());

    if (mapResponse.containsKey('pages'))
        intTotalPageCount = String.valueOf(mapResponse.get('pages')) != null ? Integer.valueOf(String.valueOf(mapResponse.get('pages'))) : 1 ;

    List<Object> lstChatData =(List<Object>)mapResponse.get('chats');
}[/php]

IMP: You need to make callout till you reach the last page number.

Integration with Help Scout

Help Scout is a simple help desk designed for small businesses.

Documentation: http://developer.helpscout.net/help-desk-api/

[php]integer intPageCountFromBatch = 1;

Http objHttp = new Http();
HttpRequest request = new HttpRequest();
request.setMethod('GET');
Blob headerValue = Blob.valueOf('APIKey:Password');
String authorizationHeader = 'Basic ' + EncodingUtil.base64Encode(headerValue);
request.setHeader('Authorization', authorizationHeader);
request.setHeader('Content-Type', 'application/json');
request.setEndpoint('https://api.helpscout.net/v1/mailboxes/YourMailboxId/conversations.json?page='+intPageCountFromBatch); 

HttpResponse res = objHttp.send(request);
request.setTimeout(120000); 

if (res.getStatus() == 'OK') {
    Map<String, Object> mapResponse = (Map<String, Object>)JSON.deserializeUntyped(res.getBody());

    if (mapResponse.containsKey('pages'))
        intTotalPageCount = String.valueOf(mapResponse.get('pages')) != null ? Integer.valueOf(String.valueOf(mapResponse.get('pages'))) : 1 ;

    List<Object> lstChatData = (List<Object>)mapResponse.get('items');
}[/php]

IMP: You need to make callout till you reach the last page number.

For both LiveChat & Help Scout, you need to implement the batch chain logic.

Categories
Salesforce

Integrating eCommerce & Other Platforms with Salesforce — Part 1

Recently I did custom Salesforce integration for with Shopify, Bill.Com, LiveChat, Helpscout, etc. The authentication request/response formats are crucial in such integration(s) as they establish the bridge between Salesforce and other platforms. Since I had a chance of working over it, I’m sharing it in this series of posts.

This part of the Salesforce integration series post covers Salesforce integration with Shopify and Bill.Com.

Integration with Shopify.com (using private app in Shopify)

Shopify is a complete eCommerce solution that allows you to set up an online store to sell your goods. It lets you organize your products, customize your storefront, accept credit card payments, track and respond to orders — all with a few clicks of the mouse.

Firstly you need to create a private app in Shopify.com which will generate the API key, password, and shared secret. We’ll need to use those keys for authentication purposes and while sending REST requests from Salesforce.

Here is the link to Shopify API Documentation: https://docs.shopify.com/api

Example:

Create customer in Shopify.com from Salesforce

API: https://help.shopify.com/api/reference/customer#create

POST Request from Salesforce:

JSONGenerator gen = JSON.createGenerator(true);
gen.writeStartObject();
    gen.writeFieldName('customer');
    gen.writeStartObject();
        gen.writeStringField('email', Contact.Email);        
        gen.writeStringField('first_name', Contact.FirstName);
        gen.writeStringField('last_name', Contact.LastName);             
    gen.writeEndObject();
gen.writeEndObject();

string strRequest = gen.getAsString();

Http objHttp = new Http();

HttpRequest request = new HttpRequest();
request.setMethod('POST');
Blob headerValue = Blob.valueOf('your apikey: your password');
String authorizationHeader = 'Basic ' + EncodingUtil.base64Encode(headerValue);
request.setHeader('Authorization', authorizationHeader);
request.setHeader('Content-Type', 'application/json');
request.setBody(strRequest);
request.setEndpoint('https://apikey:password@nameofyourshop.myshopify.com/admin/customers.json');

HttpResponse res = objHttp.send(request);

Map<String, Object> mapResponse = (Map<String,Object>)JSON.deserializeUntyped(res.getBody());

Map<String, Object> mapCustomerData = (Map<String, Object>)mapResponse.get('customer');

if(mapCustomerData .containskey('id'))
    system.debug('>>>Shopify='+string.valueof(mapCustomerData.get('id'));)

Integration with Bill.Com

Bill.com is a US-based cash flow management software system, provided as a software as a service that integrates with accounting and banking systems. It is intended to serve as a command and control dashboard for cash flow, by businesses, accounting firms, and banks.

Documentation: http://developer.bill.com/api-documentation/api/bill

Every API request needs a valid session ID, which is obtained by issuing a Login request. Login API takes in an organization ID, developer (or application) key, and user credentials (or Token), and returns a valid session ID, as well as an end-point URL, which should be used for any subsequent API requests. This session ID will remain valid for up to 35 minutes without activity. If the session becomes inactive, you will have to issue a new Login request and obtain a new session ID. You can explicitly end the session by issuing a Logout request.

You need username, password, OrganizationId, Devkey which can obtained from Bill.Com account / support.

Login Request:

String strLoginRequest = 'userName='+'Bill_com_Username'+'&password='+'Bill_com_Password'+'&orgId='+'Bill_com_OrgId'+'&devKey='+'Bill_com_Devkey'+';

HttpRequest objHttpReq = new HttpRequest();
objHttpReq.setHeader('Content-Type','application/x-www-form-urlencoded');
objHttpReq.setEndpoint('EndPOINTURL'+'/Login.json');
objHttpReq.setMethod('POST');
objHttpReq.setbody(strLoginRequest);

Http http = new Http();
HTTPResponse objHttpResp = http.send(objHttpReq);

if (objHttpResp.getStatusCode()==200) {
    Map<String,object> mapLoginResp = (Map<String,object>)JSON.deserializeUntyped(objHttpResp.getBody());
   
    if(mapLoginResp.containsKey('response_status') &&   Integer.valueOf(mapLoginResp.get('response_status'))==0) {
        if (mapLoginResp.containsKey('response_data') && mapLoginResp.get('response_data') instanceof map<string,object>) {   
            Map<String,Object> mapLoginRespData =  (Map<String,Object>)mapLoginResp.get('response_data');
   
            if(mapLoginRespData.containskey('apiEndPoint') ) {
                system.debug('>apiEndPoint='+string.valueof(mapLoginRespData.get('apiEndPoint')));
                system.debug('>sessionId='+string.valueof(mapLoginRespData.get('sessionId')));
                system.debug('>orgId='+string.valueof(mapLoginRespData.get('orgId')));
                system.debug('>usersId='+string.valueof(mapLoginRespData.get('usersId')));
            }
        }  
    }
}

The session ID, API endpoint is needed to use for making next requests:

Example:

Create Bill request:

HttpRequest objHttpReq = new HttpRequest();
objHttpReq.setEndpoint('ENDPOINTURL');
objHttpReq.setMethod('POST');
objHttpReq.setbody('devKey='+'DEVKEY'+'&sessionId='+'SESSION ID RECEIVED from LOGIN'+'&orgId='+'Bill_com_OrgId'+'&data='+'RequestBODY');
objHttpReq.setHeader('Content-Type','application/x-www-form-urlencoded');
Http http = new Http();
HTTPResponse objHttpResp = http.send(objHttpReq);
Categories
Salesforce

Overcoming Limited Feed Tracking in Salesforce

Recently I got a requirement where a client wanted feed tracking for every change that users are doing. Salesforce limits Feed Tracking to 20 fields per object.

I have used FieldSet and After Update trigger on object (for which we want to do feed tracking) to overcome the 20 field limit.

What is feed tracking?

The below Salesforce documentation link will explain in detail:
https://help.salesforce.com/apex/HTViewHelpDoc?id=collab_feed_tracking_overview.htm&language=en

Example: Account Feed tracking

IMP: Enable Feed Tracking by:
setup -> Chatter -> FeedTracking -> Select Account -> Click on Enable Feed Tracking

  1. Create field set on Account called AccountChatter. Add the fields you want to track in feed tracking.
  2. Create the following after update trigger on Account:

Add fields in FieldSet:

trigger AccountChatter on Account (after update) {
    List<Schema.FieldSetMember> lstTrackedFields = SObjectType.Account.FieldSets.AccountChatter.getFields();

    if (lstTrackedFields.isEmpty()) return;
    
    List<FeedItem> lstFieldChanges = new List<FeedItem>();
    
    if(!trigger.isUpdate) return;
    
    for (Account objNewAccount : trigger.new) {

        final Account oldAccount = trigger.oldmap.get(objNewAccount.Id); 
        // Iterate over all fields in Fieldset 
        for (Schema.FieldSetMember objField : lstTrackedFields) {
            String fieldName  = objField.getFieldPath();
            String fieldLabel = objField.getLabel();

            if (objNewAccount.get(fieldName) == oldAccount.get(fieldName))
                continue;

            String oldValue = String.valueOf(oldAccount.get(fieldName));
            String newValue = String.valueOf(objNewAccount.get(fieldName));

            if (oldValue != null && oldValue.length()>255) 
                oldValue = oldValue.substring(0,255);

            if (newValue != null && newValue.length()>255) 
                newValue = newValue.substring(0,255); 

            FeedItem post = new FeedItem();
            post.ParentId = objNewAccount.Id; // RecordId
            post.Body = UserInfo.getName()+' changed '+fieldLabel+' from '+oldValue +' to '+newValue ;

            lstFieldChanges.add(post);
        }
    }

    if (!lstFieldChanges.isEmpty()) insert lstFieldChanges;

}

Output:

Create Record in Account with Name: Ajay test chatter

Now update the record with Name: Ajay test verified

The above solution has been implemented by taking idea from below post:
(To overcome the limit of History Tracking)
http://salesforce.stackexchange.com/questions/39956/what-is-the-best-workaround-for-the-20-field-history-tracking-cap

Happy Coding!!! Cheers!