Integration SharePoint with Salesforce

June 28, 2023


 

In today's fast-paced business environment, organizations are constantly seeking ways to streamline processes, enhance collaboration, and improve data management. One powerful combination that can achieve these goals is the integration of SharePoint, Microsoft's robust document management platform, with Salesforce, a leading CRM solution. In this blog post, we will explore the benefits and steps involved in integrating SharePoint with Salesforce, enabling businesses to leverage the strengths of both platforms and create a unified, efficient solution.

 

After completing this unit, you will able to:

1.  What is SharePoint?

2.  Why Integrate SharePoint with Salesforce?

3.  Step-by-Step Integration Guide.

 

1.  What is SharePoint?

SharePoint is a web-based collaboration and document management platform developed by Microsoft. It provides organizations with a centralized location for storing, organizing, sharing, and collaborating on files, documents, and other types of content. SharePoint is highly customizable and can be extended with additional functionality through the use of web parts, custom workflows, and third-party add-ons. It is widely used by organizations of all sizes and industries to improve collaboration, information management, and productivity.

 

2.  Why Integrate SharePoint with Salesforce?

The integration of SharePoint with Salesforce enables organizations to combine the document management features of SharePoint with the customer relationship management (CRM) capabilities of Salesforce, creating a unified solution. This involves connecting and leveraging the capabilities of both platforms to streamline business processes, enhance collaboration, and improve data management.

Here are some key aspects of integrating SharePoint with Salesforce:

  1. Streamlined Document Management: By integrating SharePoint with Salesforce, organizations can centralize document management, providing a secure and organized repository for files accessible within the context of Salesforce records.
  2. Enhanced Collaboration: SharePoint's collaboration features, including co-authoring, version control, and document workflows, can be leveraged directly within Salesforce, promoting teamwork and ensuring everyone has access to the most up-to-date documents.
  3. Data Consistency and Syncing: Synchronization between SharePoint and Salesforce ensures that changes made in one platform are automatically reflected in the other, eliminating the need for manual updates and maintaining data consistency across systems.
  4. Customization and Extensibility: Integration allows the embedding of SharePoint web parts within Salesforce, empowering businesses to customize the user experience and combine the best features of both platforms to meet specific requirements.

 

3.  Step-by-Step Integration Guide

First of all, we need an apex class to integrate SharePoint with Salesforce. So let's create new apex class named SharePointServiceAPI and copy and paste with the below code sniept:

public class SharePointServiceAPI {
   
    public static Boolean siteAlreadyCreated = false;
    public static String getAccessToken() {  
        String appReg_clientId = '***************';
        String appReg_clientSecret = '***************';
        String targetHost = 'demoaccount.sharepoint.com';
        String principal = '***************';
        String realm = '***************';
        String bearer = '';
        String add_site_title = '';
        String add_site_url = '';
        String webtemplate = '{***************}#NIFTIT.Site.Template';
        String accessToken;        
        Http http = new Http();
        HttpRequest request = new HttpRequest();
        request.setEndpoint('https://accounts.accesscontrol.windows.net/'+ realm +'/tokens/OAuth/2');
        request.setMethod('POST');
        String body = 'grant_type=client_credentials&client_id='+ EncodingUtil.urlEncode(appReg_clientId+'@'+realm, 'UTF-8') +
            '&client_secret='+ EncodingUtil.urlEncode(appReg_clientSecret, 'UTF-8') +
            '&resource='+principal+'/'+targetHost+'@'+realm;
       
        request.setBody(body);
        System.Debug('token Body ' + body);
        HttpResponse response = http.send(request);
       
        if(response.getStatusCode() == 200) {
            Map<String, Object> mapOfAccessToken = (Map<String, Object>) JSON.deserializeUntyped(response.getBody());
            accessToken = String.valueOf(mapOfAccessToken.get('access_token'));
         
        } else {
            SharePointAPIException spi = new SharePointAPIException(
                response.getBody(), String.ValueOf(response.getStatusCode()), response.getStatus(), 'AccountService 38 line'
            );
            throw spi;
        }
        return accessToken;
    }
   
    public static String createSiteAPI(String accessToken, String titleName, String url1)
    {
        String targetHost = 'demoaccount.sharepoint.com';
        String bearer = accessToken;
        String type = 'SP.WebCreationInformation';
        String description = 'Auto-created site';
        Integer language = 1033;
        String title = titleName;
        String url = url1;
        Boolean useSamePermissionsAsParentSite = true;
        String webTemp = null;
        List<TemplateId__c> customSettingList = TemplateId__c.getall().values();
        for(TemplateId__c rec : customSettingList) {
            webTemp = rec.Template_Id__c;
        }
       
        Http http = new Http();
        HttpRequest request = new HttpRequest();
        request.setEndpoint('https://'+ targetHost +'/sites/eng/_api/web/webs/add');
        request.setMethod('POST');
        request.setHeader('Accept', 'application/json;odata=verbose');
        request.setHeader('Content-Type', 'application/json;odata=verbose;charset=utf-8');
        request.setHeader('Authorization', 'Bearer '+  bearer);
        request.setTimeout(120000);
       
        Map<string, Map<string, object>> parentMap = new Map<string, Map<string, object>>();
        Map<string, object> mapToSerialize = new Map<string, object>();
        mapToSerialize.put('__metadata', new Map<string, object>{'type' => type});
        mapToSerialize.put('Description', description);
        mapToSerialize.put('Language', language);
        mapToSerialize.put('Title', title);
        mapToSerialize.put('Url', url);
        mapToSerialize.put('UseSamePermissionsAsParentSite', useSamePermissionsAsParentSite);
        mapToSerialize.put('WebTemplate', webTemp);
        parentMap.put('parameters' , mapToSerialize);
        string jsonstring = JSON.serialize(parentMap);        
        request.setBody(jsonstring);
        System.debug(' jsonstring ' + jsonstring);
        HttpResponse response;
        String urlVal;
        try
        {
            response = http.send(request);
            // Parse the JSON response
            if(response.getStatusCode() == 200) {
                System.debug(response.getBody());
                Map<String, Object> mapResult = (Map<String, Object>) JSON.deserializeUntyped(response.getBody());
                Map<String, Object> urlResult = (Map<String, Object>)mapResult.get('d');
                urlVal = String.ValueOf(urlResult.get('Url'));
                System.debug(' urlVal ' + urlVal);
            }
            else if(response.getStatusCode() == 500)
            {
                //When user tried to insert the same record Id again the it will throw error with STatus code 500 that
                //This The Web site address \"/sites/eng/0060b00000rltBqAAI\" is already in use.
                String responseBody = response.getBody();
                if(responseBody.contains('/sites/eng/'))
                {
                    Integer index1 = responseBody.indexOf('/sites/eng/');
                    urlVal =  'https:/demoaccount.sharepoint.com' + responseBody.SubString(index1, index1+29);
                    siteAlreadyCreated = true;
                }
                else
                {
                    SharePointAPIException spi = new SharePointAPIException(
                    response.getBody(), String.ValueOf(response.getStatusCode()), response.getStatus(), 'AccountService 110 line'
                    );
                    throw spi;
                }
            }
            else {
                SharePointAPIException spi = new SharePointAPIException(
                    response.getBody(), String.ValueOf(response.getStatusCode()), response.getStatus(), 'AccountService 116 line'
                );
                throw spi;
            }
        }
        catch(Exception ex)
        {
            String exceptionBody = '<b>Message:</b>' + ex.getMessage() + ' <b>Cause:</b>' + ex.getCause() + ' <b>Stacktrace:</b>' + ex.getStackTraceString() + '<br/>' ;
            System.Debug(' emailBody ' + exceptionBody);
            throw ex;
        }
       
        return urlVal;
    }
   
    public static HttpResponse createListItemAPI(String accessToken,  String accountName, String accountId,
                                                 String industry,String sharePointURL, String sfType)
    {
        String targetHost = 'demoaccount.sharepoint.com';
        String bearer = accessToken;
        String title = accountName;
        String url = sharePointURL;
        String description= accountName;
        String sourceSiteGrp=industry;
        String sfId=accountId;
        String areaOfExpertise = 'Metal';
       
        Map<String, String> mapFieldValueToPassingValue = new Map<String, String>();
        List<Share_Point_Industry_Mapping__c> customSettingList = Share_Point_Industry_Mapping__c.getall().values();
        for(Share_Point_Industry_Mapping__c rec : customSettingList) {
            mapFieldValueToPassingValue.put(rec.Actual_Value__c, rec.Passing_Value__c);
        }
        Http http = new Http();
        HttpRequest request = new HttpRequest();
        String endPoint =  'https://'+ targetHost +'/sites/eng/_api/web/lists/getbytitle(\'Company%20Sites\')/items';
        request.setEndpoint(endPoint);
       
        request.setMethod('POST');
        request.setHeader('Accept', 'application/json;odata=verbose');
        request.setHeader('Authorization', 'Bearer '+  bearer);
        request.setHeader('Content-Type', 'application/json');
        request.setTimeout(120000);
       
        Map<string, object> mapToSerialize = new Map<string, object>();
        mapToSerialize.put('Title', title);
        mapToSerialize.put('Source_x0020_Site_x0020_Group', 'Group Name as per your requirement');
        mapToSerialize.put('OData__x0055_RL2', new Map<string, object>{'Url' => url , 'Description' => description});
        mapToSerialize.put('SFID', sfId);
        mapToSerialize.put('SFType', sfType);
        mapToSerialize.put('AOE', areaOfExpertise);
        string body = JSON.serialize(mapToSerialize);
        request.setBody(body);
       
        HttpResponse response;
        try
        {
            response = http.send(request);
            if(response.getStatusCode() == 201)
            {
                System.Debug('if response ' + response.getBody());
                Map<String, Object> mapResult = (Map<String, Object>) JSON.deserializeUntyped(response.getBody());
                Map<String, Object> urlResult = (Map<String, Object>)mapResult.get('d');
                String title1 = String.ValueOf(urlResult.get('Title'));                
            }
            else
            {
                System.Debug(' else response ' + response.getBody());
                SharePointAPIException spi = new SharePointAPIException(
                    response.getBody(), String.ValueOf(response.getStatusCode()), response.getStatus(), 'AccountService 181 line'
                );
                throw spi;
            }
        }
        catch(Exception ex)
        {
            String emailBody = '<b>Message:</b>' + ex.getMessage() + ' <b>Cause:</b>' + ex.getCause() + ' <b>Stacktrace:</b>' + ex.getStackTraceString() + '<br/>' ;
            System.Debug(' emailBody ' + emailBody);
            throw ex;
        }        
        return response;
    }
   
    public static void getAndDeleteSiteWithItems(String SFID, String bearer)
    {
        String targetHost = 'demoaccount.sharepoint.com';
        Http http = new Http();
        HttpRequest request = new HttpRequest();
        String endPointURL = 'https://'+ targetHost +'/sites/eng/_api/web/lists/getbytitle(\'Company%20Sites\')/items?$filter=' + EncodingUtil.urlEncode('SFID eq \''+SFID +'\'','UTF-8');
        request.setEndpoint(endPointURL);
        request.setMethod('GET');
        request.setHeader('Accept', 'application/json;odata=nometadata');
        request.setHeader('Authorization', 'Bearer '+  bearer);
        request.setTimeout(120000);        
       
        HttpResponse response;
        try
        {
            response = http.send(request);
            if(response.getStatusCode() == 200)
            {
                Map<String, Object> mapResponse = (Map<String, Object>) JSON.deserializeUntyped(response.getBody());
                List<Object> myMapObjects = (List<Object>) mapResponse.get('value');
                Map<String, Object> idResult = (Map<String, Object>)myMapObjects[0];
               
                String idVal = String.ValueOf(idResult.get('ID'));
                Map<String, Object> urlResult = (Map<String, Object>)idResult.get('OData__x0055_RL2');
                String urlVal1 = String.ValueOf(urlResult.get('Url'));
                System.Debug(' invoked getAndDeleteSiteWithItems ' + idVal + ' idVal ' +  ' urlVal1 ' + urlVal1);
                deleteItem(bearer, idVal);
                deleteSite(bearer, urlVal1);
            }
            else
            {
                System.Debug(' else response ' + response.getBody());
            }
        }
        catch(Exception ex)
        {
            String emailBody = '<b>Message:</b>' + ex.getMessage() + ' <b>Cause:</b>' + ex.getCause() + ' <b>Stacktrace:</b>' + ex.getStackTraceString() + '<br/>' ;
            System.Debug(' emailBody ' + emailBody);
        }
    }
   
    public static void deleteItem(String bearer, String listid_to_delete){
        String targetHost = 'demoaccount.sharepoint.com';        
        Http http = new Http();
        HttpRequest request = new HttpRequest();
        String endPointURL = 'https://'+ targetHost +'/sites/eng/_api/web/lists/getbytitle(\'Company%20Sites\')/items('+listid_to_delete+')';
        request.setEndpoint(endPointURL);
        request.setMethod('POST');
        request.setHeader('Accept', 'application/json;odata=nometadata');
        request.setHeader('Authorization', 'Bearer '+  bearer);
        request.setHeader('X-HTTP-Method', 'DELETE');
        request.setHeader('IF-MATCH', '*');
        request.setTimeout(120000);        
        request.setBody('');
        HttpResponse response;
        try
        {
            response = http.send(request);
            if(response.getStatusCode() == 200)
            {
                System.Debug('if response ' + response.getBody());              
            }
            else
            {
                System.Debug(' else response ' + response.getBody());
            }
        }
        catch(Exception ex)
        {
            String errorBody = 'Message: ' + ex.getMessage() + ' Cause:' + ex.getCause() + ' Stacktrace:' + ex.getStackTraceString();
            System.Debug(' emailBody ' + errorBody);
        }        
    }
   
   
    public static void deleteSite(String bearer, String site_to_delete)
    {
        if(site_to_delete == null ||
           site_to_delete == '' ||
         site_to_delete == 'https://demoaccount.sharepoint.com/sites/eng' ||
         site_to_delete == 'https://demoaccount.sharepoint.com/sites/eng/' ||
         site_to_delete == 'https://demoaccount.sharepoint.com/sites' ||
         site_to_delete == 'https://demoaccount.sharepoint.com/sites/' ||
          site_to_delete == 'https://demoaccount.sharepoint.com' ||
           site_to_delete == 'https://demoaccount.sharepoint.com/' ||
         site_to_delete.length() < 60
         )
         {
             return;
         }
        Http http = new Http();
        HttpRequest request = new HttpRequest();
        String endPointURL = site_to_delete + '/_api/web';
        request.setEndpoint(endPointURL);
        request.setMethod('POST');
        request.setHeader('Accept', 'application/json;odata=verbose');//nometadata
        request.setHeader('Authorization', 'Bearer '+  bearer);
        request.setHeader('X-HTTP-Method', 'DELETE');//Delete
        request.setHeader('IF-MATCH', '*');
         request.setBody('');
        request.setTimeout(120000);
       
        HttpResponse response;
        try
        {
            response = http.send(request);
            if(response.getStatusCode() == 200)
            {
                System.Debug('if response ' + response.getBody());
            }
            else
            {
                System.Debug(' else response ' + response.getBody());
            }
        }
        catch(Exception ex)
        {
            String errorBody = 'Message: ' + ex.getMessage() + ' Cause:' + ex.getCause() + ' Stacktrace:' + ex.getStackTraceString();
            System.Debug(' emailBody ' + errorBody);
        }        
    }
   
    public static Boolean isSiteExists(String SFID, String bearer)
    {
        Boolean result = false;
        String targetHost = 'demoaccount.sharepoint.com';
        Http http = new Http();
        HttpRequest request = new HttpRequest();
        String endPointURL = 'https://'+ targetHost +'/sites/eng/_api/web/lists/getbytitle(\'Company%20Sites\')/items?$filter=' + EncodingUtil.urlEncode('SFID eq \''+SFID +'\'','UTF-8');
        request.setEndpoint(endPointURL);
        request.setMethod('GET');
        request.setHeader('Accept', 'application/json;odata=nometadata');
        request.setHeader('Authorization', 'Bearer '+  bearer);
        request.setTimeout(120000);        
       
        HttpResponse response;
        try
        {
            response = http.send(request);
            if(response.getStatusCode() == 200)
            {
                Map<String, Object> mapResponse = (Map<String, Object>) JSON.deserializeUntyped(response.getBody());
                List<Object> myMapObjects = (List<Object>) mapResponse.get('value');
                if(myMapObjects.size() > 0)
                {
                    result = true;
                }
            }
        }
        catch(Exception ex)
        {
            String emailBody = '<b>Message:</b>' + ex.getMessage() + ' <b>Cause:</b>' + ex.getCause() + ' <b>Stacktrace:</b>' + ex.getStackTraceString() + '<br/>' ;
            System.Debug(' emailBody ' + emailBody);
            throw ex;
        }
        return result;
    }
}

 

In this class we create the methods to do some tasks. Let's discuss one by one:

1. The getAccessToken method is used to get the access token from SharePoint in the Salesforce.
 
 
2. The createSiteAPI method is used to create a site on SharePoint using the Salesforce API, you can utilize the power of Salesforce's REST API and SharePoint's API endpoints. By leveraging these APIs, you can automate the process of site creation and seamlessly integrate it into your Salesforce workflows.
 
In this method, we first set up an HTTP POST request to the SharePoint site creation endpoint. We include the required authorization header with the Salesforce access token (accessToken) to authenticate the request.
 
Next, we define the necessary parameters for creating the site, such as the site title and URL. These parameters are then combined into a JSON payload and set as the request body.
 
Finally, the request is sent using the Http class, and the response is evaluated to determine whether the site creation was successful. This method returns the site url if the response status code is 200, it means the site was created successfully. Otherwise, you can handle any potential errors accordingly.
 
 
3. The createListItemAPI method is used to demonstrate how to create a list item on SharePoint using the Salesforce API. With this method, we start by setting up an HTTP POST request to the SharePoint endpoint for creating a list item. We need to specify the URL of our SharePoint site and the title of the list (YourListTitle) where you want to create the item.
 
We include the Salesforce access token (accessToken) in the authorization header to authenticate the request. Then, we set the content type to JSON in the request headers.
 
Next, we define the parameters for the list item, such as the accessToken, accountName, accountId, industry, sharePointURL, sfType. These parameters are combined into a JSON payload and set as the request body.
 
Finally, we send the request using the Http class and evaluate the response to determine if the list item creation was successful. If the response status code is 201, it means the item was created successfully. Otherwise, you can handle any potential errors accordingly.
 
 
4. The purpose of getAndDeleteSiteWithItems method is to demonstrate how to retrieve and delete items on SharePoint using the Salesforce API.
 
With this method, we first demonstrate how to retrieve items from a SharePoint list using a GET request with the SFID (replace SFID with your salesforce organization Id)and the bearer parameters.
 
Next, we illustrate how to delete a specific SharePoint list item using a DELETE request with the deleteItem method and with the deleteSite method.
 
 
5. The isSiteExists method describes how to check if a site exists on SharePoint using the Salesforce API.
 
In the code snippet above, we perform a GET request to the SharePoint site with SFID (replace SFID with your salesforce organization Id)and the bearer parameters.
 
After sending the request, we evaluate the response status code to determine the result. If the response status code is 200, it indicates that the site exists. If the status code is 404, it means that the site does not exist. You can handle these scenarios accordingly.
 
 
Now the integration is successfully completed.
 

I hope this blog helped you!