Skip to Content
Technical Articles
Author's profile photo Prasanth Padmanabhan Menon

How to use a REST API to post data into SAP S/4HANA Cloud using SAP Intelligent RPA 2.0

Co-Authored with Piyush Gupta

In this blog, I will take you through the steps for creating a bot via SAP Intelligent RPA 2.0, through which you can post data into SAP S/4HANA Cloud via REST APIs.

SAP Intelligent RPA 2.0 uses a new Low-code/No-code approach for bot creation and this significantly reduces the load on developers.

Introduction

With the desktop studio application, developers are free to create custom SAP Intelligent RPA bots which simplifies day to day tasks by reducing human intervention. With SAP Intelligent RPA 2.0 and its Low-Code approach, I will show you how to leverage the SAP Intelligent RPA Cloud Studio to create the API call.

I will be using the supplier invoice creation API which can be accessed via activating the Communication Arrangement SAP_COM_0057 in the SAP S/4HANA Cloud system. You can refer the blog Setting up Communication Management in SAP S/4HANA Cloud for steps to activate a communication arrangement.

Create Automation

The first step would be to login to the SAP Intelligent RPA Cloud factory, go to the projects tab and create a new project.

Enter the bot name and click on create.

This will create a new project and will open the project in a new window.

Under the contents, tab, Click on Create and then select Automation

Provide the necessary details and click on create

This will create a new automation with an empty workflow as shown

Let us create two input variables for providing username and password of type String. This can be done by going to the I/O tab and adding two input parameters as shown

The next step will be to encode the username and password. The encoded string can be used to make the REST API calls.

Search for Encode String under the tools tab to get the Encode String activity.

Drag and drop this activity to the RPA workflow as shown below

You will now see that the activity has a red highlight. This is because it expects an input to be encoded.

Click on the activity Encode String. This will open the input fields for the activity. Select the highlighted button next to the input

This will open the Expression Editor.

Expand the Tree variables and click on both username and password and maintain as shown. Click on test expression to validate the input

The encrypted output will be returned via the Output Parameter, result of type String, which will be created automatically.

I have renamed this to credentials. You can do this by clicking on the Output Parameters field directly.

A custom script step should be added to fetch the CSRF token for posting the API.

Add the step custom script to the workflow from the tab Tools and rename it to Fetch Token

Double click on the activity Custom Script and add the field credentials as an input of type String and paste the following code in the script

async function fetchToken() {
    const options = {          
        resolveBodyOnly : false,
        method: 'GET',
        url: 'https://xxxxxx-api.s4hana.ondemand.com/sap/opu/odata/sap/API_SUPPLIERINVOICE_PROCESS_SRV/A_SupplierInvoice',
        headers: {
            'Accept' : 'application/json',
            'Content-Type': 'application/json',
            'Authorization' : 'Basic ' + credentials,
            'x-csrf-token': 'fetch'
        }
    };
    try {
        const response = await irpa_core.request.call(options);
        return response;   
    } catch (error) {
        const csrfToken = error.response.headers['x-csrf-token'];
        return error;
    }
}
let response = await fetchToken();
return response.headers;


Create an output parameter and name it as options, to return the output data and maintain the type as Any

You would still see the red highlight on the Activity Fetch Token. This is because the input field credentials is not yet mapped. To solve this, single click on the Activity Fetch token and map the output field ‘credentials’ of the previous step to the input of Fetch Token

This step will return the required tokens and cookies.

Add another Custom step to make the API post call and rename the step to Post API. We will build the test payload also in this step.

Add the input parameters csrf_token, cookie and credentials of type String and an output parameter payload of type Any and paste the following code in the script

var i = 0; 
var temp ="";
var cookieField ="";
if(cookie!=""){
    for(i=0;i<cookie.length-1;i++)
    {
        temp = cookie[i].split(";");
        cookieField = cookieField + temp[0] + "; ";
    }
    temp = cookie[i].split(";");
    cookieField = cookieField + temp[0];
}
var data = {
    "FiscalYear": '2020',
    'CompanyCode': '1710',
    'DocumentDate': '2020-02-20T00:00',
    'PostingDate': '2020-02-20T00:00',
    'InvoicingParty': '17300001',
    'DocumentCurrency': 'USD',
    'InvoiceGrossAmount': '520.00',
    'AccountingDocumentType': 'RA',
    'TaxIsCalculatedAutomatically': false,
    'to_SuplrInvcItemPurOrdRef': [
        {
            'FiscalYear': '2020',
            'SupplierInvoiceItem': '1',
            'PurchaseOrder': '4500000000',
            'PurchaseOrderItem': '10',
            'Plant': '',
            'ReferenceDocument': '',
            'ReferenceDocumentFiscalYear': '',
            'ReferenceDocumentItem': '',
            'TaxCode': 'I1',
            'DocumentCurrency': 'USD',
            'SupplierInvoiceItemAmount': '520',
            'PurchaseOrderQuantityUnit': 'PC',
            'QuantityInPurchaseOrderUnit': '10',
            'QtyInPurchaseOrderPriceUnit': '1',
            'to_SupplierInvoiceItmAcctAssgmt': {
            'results': []
            }
        }
    ]
};
var payload = {
    resolveBodyOnly : true,
    method: 'POST',
    url: 'https:// xxxxxx-api.s4hana.ondemand.com/sap/opu/odata/sap/API_SUPPLIERINVOICE_PROCESS_SRV/A_SupplierInvoice',
    headers: {
        'Authorization': 'Basic '+ credentials,
        'Cookie' : cookieField,      
        'Content-Type': 'application/json',
        'x-csrf-token' : csrf_token
    },
    ignoreClientCertificate: true,
    body: JSON.stringify(data)
};
return payload;

Make sure to modify the input payload according to your system landscape settings.

Now, there will be a red highlight on the Activity Post API. Maintain the input for csrf_token, cookie and credentials as follows

csrf_token

cookie

credential

Save the expressions

Add the step Call Web Service from the tools tab and maintain the input as follows

Add the step Log Message to log the output of the web service call and maintain the input as shown

Save the workflow and click on test.

Provide the username and password as input and click on test

This will post the supplier invoice to the SAP S/4HANA Cloud system and return the Supplier invoice number as shown

You can convert this to JSON by adding a header type ‘Accept’: application/json in the Custom Script Post API and continue to use this in your application as required.

 

You could then follow the blog Deploy your SAP Intelligent RPA bot from the Cloud Studio to the Cloud Factory  for deploying and publishing the bot to the Cloud factory

 

For more information on SAP Intelligent RPA

Assigned Tags

      4 Comments
      You must be Logged on to comment or reply to a post.
      Author's profile photo Alan Weichelt
      Alan Weichelt

      Hi Parasanth

      I am getting an error on the FETCH TOKEN step :

      "Cannot read property 'headers' of undefined"

      {
          "uid": "b787943c-cdf0-49e8-8067-0eeffb38cc74",
          "name": "RestAPI Call",
          "type": "automation",
          "instanceUid": "a93961dd-9cbf-4e18-7f3f-cc9575d1952c",
          "packageUid": "4d90e55f-14d6-4300-83d6-83c2e7285828",
          "packageVersionUid": "b28c6ede-cba8-49f3-ab6c-efd685c9168f",
          "attended": true,
          "duration": 11,
          "nbRun": 1,
          "status": "Failed",
          "code": "KO",
          "label": "Cannot read property 'headers' of undefined",
          "containerInstanceUid": "bc9b7c5f-5b86-30c3-2c0d-69968879a9ff",
          "parentInstanceUid": "50df578a-ee2f-6fc2-8286-cc78dd65a163",
          "line": 21,
          "file": "restAPICall.js",
          "stepId": "5",
          "exception": "irpa_core.error.Error",
          "stack": "Error: Cannot read property 'headers' of undefined\n    at Object.e.error.cast (C:\\Users\\Koala\\AppData\\Local\\SAP\\Intelligent RPA\\Projects\\cd4447f8-3229-4007-b4e0-0c8259d4aa4d\\dist\\bundle.js:2:199629)\n    at C:\\Users\\Koala\\AppData\\Local\\SAP\\Intelligent RPA\\Projects\\cd4447f8-3229-4007-b4e0-0c8259d4aa4d\\dist\\bundle.js:2:406275\n    at processTicksAndRejections (internal/process/task_queues.js:93:5)\n    at async e.jobClass.restAPICall [as a93961dd-9cbf-4e18-7f3f-cc9575d1952c] (C:\\Users\\Koala\\AppData\\Local\\SAP\\Intelligent RPA\\Projects\\b28c6ede-cba8-49f3-ab6c-efd685c9168f\\automations\\restAPICall.js:7:25)"
      }
      Can you help ?
      Author's profile photo Prasanth Padmanabhan Menon
      Prasanth Padmanabhan Menon
      Blog Post Author

      Hi Alan,

       

      Could you share the code you have used to perform the Fetch token step?

       

      Best Regards,

      Prasanth

      Author's profile photo Alan Weichelt
      Alan Weichelt

      Hi Parasanth

      The code is:

      async function fetchToken() {

          const options = {
              resolveBodyOnly : false,
              method: 'GET',
              url: 'https://vhrbsds4ci.sap.rbd.co.nz:44300/sap/opu/odata/sap/api_supplierinvoice_process_srv/A_SupplierInvoice',
              headers: {
                  'Accept' : 'application/json',
                  'Content-Type': 'application/json',
                  'Authorization' : 'Basic ' + credentials,
                  'x-csrf-token': 'fetch'
              }
          };
          try {
              const response = await irpa_core.request.call(options);
              return response;
          } catch (error) {
              const csrfToken = error.response.headers['x-csrf-token'];
              return error;
          }
      }
      let response = await fetchToken();

      return response.headers;

      Author's profile photo Prasanth Padmanabhan Menon
      Prasanth Padmanabhan Menon
      Blog Post Author

      Hi Alan,

       

      Apologies for the delayed response. The code looks ok as the same code works for me. Could you check the version of the dependency irpa_core on your system? Make sure that it is above 1.7.59

       

      Best Regards,

      Prasanth