cancel
Showing results for 
Search instead for 
Did you mean: 
Read only

Access external sources from Kyma function

lucasmillbrodt
Explorer
0 Likes
2,375

Dear all,

I am experimenting in the Kyma environment and I would like to access an external OData-service (in this case one that is anchored in our C4C) in a Node.js-function. I can see and use the credentials saved in the environment variables, however, I am uncertain which JavaScript-function can be used in this environment to access the external source.

So far, my function looks like this. Upon contacting the API-Endpoint directing to this function, I receive my username of the C4C (as saved in the environment variables) and the unique entity-id as served by the C4C after firing the Event Notification.

module.exports = { 
  main: function (event, context) {
    // access to environment variables
    var oCredentials = JSON.parse(process.env.CONFIGURATION);
    var sUser = oCredentials.credentials.username;
    
    // make the incoming JSON readable by Node.js and select the Unique-ID (Entity-ID)
    var sEventData = event.data.replace(/-/g, '');
    var oEventNotification = JSON.parse(sEventData);
    var sEntityId = oEventNotification.data.entityid;
    return sUser + " " + sEntityId;
  }
}

If I simulate this code by sending a payload via Postman, I see, that I get the values I selected. My next step would be fetching the corresponding data with this entity-id from the OData Service. Is this possible in this manner?

Also, as you can see, my C4C is already recognized by the Kyma-environment:

All the best

Lucas Millbrodt

Accepted Solutions (0)

Answers (3)

Answers (3)

Marco_Dorn
Product and Topic Expert
Product and Topic Expert

Hello lucasmillbrodt,

I am not sure what you would like to achieve. If you want to make use of the OData APIs, you typically use the Gateway URL and you don't need to authenticate again. That's what the pairing process via the Global Account and creating the Formation is taking care of. E.g. one of our examples selects the address of an updated account. This means, you start with

const baseURL = `${process.env['SAP_SALES_CLOUD_***_GATEWAY_URL']}`;

In the main function, you then get the entity-id of the updated object

var accountId = event.data["entity-id"];

And then you can read the address

var response = await axios({
  method: 'get',
  url: `${baseURL}/CorporateAccountCollection('${accountId}')`,
  params: {
    '$select': 'CurrentDefaultAddressUUID,Name,CountryCodeText,HouseNumber,Street,StreetPostalCode,City'
  }
})
corporateAccount = response.data.d.results;

You can have a look as well at our samples on GitHub.com as some relate to C4C: https://github.com/SAP-samples/kyma-runtime-extension-samples

Best regards,
Marco.

VishnAndr
Active Contributor

And don't forget to make your main function as async if you want to use await within it.

module.exports = { 
main: async function (event, context) { 
....
}

lucasmillbrodt
Explorer
0 Likes

Thank you marco.dorn and 380bac697e274c14b0bf3ca56bd5603e!

I had to experiment a bit further because I was not aware of how to set the needed dependencies (I have a feeling this might still be missing in the current tutorials), but after looking around for a bit I got this one figured out.

Yes, Marco, in general you got my idea. However, as far as I can see, the Gateway-URL fetches data from the SAP OData-Services. As we are working on a custom object, I want to fetch the OData from one of the Custom OData-Services. Is there an elegant way to switch to another path (in the environment variable the relative path assigned to the SAP-OData is "/v1/c4codataapi/", however the needed path would be "/cust/v1/z_eventlm_odata").

Best regards

Lucas

jamie_cawley
Product and Topic Expert
Product and Topic Expert
0 Likes

Hi Lucas,

Unfortunately, c4c doesn't provide a way to register custom services. As a workaround, you could use the information found in configuration variable provided by the service binding to manually authenticate and call your service.

Regards,

Jamie

VishnAndr
Active Contributor
0 Likes
jamie_cawley
Product and Topic Expert
Product and Topic Expert
0 Likes

Hi Lucas,

When you are sending the post most sure you include the cookies received in the response for obtaining the x-csrf-token.

Regards,

Jamie

lucasmillbrodt
Explorer
0 Likes

Hey Jamie,

do you have a suggestion on how to implement the inclusion of cookies via the Node.js-Code?

Best regards

Lucas

jamie_cawley
Product and Topic Expert
Product and Topic Expert
0 Likes

The values should be in the set-cookie headers, just copy and send them the same way you are doing with the x-csrf-token.

Regards,

Jamie

lucasmillbrodt
Explorer
0 Likes

Hi Jamie,

I set the cookies acoordingly, as to be seen in this screenshot:

Sadly, the error message remains the same (It says CSRF token validation failed):

Best regards

Lucas

jamie_cawley
Product and Topic Expert
Product and Topic Expert

Try setting the headers with

headers: {
"x-csrf-token": resp.headers['x-csrf-token'],
        "Cookie": resp.headers["set-cookie"].join(";")
      },


lucasmillbrodt
Explorer
0 Likes

Thank you Jamie,

this solved my problems.

All the best

Lucas