function readOnly(count){ }
Starting November 20, the site will be set to read-only. On December 4, 2023,
forum discussions will move to the Trailblazer Community.
+ Start a Discussion
Captain SFDCCaptain SFDC 

Sharepoint Integration with Salesforce

How to integrate sharepoint with salesforce??

I have completed code for sharepoint/salesforce integration code below,but I don't know how to implement this step by step i.e within one class or in different class.

I am new in salesforce development,please help me.

How Salesforce Performs Step 1
The main point for cloud based integration is to host a running service on Microsoft’s cloud app platform Azure, and leveraging it to interact with SharePoint. Since the service is hosted on a cloud platform, we usually access it via web-based URL. So our methods from Salesforce side to request authentication token look something like this:
public static String getToken() {
String token;
if(!Test.isRunningTest()) {
token = SharePointAPIUtility.SharePointAPIGet('http://testingalgoworks.azurewebsites.net/Api/Values/GetAuthToken','Test@test.com','TestingPassword');
}
system.debug('token>>> '+token);
if(token != null) {
return EncodingUtil.urlEncode(token.replaceAll('"',''), 'UTF-8');
}
return null;
}
public static String SharePointAPIGet(String endpointUrl,String username, String password) {
try {
HttpRequest httpRequestObject = new HttpRequest();
httpRequestObject.setEndPoint(endpointUrl);
httpRequestObject.setmethod('GET');

Blob headerValue = Blob.valueOf(username + ':' + password);
String authorizationHeader = 'BASIC ' + EncodingUtil.base64Encode(headerValue);
httpRequestObject.setHeader('Authorization', authorizationHeader);
httpRequestObject.setTimeout(120000);

system.debug('httpRequestObject>> '+httpRequestObject);

Http http = new Http();
HttpResponse httpResponse ;

if(!test.isRunningTest())
httpResponse = http.send(httpRequestObject);

if(httpResponse != null && httpResponse.getStatus() == 'OK' && httpResponse.getStatusCode() == 200) {
system.debug('httpResponse.getBody();>>>>'+httpResponse.getBody()+'httpResponse.getBody();>>>>');
return httpResponse.getBody();
}
else if(httpResponse != null) {
return 'SharePoint Server Error: Status '+ httpResponse.getStatus()+' Status Code '+ httpResponse.getStatusCode() +' Body '+httpResponse.getBody();
}
} catch(CalloutException ce) {
throw ce;
} catch(Exception ex) {
throw ex;
}
return null;
}
This code hits the Azure service using the URL and receives the authentication token which the Azure service sends.
We will come to the steps 2,3 and 5 right after the 5th:
How Salesforce Performs Step 5
Once Salesforce has authentication token, it uses that to request files and folders from the adapter. Once again it uses the Azure service URL to hit the service.
Here’s a method to request files and a method to request folders
public static List<String> getAllFolders(SharePoint365APIParser objSharePoint365APIParser){
try {
list<String> objFolders = new list<String>();
if(objSharePoint365APIParser.folders != null && objSharePoint365APIParser.folders.size()>0) //null check
for(SharePoint365APIParser.folders sp:objSharePoint365APIParser.folders) {
objFolders.add(sp.name);
}
return objFolders;
} catch(Exception ex) {
throw ex;
}
return null;
}
public static List<String> getFilesByFolder(String folderName, SharePoint365APIParser objSharePoint365APIParser) {
//if(!test.isRunningTest()) {
try{
if(objSharePoint365APIParser.folders != null && objSharePoint365APIParser.folders.size()>0)
for(SharePoint365APIParser.folders sp:objSharePoint365APIParser.folders) {
if(sp.name.equalsIgnoreCase(folderName)) {
if(sp.files.size() > 0) { 
return sp.files;
} else {
return new list<String>();
}
}
}
} catch(Exception ex) {
throw ex;
}
//}//end running test loop

return null;
}
How Azure Performs Step 2, 3, and 4
Once Salesforce has sent the request for authentication token, here’s how Azure platform service authenticates login.
[HttpPost]
public bool Login(string email, string password) {
//throw new Exception("This is error!!");
bool validateLogin = false;
List<string> MessageList = new List<string>();
//string decryptedPassword = Encryption.Decrypt(encryptedPassword);
if (email == ConfigurationManager.AppSettings["Email"] && password == ConfigurationManager.AppSettings["Password"]) {
string authInfo = email + ":" + password;
authInfo = Convert.ToBase64String(System.Text.Encoding.Default.GetBytes(authInfo));
//authInfo = Encryption.Encrypt(authInfo);
System.Web.HttpContext.Current.Response.AppendHeader( "Authorization", "Basic " + authInfo);
// Insert User Token
MessageList.Add("Login Successful");
validateLogin = true;
}
else {
MessageList.Add("Invalid Username Or Password");
}
return validateLogin;
}
How Azure service handles Step 6
Now that Salesforce has authentication token and is logged in on SharePoint, here’s how our Azure service parses the request for file and folder lists.
[AuthorizeWebAPI()]
[HttpGet]
public Folders GetResourceData() {
Folders fld = new Folders();
try {
using (ClientContext clientContext = new ClientContext("https://yourprojectname.SharePoint.com/Resources"))
{
SecureString passWord = new SecureString();
foreach (char c in "TestPassword".ToCharArray()) 
passWord.AppendChar(c);

clientContext.Credentials = new SharePointOnlineCredentials("Test@test.com", passWord);
Web rootweb = clientContext.Web;
var folders = rootweb.GetFolderByServerRelativeUrl("/Resources").Folders;
string pString = @"\Resources\";
clientContext.Load(folders);
clientContext.ExecuteQuery();
fld.folders = new List<Folders>();
fld.name = "Resources";
foreach (Microsoft.SharePoint.Client.Folder myFolder in folders)
{
fld.folders.Add(GetFoldersAndFiles(myFolder, clientContext, pString));
}
}
}
catch (Exception)

fld.name = "Some error happened."; }
return fld;
}
private Folders GetFoldersAndFiles(Microsoft.SharePoint.Client.Folder mainFolder, ClientContext clientContext, string pathString) {
Folders fldr = new Folders();
List<string> fls = new List<string>();
fldr.folders = new List<Folders>();
clientContext.Load(mainFolder, k => k.Files, k => k.Folders);
clientContext.ExecuteQuery();
foreach (var folder in mainFolder.Folders)
{
string folderPath = string.Format(@"{0}{1}\", pathString, folder.Name);
if (folder.Name != "Forms")
fldr.folders.Add(GetFoldersAndFiles(folder, clientContext, folderPath));
}
foreach (var file in mainFolder.Files)
{
fls.Add(file.Name);
}
fldr.files = fls;
if (mainFolder.Name != "Forms")
fldr.name = mainFolder.Name;
return fldr;
}
NagendraNagendra (Salesforce Developers) 
Hi Captain SFDC,

Please read the below documentation clearly which helps you in better understanding of SharePoint integration with salesforce.

This is the Cloudage
  • Everything everywhere is connected with each other via cloud hosted web services and people can access these services from anywhere in globe, anytime.
  • But is everything really connected as is expected? Not every cloud based service can be connected with every other service,
  • But fortunately most popular Apps can be integrated And so can Salesforce and Microsoft SharePoint
  • Salesforce with SharePoint How to integrate
  • Integrate Salesforce with SharePoint Microsoft has not released any API to facilitate direct Salesforce SharePoint interactions so we need to involve a third-party adapter or service.
  • Integrate Salesforce with SharePoint There are a number of ways you can integrate SharePoint with Salesforce. However most of these ways can be categorized into three approaches.
  • Integrate Salesforce with SharePoint The different ways are: 1. Integrating using a third party system installed adapter. 2. Integrating using a Custom Coded Adapter. 3. Integrating using a third party integration service.
  • Integrate Salesforce with SharePoint The first way involves building a third-party adapter that had to be physically installed on a computer system and therefore severely limits the cloud based capabilities.
  • The third way involves using a paid integration product usually in a SaaS format. It is easy to use but it is not as flexible as a custom adapter and may prove to be a security risk. Integrate Salesforce with SharePoint
  • Integrate Salesforce with SharePoint So the best cloud integration method left is to use a custom coded integration solution that is hosted on Microsoft Azure service to integrate your Salesforce and SharePoint.
  • The main point for cloud-based integration is to host a running service on Microsoft’s cloud app platform Azure, and leveraging it to interact with SharePoint. How Salesforce Performs Step 1
  • Since the service is hosted on a cloud platform, we usually access it via web- based URL. Like How Salesforce Performs Step 1 http://testingalgoworks.azurewebs ites.net/Api/Values/GetAuthToken
  • How Salesforce Performs Step 1 So our methods from Salesforce side to request authentication token look something like this:
  • How Salesforce Performs Step 2,3,4 Once Salesforce has sent the request for authentication token, here’s how Azure platform service authenticates login.
  • How Salesforce Performs Step 5 Once Salesforce has authentication token, it uses that to request files and folders from the adapter. Once again it uses the Azure service URL to hit the service. Here’s a method to request files and a method to request folders
  • How Azure Services Handle Requests The code for how Azure service handle requests is a little long. So i request you to checkout our blog on the same. Our Blog: How to integrate SharePoint with Salesforce? There you will also find the code to actually display Sharepoint files in Visual force page.

Share Point Salesforce integration using Microsoft Azure:
There are a number of ways by which you can carry out this integration like using third party integration service, or a third party system installer adapter, Microsoft Azure hosted service, etc.

The Steps Are as Follows:

Step 1: Authentication request is sent to the adapter by Salesforce.
Step 2: The adapter forwards the request to SharePoint.
Step 3: After authenticating the information, SharePoint passes the security token for further use.
Step 4: The adapter receives the token and thereafter sends it to Salesforce.
Step 5: The token is used as an authentication key, Salesforce then send a request to view the accessible files and folders.
Step 6: The Adapter then forwards the request along with the token and subsequently receives an output. It then again passes on to the Salesforce installation.
Step 7: Either of the two things happen: First being either the token expires and the process is repeated again or secondly using the same token, more requests are sent and received.

Salesforce Handling Step 1:
To enable this Sharepoint Salesforce integration, the main point is to host a running service on Microsoft Azure and allow it to interact with SharePoint. It is hosted on the cloud and hence accessed via URL. So the Salesforce methods requesting authentication token are as follows. This codes reaches out to the Azure service using URL and receives the authentication token.
public static String getToken(){
        String token;
      if(!Test.isRunningTest()){
        token = SharePointAPIUtility.SharePointAPIGet
          ('http://testingalgoworks.azurewebsites.net/Api/Values/GetAuthToken',
           'Test@test.com','TestingPassword');
        }
      system.debug('token>>> '+token);
           if(token != null){
        return EncodingUtil.urlEncode(token.replaceAll('"',''), 'UTF-8');
        }
        return null;
        }
        public static String SharePointAPIGet(String endpointUrl,String username, String password){
        try{
          HttpRequest httpRequestObject = new HttpRequest();
          httpRequestObject.setEndPoint(endpointUrl);
          httpRequestObject.setmethod('GET');
        Blob headerValue = Blob.valueOf(username + ':' + password);
        String authorizationHeader = 'BASIC ' + EncodingUtil.base64Encode(headerValue);
          httpRequestObject.setHeader('Authorization', authorizationHeader);
          httpRequestObject.setTimeout(120000);
          system.debug('httpRequestObject>> '+httpRequestObject);
        Http http = new Http();
          HttpResponse httpResponse ;
          if(!test.isRunningTest())
              httpResponse = http.send(httpRequestObject);
          if(httpResponse != null && httpResponse.getStatus() == 'OK' 
             && httpResponse.getStatusCode() == 200){
              system.debug('httpResponse.getBody();
                           >>>>'+httpResponse.getBody()+'httpResponse.getBody();>>>>');
        return httpResponse.getBody();
        }else if(httpResponse != null){
        return 'SharePoint Server Error: Status '+ httpResponse.getStatus()+'
          Status Code '+ httpResponse.getStatusCode() +' Body 
          '+httpResponse.getBody();
        }
      }catch(CalloutException ce){
        throw ce;
      }catch(Exception ex){
        throw ex;
        }
        return null;
        }
Azure Taking Care of Step 2, 3 and 4:
After receiving the authentication token, Azure authenticates the login.
public bool Login(string email, string password)
     {
      //throw new Exception("This is error!!");
      bool validateLogin = false;
      List<string> MessageList = new List<string>();
      //string decryptedPassword = Encryption.Decrypt(encryptedPassword);
      if (email == ConfigurationManager.AppSettings["Email"] 
          && password == ConfigurationManager.AppSettings["Password"])
      {
     string authInfo = email + ":" + password;
     authInfo = Convert.ToBase64String(System.Text.Encoding.Default.GetBytes(authInfo));
     //authInfo = Encryption.Encrypt(authInfo);
     System.Web.HttpContext.Current.Response.AppendHeader("Authorization", "Basic " + authInfo);
     // Insert User Token
     MessageList.Add("Login Successful");
     validateLogin = true;
      }
      else
      {
     MessageList.Add("Invalid Username Or Password");
      }
      return validateLogin;
     }
Salesforce Performing Step 5:
Once Salesforce has authentication token, it uses that same token to request files and folders from the adapter. After completion of sending a request, it again uses the Azure service URL to hit the service.
public static List<String> getAllFolders(SharePoint365APIParser objSharePoint365APIParser){
        try{
          list<String> objFolders = new list<String>();
        if(objSharePoint365APIParser.folders != 
           null && objSharePoint365APIParser.folders.size()>0)//null check
        for(SharePoint365APIParser.folders sp:objSharePoint365APIParser.folders){
                  objFolders.add(sp.name);
        }
        return objFolders;
      }catch(Exception ex){
        throw ex;
        }
        return null;
        public static List<String> 
          getFilesByFolder(String folderName, SharePoint365APIParser objSharePoint365APIParser){
      //if(!test.isRunningTest()){
        try{
        if(objSharePoint365APIParser.folders != null && objSharePoint365APIParser.folders.size()>0)
        for(SharePoint365APIParser.folders sp:objSharePoint365APIParser.folders){
                  if(sp.name.equalsIgnoreCase(folderName)){
                      if(sp.files.size() > 0){             
                          return sp.files;
                      }else{
                          return new list<String>();
                      }
                    }
        }
          }catch(Exception ex){
        throw ex;
        }
        //}//end running test loop
        return null;
        }

Azure Handling Step 6:
After Salesforce has received the authentication token and is logged in on SharePoint, the Azure service parses the file in the following way:
[AuthorizeWebAPI()]
     [HttpGet]
     public Folders GetResourceData()
     {
      Folders fld = new Folders();
      try
      {
          using (ClientContext clientContext = 
                 new ClientContext("https://yourprojectname.SharePoint.com/Resources"))
            {
             SecureString passWord = new SecureString();
             foreach (char c in "TestPassword".ToCharArray()) passWord.AppendChar(c);
             clientContext.Credentials = new SharePointOnlineCredentials("Test@test.com", passWord);
             Web rootweb = clientContext.Web;
             var folders =
   rootweb.GetFolderByServerRelativeUrl("/Resources").Folders;
             string pString = @"\Resources\";
                 clientContext.Load(folders);
             clientContext.ExecuteQuery();
             fld.folders = new List<Folders>();
             fld.name = "Resources";
             foreach (Microsoft.SharePoint.Client.Folder myFolder in folders)
             {
                  fld.folders.Add(GetFoldersAndFiles(myFolder, clientContext, pString));
             }
     }
   }
      catch (Exception)
      { fld.name = "Some error happened."; }
      return fld;
     }
     private Folders GetFoldersAndFiles(Microsoft.SharePoint.Client.Folder mainFolder,
                                        ClientContext clientContext, string pathString)
     {
      Folders fldr = new Folders();
      List<string> fls = new List<string>();
      fldr.folders = new List<Folders>();
          clientContext.Load(mainFolder, k => k.Files, k => k.Folders);
     clientContext.ExecuteQuery();
      foreach (var folder in mainFolder.Folders)
      {
     string folderPath = string.Format(@"{0}{1}\", pathString, folder.Name);
     if (folder.Name != "Forms")
             fldr.folders.Add(GetFoldersAndFiles(folder, clientContext, folderPath));
      }
      foreach (var file in mainFolder.Files)
      {
     fls.Add(file.Name);
      }
      fldr.files = fls;
      if (mainFolder.Name != "Forms")
     fldr.name = mainFolder.Name;
      return fldr;
     }

Good luck with the integration steps of the two powerful systems SharePoint and Salesforce. You may get in touch with me if you encounter any issues.

Please make sure you mark this as solved if it helps.

Best Regards,
Nagendra.P







 
Himanshu Kaushal 5Himanshu Kaushal 5

Hello, Nagendra, We are facing the issue in integrating Salesforce with Sharepoint online, I have listed out the details of the issue and was wondering if anyone has worked on this integration before?


Details: Requirement: We have a requirement to upload document attachments along with metadata from Salesforce to SharePoint Online. Documents can be of any type. For e.g. PDF, Doc, CSV, Png, PPT etc. - Once the document has been uploaded to Salesforce, there is a rest API integration which pushes the details from Salesforce to Sharepoint(Attachments+Metadata(Example: Date, Name, ID etc)
 
Problem Statement: Salesforce can store documents either inside Attachment object or in the File object. We are able to read the attached document and its metadata from both the object. But Salesforce encodes the document into the binary file while storing it into Salesforce. While uploading the document(via REST integration) into SharePoint, we are not able to decode the binary file into the actual file stored and hence the uploaded document is not opening in SharePoint site with following error “Failed to load the document. Try to reload.” (We do not want to use the FILE connect option (Standard Salesforce connector) since it has its limitation and does not meet the business requirement)

Laxman Vattam 26Laxman Vattam 26
@Himanshu - Were you able to figure out the issue? I'm stuck with exact same problem. Many solutions suggest to use EncodingUtil.base64Decode(inputString) but it fails with error message (Not a valid UTF 8 character or  Illegal hexadecimal character � at index ) Any inouts will be really helpful. TIA
kapil chauhan 6kapil chauhan 6
Can Someone expalint what is 'SharePointAPIUtility'?? and where we have created it ??
sfdc org 1sfdc org 1
Hi Kapil,

SharePointAPIUtility is a class where you have to create a method with name of 'SharePointAPIGet' and pass your all required parameter in the same method.
Thanks.
Reuben James San DiegoReuben James San Diego
I have a few questions:
- Does the SharePointAPIUtility class mean that this has to been created as a separate API class? Kind of confusing that it is in the same space as getToken so it's not clear
- What object is SharePoint365APIParser? What does it do, and how is it used in this code?
Gauri Kasat 20Gauri Kasat 20
Hello while creating a folder in SharePoint from Postman I am encountering the following error :
{
    "error": {
        "code": "-2147024891, System.UnauthorizedAccessException",
        "message": {
            "lang": "en-US",
            "value": "Access denied. You do not have permission to perform this action or access this resource."
        }
    }
}
Ashutosh Mishra 133Ashutosh Mishra 133
Hi Nagendra.P,

We have similar requirement to access sharepoint folders within SF (file) for service agents and customer community Users. We want the capability to upload and download doc from folder contents and send a link/share doc in live-chat from service agents to Customer community user Can you specify if file upload and download can be done with custom code implementation as mentioned above and what extra steps needs to be done.

A quick respone is highly appreciated .