Skip to Content
Technical Articles
Author's profile photo ASUTOSH MAHARANA

SharePoint Integration using SAP CPI (Without SAP Open Connector)

**edited on Oct 2022 to add postman collection to test sharepoint APIs**

Introduction

Sometimes documents need to be copied to the SharePoint team site so that it can be made accessible to broader recipients within an organization.

Main

This integration requires configuration changes in SharePoint as well as SAP CPI.

SharePoint App Configuration

Register Add-In

On the initial stage, we have to register the Add-In in SharePoint, where we want to access the information. Follow the steps below to register the Add-In in SharePoint site.

  • Navigate and login to SharePoint online site.
  • Then navigate to the Register Add-In page by entering the url as
  • https://<siteURL>/_layouts/15/appregnew.aspx
  • On the App Information section, click the Generate button next to the Client Id and Client Secret textboxes to generate the respective values.
  • Enter Add-In Title in Title textbox
  • Enter AppDomian as a localhost
  • Enter RedirectUri as a https://localhost
  • Click Create button, which registers the add-in and returns the success message with created information.

Register%20SharePoint%20Add-ins

Register SharePoint Add-ins

 

Grant Permissions to Add-In

Once the Add-In is registered, we have to set the permissions for that add-in to access the SharePoint data. We will set the Read permission level to the web scope, so that we will be able to read the web information.

  • Navigate to the SharePoint site
  • Then enter the URL https://<siteURL>/_layouts/15/appinv.aspx in the browser. This will redirect to the Grant permission page.
  • Enter the Client ID(which we have generated earlier), in the AppId textbox and click the Lookup button. That will populate the value to other textboxes in Title, App Domain and Redirect Url.

Grant%20Permission%20to%20Add-In

Grant Permissions to Add-In

  • Now enter the below permission request in XML format.
<AppPermissionRequests AllowAppOnlyPolicy="true">
    <AppPermissionRequest Scope="http://sharepoint/content/sitecollection/web" Right="Write" />
</AppPermissionRequests>
  • Then click the Create button. This will redirect to your page, where we have to trust the add-in to read items from the website.

Note: If we want to access site collection or tenant level, we have add the xml accordingly.

 

Retrieve the Tenant ID

Once we register the Client Id and Secret with the permissions, we are ready to access the SharePoint information from external systems or tools.

First, we have to know the Tenant ID. Follow the below steps to obtain that information from the postman. Postman helps to get the tenant Id by requesting the below url with Authorization header.

  • Launch Postman.
  • Select Get Method
  • Enter the below URL in the “Request URL” textbox
  • https://<siteURL>/_vti_bin/client.svc/
  • Configure the below information in the header section to send along with the url requestMethod = Get

Get%20Call%20for%20Tenant%20ID

Get Call for Tenant ID

  • After applying the configuration, click the Send button. The response returns a lot of headers but ends with unauthorized access.

Response%20Headers

Response Headers

In response header, we will get WWW-Authenticate as one of the headers and that contains the necessary information required for the next step. The realm value contains the tenant id for the SharePoint Online site and clientid value contains the resource information (we’ll use it later in our SAP CPI iFlow).

 

SAP CPI iFlow Configuration

iFlow

iFlow

This iFlow is creating one webservice which can be triggered by any HTTP Client and upload files to SharePoint using REST api V1 of SharePoint.

Here we have used parallel multicast to get the OAuth access token from Microsoft Access Control Services.

 

OAuth Call Branch

OAuth Request

First of all we are using a content modifier step to create the request. 

  • Request Header: We have added one header with key and value pair as “Content-Type” and “application/x-www-form-urlencoded”.
  • Request Body: We have to add the below string to the message body section with appropriate replacement.
grant_type=client_credentials&client_id=ClientID@TenantID&client_secret=ClientSecret&resource=resource/SiteDomain@TenantID
  • ClientID: Created in the Add In section
  • ClientSecret: Created in the Add In section
  • TenantID: Fetch from “WWW-Authenticate” header in the last section
  • resource: Fetch from “WWW-Authenticate” header in the last section
  • SiteDomain: Domain name

 

Call to MACS and HTTP Receiver

Then we have a request reply step which will call the Microsoft Access Control Services and fetch the response. HTTP receiver channel should be updated with the below address and “POST” Method.

Address: https://accounts.accesscontrol.windows.net/<TenantID>/tokens/OAuth/2

 

JSON to XML Converter and Fetch Access Token

As we are getting one JSON response we need to convert it to XML format and then we have used another content modifier to fetch the access token and assign it to a property called “access_token”.

 

Access_Token

Access_Token

 

Remove Body

We have used one simple Groovy script to remove the body of the OAuth call branch.

import com.sap.gateway.ip.core.customdev.util.Message
import groovy.json.JsonOutput

Message processData(Message message) {
    def body = "";
    message.setBody(body) 
    return message;
}

 

Final Call to SharePoint

 

Join and Gather

We have used Join and Gather to merge both the branches. So that we can get an OAuth access token as well as the original message body from the request.

 

Set Header

We have used one content modifier to create 2 headers with a key value pair as below. We have also deleted the unused headers.

Key :: Value

Content-Type :: application/xml (You can change the value as per your requirement)

Authorization :: Bearer ${property.access_token}

 

Headers

Headers

 

We have also created one exchange property to transmit the filename.

Property

Property

 

Convert Body to outputStream

As per our understanding the request body should be passed to the HTTP adapter but as per our testing the content modifier or ${body} is not giving required results when the request body is passed directly (SharePoint REST API is giving 500 error with I/O error). So we have used one simple groovy script to convert the payload to ByteArray and again set it to the message body. (Not sure why it is behaving like this as we are still investigating this issue.)

import com.sap.gateway.ip.core.customdev.util.Message;
import java.util.HashMap;
def Message processData(Message message) {
    //Body 
       def body = message.getBody(byte[]);
       message.setBody(body);
       message.setHeader("Content-Type", "application/octet-stream")
       return message;
}

 

Call to SharePoint

We are making a POST call to SharePoint REST api using request reply and HTTP receiver channel.

HTTP%20Receiver

HTTP Receiver

 

Test 

We have called the HTTP endpoint of the iFlow from a Postman client.

Call%20from%20Postman

Call from Postman

 

Result

We can see the files being sent to the SharePoint.

Result

Result

 

Conclusion

With this you have successfully created and tested an integration flow that is uploading documents  to SharePoint, created a team site in SharePoint, leveraged the SAP CPI to connect seamlessly to SharePoint site. Basically we need to take care of the HTTP request payload while calling the rest api of SharePoint. Please go through the Microsoft documentation for API overview.

Sharepoint API Postman Collection.

 

 

Assigned Tags

      49 Comments
      You must be Logged on to comment or reply to a post.
      Author's profile photo Daniel Graversen
      Daniel Graversen

      Nice post.

      I would often save the payload in the Exchange properties and then restore it afterwards.

      Author's profile photo Yeswanth Posam
      Yeswanth Posam

      Hi Asutosh,

      Did u check uploading binary (ppt,pdf,word..) files.

      I am unable to post binary data to Sharepoint eventhough my headers and request payload is correct

      Input Attachment

      Input%20attachment

      Input attachment

      Groovy script code to read attachments and set header data(tried with ByteArrayOutputStream also)

      Map<String, DataHandler> attachments = message.getAttachments()

      List<String> aList = new ArrayList<String>();

      for (String x : attachments.keySet())

      {

      aList.add(x);

      }

      def attch=attachments.get(aList.get(0))

      message.setHeader("fName",attch.getName())

      def xcn=attch.getInputStream().getBytes()

      message.setBody(xcn)

      message.setHeader("Content-Length",xcn.size())

      def ctype=attch.getContentType().indexOf(';')

      message.setHeader("Content-Type",attch.getContentType().substring(0,ctype))

      return message

       

      Message Content from trace step

      Message Header

      Message%20Headers

      Message Headers

      Body(Binary data)

      Binary data which is downloaded and saved with the extension is of actual file

      Msg%20before%20Step

      Msg before Step

      Error in SAP CPI

      Error%20in%20CPI

      Error in CPI

      Exception from sharepoint 

      <?xml version="1.0" encoding="utf-8"?>
      <m:error xmlns:m="http://schemas.microsoft.com/ado/2007/08/dataservices/metadata">
      <m:code>-1, System.IO.IOException</m:code>
      <m:message xml:lang="en-US">I/O error occurred.</m:message>
      </m:error>

      Could you please help me with this.

      Author's profile photo ASUTOSH MAHARANA
      ASUTOSH MAHARANA
      Blog Post Author

      Dear Yeswanth,

       

      I have also tried to modify the script to assign binary payload to the request body but it's giving same I/O error. It seems like conversion to string only working fine as of now.

       

      I have observed that HTTP adapter is converting the type of request body to "inputStream" but it seems like there is some issue with the SAP CPI HTTP receiver adapter which is not able to pass byte streams correctly. I have tried using Postman it is working fine.

       

      I am trying to create a custom HTTP adapter from Apache components and try to use that adapter to connect to SharePoint.

       

      BR,

      Asutosh Maharana

      Author's profile photo Faisal Jamal
      Faisal Jamal

      Were you able to resolve this issue? I am also facing Error 500 I/O exception while trying to send the binary data to Sharepoint. The payload looks fine and I am able to open it up as a pdf when downloaded.

      Thanks!

      Author's profile photo Yeswanth Posam
      Yeswanth Posam

      Hi Asutosh,

      I also feel it is issue with HTTP Adapter based on below screenshots. I think issue is also with encoding, as per HTTP adapter default encoding is UTF-8.

      Input Attachment

      Input%20Attachment

      Message Before Step in Adapter

      Msg%20Before%20Step

       

      Downloaded and opened above binary data in Notepad++(length is as expected and encoding in ANSI) and saved it with .pptx as is working as expected.

      Before%20Step_Notepad

      Message before Receiver Adapter(here is the step where the file encoding is getting changed)
      Message%20before%20Receiver%20Adapter

      Downloaded and opened above binary data in Notepad++(length is not as expected and encoding in UTF-8 as per HTTP adapter standards)

      Encoding change as per below SAP Documentation

      https://help.sap.com/viewer/368c481cd6954bdfa5d0435479fd4eaf/Cloud/en-US/2da452effb764b3bb28f8e0a2f5bd480.html

      Encoding property as per above SAP blog (changed CamelCharsetName to overwrite standard UTF-8 encoding)

      File in Notepad++ after above encoding change (almost original input attachment data expect few characters unable to find the exact encoding for ANSI as ANSI is not an encoding type)

       

       

      Author's profile photo ASUTOSH MAHARANA
      ASUTOSH MAHARANA
      Blog Post Author

      Dear Yeswanth,

       

      I have a workaround for this issue not sure if it will help you or not.

      We can first convert the binary payload to base64 encoded string then transfer it to SharePoint and create one text file. Then we can use Power Automate flow to convert the base64 encoded text file to binary file again.

      Power Automate flow: It's a manually triggered flow but you can create an automated flow as well. Let me know if you are facing any issue with power automate.

      Base64%20to%20binary

      Base64 to binary

      Will this suffice your requirement ?

      I am also looking into the charset conversion issue of the HTTP receiver adapter.

       

      BR,

      Asutosh Maharana

      Author's profile photo Erkam Ozturk
      Erkam Ozturk

      Hi Yeswanth, Asutosh,

      Were you able to find a solution for the binary files? I'm also suffering from this problem.

       

      Regards,

      Erkam

      Author's profile photo Erkam Ozturk
      Erkam Ozturk

      Hi all,

      For the upload of binary files to a SharePoint site, I've just come up with such a solution; Instead of CPI's own HTTP receiver adapter, I'm uploading the files via HTTP call from the groovy.  That works fine. Here is my code:

      import com.sap.gateway.ip.core.customdev.util.Message;
      import java.util.HashMap;
      
      def Message processData(Message message) {
          String contentLength = message.getBodySize();
          def Content = message.getBody(byte[])
          
          
          def messageLog = messageLogFactory.getMessageLog(message);
          def propertiesMap = message.getProperties();
          def headersMap = message.getHeaders();
          
          def siteDomain = propertiesMap.get("siteDomain");
          def site = propertiesMap.get("site");
          def pathSpaceCorrected = propertiesMap.get("pathSpaceCorrected");
          def fileName = propertiesMap.get("fileName");
          
          String SharePointURL = 'https://' + siteDomain + '/sites/' + site + '/_api/web/GetFolderByServerRelativeUrl(\'' + '/sites/' + site  + pathSpaceCorrected + '\')/Files/add(url=\'' + fileName + '\',overwrite=true)';
          
          // POST
          def post = new URL(SharePointURL).openConnection();
          
          
          post.setRequestMethod("POST")
          post.setDoOutput(true)
          post.setRequestProperty("Content-Type", headersMap.get("Content-Type") as String);
          post.setRequestProperty("Content-Length", contentLength ); 
          post.setRequestProperty("Authorization", headersMap.get("Authorization") as String);
          post.getOutputStream().write(Content);
          
          def postRC = post.getResponseCode();
          if(postRC.equals(200)) {
              message.setBody("<?xml version=\"1.0\" encoding=\"utf-8\"?><root><status>Uploaded</status></root>");       
              messageLog.addAttachmentAsString("Post result:", post.getInputStream().getText() as String, "text/plain")
          }else{
              message.setBody("<?xml version=\"1.0\" encoding=\"utf-8\"?><root><status>Failed</status></root>");
              def exceptionMsg = "HTTP" + postRC.toString() + ", " + post.getInputStream().getText()
              throw new Exception(exceptionMsg as String)
          }
          
          return message
      }
      

      Reference articles:

      Nick Yang's solution, and Joao Miguel Gomes's contribution:

      https://answers.sap.com/questions/12963572/send-zip-file-and-form-data-through-cpi-and-http-a.html

      Rajath Kodandaramu's article:

      https://blogs.sap.com/2019/04/17/cpi-http-calls-from-groovy/

       

      Regards,

      Erkam Ozturk

      Author's profile photo ASUTOSH MAHARANA
      ASUTOSH MAHARANA
      Blog Post Author

      Dear Erkam,

       

      I think it's not recommended to do HTTP call directly from scripts without using any adapter from SAP CPI or any integration platform as it will cause issues for tracing and logging. We discourage developers to call the webservices from Java mapping as well in SAP PO for this reason.

      And there is no point in having all the processing steps or adapters in SAP CPI as well because we can do all the operations using Groovy scripts basically.

      The real culprit is SAP CPI's HTTP receiver adapter where we are getting the error due to charset conversion. Because we are already aware of this solution to call the APIs directly from script.

       

      You can go through the Power Automate flow alternative as well.

      BR,

      Asutosh Maharana

      Author's profile photo Yeswanth Posam
      Yeswanth Posam

      Hi Erkam,

      Even I could post files directly to Sharepoint using script but it is not recommended to follow that approach, so trying to use receiver adapter for posting files.

       

      Regards,

      Yeswanth

      Author's profile photo Lance Cansanay
      Lance Cansanay

      Hi Erkam,

      I know this is old but thank you for sharing this solution.

      I am currently encountering a HTTP 400 code error when posting a binary file to SharePoint.

      However, when the retrieval of binary files using this method works for me so I can confirm that the authentication works fine.

      If may I ask would you kindly provide an insight on what might be causing an issue when sending a binary file over?

      Your help would be highly appreciated.

      Thank you in advance.

       

       

      Author's profile photo Faisal Jamal
      Faisal Jamal

      Hi All,

      I am also facing the same issue while sending the binary data to SharePoint through HTTP receiver adapter in SAP CPI.

      Is there any other solution to this without using the Groovy script to directly call SharePoint or Power Automate flow?

      Thanks in advance!

      Regards,

      Faisal

      Author's profile photo Shameer Shaik
      Shameer Shaik

      Hello Ashutosh, Were you able to resolve issue of sending pdf's or pptx via http receiver adapter. If please provide insights .

      Author's profile photo ASUTOSH MAHARANA
      ASUTOSH MAHARANA
      Blog Post Author

      Dear Shameer,

      It seems like a standard behaviour of HTTP adapter to put UTF-8 encoding. But when we change the encoding of binary files, it seems like it corrupts the file and also changes the file length. This is the reason of failure.

      BR,

      Asutosh

      Author's profile photo Shameer Shaik
      Shameer Shaik

      Any alternative way overcome that. In my case I have to send binary data(pdf/gif) to Azure blob storage using HTTP adapter.

      Thanks!

      Shameer

      Author's profile photo Shameer Shaik
      Shameer Shaik

      Any alternative way overcome that. In my case I have to send binary data(pdf/gif) to Azure blob storage using HTTP adapter.

      Thanks!

      Shameer

      Author's profile photo ASUTOSH MAHARANA
      ASUTOSH MAHARANA
      Blog Post Author

      Only alternative I can think of is to send it via simple groovy script to call instead f http adapter.(or open connectors if you have license). But you should also explore more in http adapter.

      Author's profile photo Shameer Shaik
      Shameer Shaik

      Since we have standard connector provided by SAP, Performing http calls via script is not a good practice and debugging also will cause some problem.

      I have tried using SAP PO rest adapter , It's working fine there.

      Let me also raise it to SAP .Thanks Asutosh for providing more insights.

      Author's profile photo sivasankar chagaleru
      sivasankar chagaleru

      Hi maharana what you explained was very nice

      I am struk in creating content modifier could you please upload images of each and every step it would be easy to unserstand for us thank you hope you can upload pictures.

      Author's profile photo ASUTOSH MAHARANA
      ASUTOSH MAHARANA
      Blog Post Author

      Dear Sivasankar,

      if you want i can provide GitHub link.

      BR,

      Asutosh Maharana

      Author's profile photo Mahesh Sabba
      Mahesh Sabba

      Hi Asutosh,

       

      Very useful blog, Thank you.

       

      I am doing the same integration now to upload the .csv files from CPI sharepoint path, i have followed the same steps as per the blog and Bearer token also generated.

      But while passing the same token in the header to connect to sharepoint getting the 401 authorization error with the below error description

      {"error_description":"Invalid JWT token. Could not resolve issuer token."}

      Could you please help me with this error ,Whether am i missing something to pass while connecting to sharepoint.

       

      Thanks & Regards,

      Mahesh

       

      Author's profile photo ASUTOSH MAHARANA
      ASUTOSH MAHARANA
      Blog Post Author

      Dear Mahesh,

      Please try using the same token in postman first. There might be some authorization issue. Kindly follow Sharepoint app configuration steps properly and then try to upload something using postman first. if that is successful then you should not have issue with SAP CPI.

      BR,

      Asutosh Maharana

      Author's profile photo Mahesh Sabba
      Mahesh Sabba

      Hi Asutosh,

       

      Thanks for the response.

      I am getting the same error from Postman also. I am trying with the GET operation first just to check the connectivity.

      Below is the screenshot from the Postman

      Sharepoint

      Sharepoint

       

       

      Author's profile photo Shyam Viswanathan
      Shyam Viswanathan

      Did you resolve this? I have the same issue.

      Author's profile photo Chandrasekhar Pelluru
      Chandrasekhar Pelluru

      Hi Asutosh,

       

      When we are posting excel files (CSV files ) to share point, facing an encoding issue as shown below by using ByteArray script.

      Endoing_issue

      Endoing_issue

       

      Please help us for this encoding issue.

      Author's profile photo Shyam Viswanathan
      Shyam Viswanathan

      Hi ,

       

      I am in the final step where i am trying to post a file and keep getting 401 no matter what i do and try

       

      Have followed the steps, retreived the token, adding only 2 heders to the final POST step but always keep getting 401, have checked permissions and have added tenant level FULL CONTROL permissions.

      Author's profile photo ASUTOSH MAHARANA
      ASUTOSH MAHARANA
      Blog Post Author

      Dear Shyam,

      Thanks for letting me know. It seems like authorization issue.

       

      Thanks,

      Asutosh

      Author's profile photo satish b
      satish b

      Hello Asutosh,

       

      We are following your blog and trying to post a file in SharePoint, but we are facing a http:403 issue. While debugging, we found the receiver payload with original xml and did not append the token.

      It seems, payload did not merge after join & gather. Please find the attached screenshots for the same.

      Could you please let us know, if we have missed anything in the iflow or in configuration of content

      modifier/join & Gather.

      Thanks in advance.

      Satish

      Author's profile photo Akansh Bhatnagar
      Akansh Bhatnagar

      Hi Satish,

      How did you get this issue resolved?

      Author's profile photo satish b
      satish b

      Hello Akansh,

       

      We have used a groovy to construct the URL and called that URL at the HTTP adapter in the IFLOW find the attached for the same.

      Before to Groovy, values of filepath, file and hostname are maintained in content modifier.

       

      Below is the Groovy Code:

      import com.sap.gateway.ip.core.customdev.util.Message;

      import java.util.HashMap;

      import java.io.UnsupportedEncodingException;

      import java.net.MalformedURLException;

      import java.net.URL;

      import java.net.URLEncoder;

       

      def Message processData(Message message) {

      def pMap = message.getProperties();

      def filepath = pMap.get("filepath");

       

      def filename = pMap.get("filename")

       

      def hostname = pMap.get("hostname")

       

      def enfilepath = URLEncoder.encode(filepath, "UTF-8")

      def enfilename = URLEncoder.encode(filename, "UTF-8")

       

      def sURL = "https://${hostname}/_api/web/GetFolderByServerRelativePath(DecodedUrl=@a1)/Files/AddUsingPath(DecodedUrl=@a2)";
      def query = "@a1=${enfilepath}&@a2=${enfilename}"

      message.setProperty("sharepointQuery",query)

      message.setProperty("sharepointURL",sURL)

       

      return message;

      }

       

      Author's profile photo Alan Waters
      Alan Waters

      Hi there,

      I'm pretty new to Sharepoint config, so apologies if this is obvious.

      I'm struggling to get it to work, I keep getting a 403 error when connecting to SP from Postman or SCI:
         <m:code>-214702****, System.UnauthorizedAccessException</m:code>
         <m:message xml:lang="en-US">Access denied.</m:message>

      I think I may have something wrong in the first step ("SharePoint App Configuration").

      On these steps:
      Enter AppDomian as a localhost
         Enter RedirectUri as a https://localhost

      Do we enter the actual word "localhost", or do we need to enter our company Sharepoint domain, or the SCI/CPI tenant domain that we're connecting to Sharepoint from?

      Similarly on "Grant Permissions to Add-In", do we need to change the following string to be our own Sharepoint domain?

      i.e.
      <AppPermissionRequest Scope="http://sharepoint/content/sitecollection/web" Right="Write" />

      or

      <AppPermissionRequest Scope="http://mycompany.sharepoint.com/content/sitecollection/web" Right="Write" />

       

      Apologies if these are obvious questions.

      Many thanks,
      Alan

      Author's profile photo ASUTOSH MAHARANA
      ASUTOSH MAHARANA
      Blog Post Author

      Dear Alan,

      I would request you to go throught the "SharePoint App Configuration" section again. Common mistakes are not creating App under proper site. <siteURL> is actually combination of your sharepoint domain name + '/sites/' + site name.

      I am attaching a postman collection for manually testing the sharepoint file upload and download.

      Please verify the connectivity first from postman and then try to replicate the same in Cloud Integration.

       

      If you are still facing issue, please DM me in LinkedIn.

      Thanks,

      Asutosh

      Author's profile photo Alan Waters
      Alan Waters

      Thanks Asutosh. I will go through the SP config again and ensure everything is correct. I had a quick look at the Postman collection - this looks very helpful. I'll let you know how I go.

      Thank you for your support 🙂

      Author's profile photo Alan Waters
      Alan Waters

      Hi Asutosh,

      The Postman collection has been incredibly helpful in helping me to understand the correct syntax and format of each element. I have the GET request working to retrieve a file from my SP folder, which means my access token is working correctly - superb.

      But when I try to POST, it keeps telling me 'Access denied. Before opening files in this location, you must first browse to the web site and select the option to login automatically.'

      Any idea how to get around this?

      Many thanks again Asutosh.

      Kind regards,

      Alan

       

      Author's profile photo ASUTOSH MAHARANA
      ASUTOSH MAHARANA
      Blog Post Author

      Dear Alan,

      Can you please check where exactly you have registered your App. Is it in your Site Collection url or Tenant url? Ideally it should be in your Site collection url "https://<TenantName>.sharepoint.com/sites/<siteName>/_layouts/15/appregnew.aspx"

      and then go to below URL to provide permission.

      "https://<TenantName>.sharepoint.com/sites/<siteName>/_layouts/15/appinv.aspx"

      and put below xml for permission.

      <AppPermissionRequests AllowAppOnlyPolicy="true">
        <AppPermissionRequest Scope="http://sharepoint/content/sitecollection/web" Right="FullControl" />
      </AppPermissionRequests>

      then use that client id and client secret to call.

      Thanks,

      Asutosh

      Author's profile photo Alan Waters
      Alan Waters

      Hi Asutosh,

      I finally figured it out, it was an error in my URL call. The {{folderpath}} in the POST call below must contain the FULL path from /sites/ onwards (even though the collection name is already included in the {{HostName}}):

      https://{{HostName}}/_api/web/GetFolderByServerRelativeUrl('{{folderpath}}')/Files/add(url='testfile.txt',overwrite=true)

      e.g. my Sharepoint folder is...

      https://<mycompany>.sharepoint.com/sites/TEST_Records/Shared%20Documents/Forms/AllItems.aspx

      And folder in it is: Documents/Employee_files

      Therefore the parameters are:

      HostName =     <mycompany>.sharepoint.com/sites/TEST_Records

      folderpath =      /sites/TEST_Records/Shared%20Documents/Employee_files/

      The collection name (TEST_Records) is repeated in the Hostname and folderpath - this is where I was going wrong.

      I'm now able to post files from Postman to Sharepoint (and therefore MS Teams). Now I'll try it in SCI...

      Thanks for your support Asutosh, you're a gentleman. Incredibly useful blog 🙂

      Kind regards,

      Alan

      Author's profile photo ASUTOSH MAHARANA
      ASUTOSH MAHARANA
      Blog Post Author

      Really happy that it worked.

       

      PS. Above details were also shown in the Environment "Sharepoint AsutoshIntegration" in my Postman workspace. Kindly have a look into that as well.

      Thanks,

      Asutosh

      Author's profile photo Alan Waters
      Alan Waters

      One last question, Asutosh (thanks!)

      I'm trying to call the URL from SCI now, with the same parameters as I'm using in Postman, but it's failing (403) on both the GET and POST calls.

      Do I need to register another app on the Sharepoint site with the SCI domain info that I'm calling from, instead of "localhost"?

      i.e. to tell Sharepoint that it should allow the SCI tenant to connect?

      Thanks,
      Alan

      Author's profile photo ASUTOSH MAHARANA
      ASUTOSH MAHARANA
      Blog Post Author

      Dear Alan,

      It's not required to have another App, the same should work you need to debug the flow more to understand the issue.

      Thanks,

      Asutosh

      Author's profile photo Alan Waters
      Alan Waters

      Thanks Asutosh, will keep working on it.

      Author's profile photo Alan Waters
      Alan Waters

      Hi Asutosh,

      I finally got it to work. The issue was that the 'Authorization' header was not being passed to the URL call, so I forced it through by allow-listing it in the Request Headers on the HTTP adapter:

      The solution is described here, hopefully this will help others with the same issue:

      https://answers.sap.com/answers/13547307/view.html

      I'm now able to GET and POST between SCI and Sharepoint.

      Thanks again for your help and advice.

      Cheers,
      Alan

      Author's profile photo Babu Rao Gummadela
      Babu Rao Gummadela

      Hi Asutosh,

      Thanks a lot for your post and we're facing an Issue from SAP CPI Flow . Please find the steps which we've followed.

      1. Registered the app in SharePoint
      2. Tested the REST services from Postman tool
      3. Build the SAP CPI Flow
      4. Tried to access SharePoint Services via CPI Flow but it is throwing an Issue and unable to generate the Refresh token.

      Error : "error":"invalid_client","error_description":"AADSTS7000215: Invalid client secret provided. Ensure the secret being sent in the request is the client secret value, not the client secret ID

      Cross verified the client ID and secret and all are working fine from Postman.  Request you to share if you've any thoughts. Appreciate all your help.

      Author's profile photo Alan Waters
      Alan Waters

      Hi Babu,

      I had a similar issue. If the Client Secret contains + = etc, it can cause issues.

      You can get around this by encoding the non-alphabetical characters in the Secret

      e.g. replace + by %2B , = by %3D etc.

      This worked for me.

      Hope this helps.

      Cheers,
      Alan

      Ref: https://stackoverflow.com/questions/42477266/aadsts50012-invalid-client-secret-is-provided-when-moving-from-a-test-app-to-pr

      Author's profile photo Techedge-PI Consultor
      Techedge-PI Consultor

      Hi,

      I´ve been checking the blog, looks great.

      When checking the attached postman collection, I thought that the autentication for the first request (the one to get the resource and tenant_id), was weird:

      The value of the Bearer Token, is "Bearer"

      Is this fine?

      Do we have to make a previous call to get this token?

      Thanks in advance,

      Mikel

      Author's profile photo Alan Waters
      Alan Waters

      Hi Mikel,

      You don't need a token in this step, because all you're doing is trying to retrieve the response headers. The call should fail with code 401:

       

      But you don't need it to be successful.

      You need to look at the response header WWW-Authenticate - this contains the information you need for the next step, when you will try to retrieve the access token using the Bearer realm, client_id, etc.

      Hope this helps.

      Thanks,

      Alan

      Author's profile photo Techedge-PI Consultor
      Techedge-PI Consultor

      Thanks mate!

      Author's profile photo Alan Waters
      Alan Waters

      Hi ASUTOSH MAHARANA

      Thanks for all your help on this so far. All going well, except I've hit another small issue, I'm hoping you might know what to do here.

      I have everything working on a test Team: files and folders are modified by Sharepoint App.

      All good.

      I'm now trying to get it working on a 'real' Team, but the Channels on the real Team are set to 'Private'.

      So I tried creating a test private Channel:

      Now when I try to even GET a file from this Channel using the exact same logic, it's returning an access issue (in Postman or in SCI):

      Access is denied. (Exception from HRESULT: 0x80070005 (E_ACCESSDENIED))

       

      Is there something else that needs to happen here?

      e.g. do I need to somehow add Sharepoint App to the team as a member? (not sure how I would do this)

      Or is there something else?

      Many thanks,
      Alan

      Author's profile photo Alan Waters
      Alan Waters

      I've figured this out. A Teams Private Channel gets its own Sharepoint site, so it needs its own add-in app (i.e. Client ID & Secret), separate from the app that was set up for the main Team.

      Author's profile photo Faycal El Khenati
      Faycal El Khenati

      Hi ASUTOSH MAHARANA,

      I have followed your blog to config the Sharepoint connector but i'm facing the following error:

      {"error_description":"Exception of type 'Microsoft.IdentityModel.Tokens.AudienceUriValidationFailedException' was thrown."}

      x-ms-diagnostics : 3000003;reason="Invalid audience Uri '00000003-0000-0ff1-ce00-000000000000/cascades@a866874a-d0e3-4a03-a79d-4c893ab51296'.";category="invalid_client"

      Do you have an idea what might be the issue?

       

      Thank you in advance