Skip to Content

Glad to meet you all in Part 4! In the earlier posts, we have covered the basics of SAP Cloud Platform Functions with an interesting hello-world and a serverless whatsapp chatbot. In this post, we will be exploring the use case of event-driven integration between disparate SaaS systems/products.  Apart from the earlier usecases that we saw, this one is specific to integration between Cloud ERP(SAP ByD) and a SaaS product(Ex. Leadsquared). We leverage the power of webhooks to achieve event-driven integration.

In this example,we will see how a lead, which is present in the Leadsquared tool, gets converted to a customer in SAP Business ByDesign when the lead stage changes from prospect to customer. Here’s a sneak peak of how it works.The video is the TL;DR as well 😉

We will make use of CloudFoundry FaaS with minimal coding to achieve the same. Here are some of the prerequisites before we dive-in:

  1. Trial SAP Cloud Platform Account with SAP Cloud Platform Functions (CF FaaS) enabled.
  2. Leadsquared or any other CRM/Marketing automation tools like Hubspot,Zoho CRM etc. that has support for webhook APIs.

Let's get into action !

Let’s get started.

Configuring SAP Business ByDesign(ByD) tenant and exposing WebServices:

Inorder for us to interact with any Cloud ERP, we need to know the APIs that it offers. In the SAP ecosystem, the SAP API Business Hub (https://api.sap.com/) takes care of that! Since we would be requiring APIs related to customer creation, we can search for ByD artifacts.

Technically, we would be creating an account in ByD and hence we will be making use of ManageCustomerIn API. The definition of the API, payload structure, technical codes to be used are mentioned over there with examples. You can find the same in ByD Web Service explorer. However, I’d prefer the API Business Hub since it is documented really well,looks neat & can be used as a standard reference for looking up other APIs as well.

API Documentation : https://api.sap.com/api/PSM_ISI_R_II_MANAGE_CUSTOMER_IN/overview

 

Now that we know the right APIs, its just a matter of exposing them. You need to configure the following a. Communication System (Optional) > b. Communication Scenario > c. Communication Arrangement in the ByD tenant. For this API, you can use an existing communication scenario called “Business Partner Data Management – Manage Accounts”. Please skip to section 2 if you know how to do this setup in ByD. The goal is to expose the APIs and make it accessible via a technical user.

Regardless, I’ll walk you through the setup right from a to c & show you how easy it is. Start by clicking on Application and User Management.

i. Communication System:

You can create a separate communication system by clicking on the ‘Communication Systems’ option. You need to specify the ID, Hostname, AccessType – Internet, Technical contact details and then hit ‘Save’. Make sure it is activated.

ii. Communication Scenario:

The communication scenario exposes the services that we need. Specify the name and add the necessary services that should be exposed.

iii. Communication Arrangement:

In the communication arrangement you can specify the communication method, protocol, authentication method. You can specify the credentials that you will be using for basic authorization. Kindly note it down. We will be requiring it.

You will also be able to see the service url along with the wsdl. Download the WSDL and note the service url.

 

You can use SOAP UI to validate the service and test account creation. You can use this sample payload.

..and it works in SOAP UI!

(Make sure you specify the technical user credentials that we created while setting up the ByD communication arrangement under the SOAP UI ‘Request properties’ pane to access the ByD webservice)

It Works! Hold tight, Just a couple of scrolls away from complete integration.

We will use this payload as a template in our cloud function. Let’s get to the SAP Cloud Platform Functions designer Node.JS IDE

Create the SAP Cloud Platform Function that integrates LeadSquared with ByD

It is assumed that you have gone through this post to understand the basics of SAP Cloud Platform Functions. In your functions designer dashboard, just paste the below mentioned code for the newly created function and create an HTTP trigger for it. The code outputs the payload that Leadsquared sends. This is just to test the connectivity between ByD and Leadsquared tool.

module.exports = {
    handler: function (event, context) {
        try{
            var newLead = JSON.parse(event.extensions.request.body.toString('utf-8'));
            console.info(newLead);
        }catch(e){
            console.warn(e);
        }
        event.extensions.response.send("OK");
    }
}

Open the LeadSquared system in parallel, and navigate to the webhooks screen. Webhooks are means to call a target external API when some event occurs in the source system. Paste the HTTP trigger URL of the function in the Webhook URL.

Select the Event as Lead Stage Change. In our case, it will be Any Stage to Customer.

Make sure the Webhook url has https and not http selected. The content type can be application/json

Now, create few dummy leads in LeadSquared and change the stage from Prospect to Customer.

You will be able to see the payload in the Functions logs.

This means that the Leadsquared tenant is able to invoke the SAP Cloud Platform Function whenever the lead state occurs..!

Automating Customer creation in ByD when a lead state changes

Now that we know webhooks work as intended with SAP Cloud Platform Functions,we can use it to invoke the APIs in ByD. It can be achieved with the below mentioned function code. The function posts the xml body to the ByD (SOAP) Webservice. It acts as a light-weight middleware that transforms the payload which is received from the Leadsquared tenant to the format that SAP ByD expects.

const request = require('request');

function xBody(details){

var xmlbody = `<soap:Envelope xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/" xmlns:glob="http://sap.com/xi/SAPGlobal20/Global" xmlns:glob1="http://sap.com/xi/AP/Globalization">
<soap:Header />
<soap:Body>
   <glob:CustomerBundleMaintainRequest_sync_V1>
      <BasicMessageHeader/>
      <Customer actionCode="01" textListCompleteTransmissionIndicator="true">
         <CategoryCode>1</CategoryCode>
         <CustomerIndicator>true</CustomerIndicator>
         <Person>
            <GivenName>`+details.After.FirstName+`</GivenName>
            <FamilyName>`+details.After.LastName+`</FamilyName>
            <GenderCode>1</GenderCode>
         </Person>
         <AddressInformation actionCode="01" addressUsageListCompleteTransmissionIndicator="true">
            <Address actionCode="01" telephoneListCompleteTransmissionIndicator="true">
               <EmailURI>`+details.After.EmailAddress+`</EmailURI>
               <Telephone>
                  <ObjectNodeSenderTechnicalID>004</ObjectNodeSenderTechnicalID>
                  <FormattedNumberDescription>`+details.After.Phone+`</FormattedNumberDescription>
                  <MobilePhoneNumberIndicator>true</MobilePhoneNumberIndicator>
               </Telephone>
            </Address>
         </AddressInformation>
             <Text actionCode="01">
             <ObjectNodeSenderTechnicalID>019</ObjectNodeSenderTechnicalID>
             <TypeCode>10034</TypeCode>
             <ContentText>`+details.After.Source+`</ContentText>
         </Text>
      </Customer>
   </glob:CustomerBundleMaintainRequest_sync_V1>
</soap:Body>
</soap:Envelope>`;
return xmlbody;

}

module.exports = {
    handler: function (event, context) {
        // event.extensions.response.send(JSON.stringify(event.extensions.request.body));
        var newCustomer = JSON.parse(event.extensions.request.body.toString('utf-8'));
        var opts = {
            url: 'https://<byd_tenant>/sap/bc/srt/scs/sap/managecustomerin1',
            method: 'POST',
            body: xBody(newCustomer),
            headers: {
                'Content-Type': 'text/xml',
                'Authorization': 'Basic <base64_of_username:password>'
            }
        };
        console.log(opts);
        request(opts, (err, res, body) => {
            if (err) { return console.log(err); }
            console.log(res.headers);
            console.log(res.body);
        });
    }
}

Make sure you replace the filler with ByD tenant URL and technical user credential in the respective places.Also, add dependencies specified below the function code

{
   "dependencies":{
      "request":"latest"
   }
}

Now let’s try again and see if the replication works as intended.

 

and it works! 🙂 ! This setup acts as a starter template for simple integration and there’s lot of room for improvements. Let me know if this technique worked for you ! Please share your feedback & interesting findings as well! Get in touch with our ByD team over here.You can contact me on LinkedIn or Twitter regarding the same! Stay tuned ! ⚽

To report this post you need to login first.

Be the first to leave a comment

You must be Logged on to comment or reply to a post.

Leave a Reply