Skip to Content
Technical Articles
Author's profile photo Somnath Paul

Build Your BOT with SAP CAI & Integrate with UI5 App using Node JS

Introduction:

This blog post is part of a series of learning & here you can check my previous blog post which includes a bunch of tutorials containing the RESTFUL ABAP Programming journey.

I built a full-stack UI5 Application (Travel & Booking App) on top of the RAP Model and now the intention is to add a tiny chatbot (named Travel Bot) to make a simple query to get to know my Travel details against a Travel ID and integrating this Travel BOT with my simple UI5 Application

Let’s begin…

Step1-Build a simple Node JS Application:

The plan is to create a node JS application to make it work as my backend server which will make a call to my RAP API and do some massaging with the response from RAP Service.

But my RAP service is covered under OAuth protection so just a simple call with Basic Authentication will not work and we need some JWT (JSON Web Token) to deal with it. That means for every query to my RAP Model I need a token?.but…

The token does have a certain validity period so what about that? Should I keep generating for every call or some approach I can think of to store the token until this is not expired! Cool…but where should I store this?

Can I store this in a cookie? Technically yes, what about security? I am not sure of, leaving experts to comment on 🙂

BTW this is a POC so thought to go with the cookie approach to store my JWT.

So what this Node JS will do eventually?

  • First, check if the token is available in my browser cookie, use it if available
  • If this token is valid I am lucky else clean the cookie and raise the error
  • The user will retry and generate a new token and store it back to the cookie
  • Do some response molding to be used for my Travel BOT

Fine so now the basic algorithm is clear and let’s build it.

How to get the Authentication details, I mean, I need something to generate a token!

In my previous blog post, you will find how to test your Web API using POSTMAN:

  • Build Web API and get this Tested in POSTMAN –  Video

Which says how to generate a token using client id, client secret using XSUAA – Authentication, and Trust Management Service, that’s cool. but here I need to do a similar thing but programmatically, let’s do that.

 

let request = require("request");
const getToken = function () {
  let auth_url =
    "https://c14ab408trial.authentication.us10.hana.ondemand.com/oauth/token?grant_type=password&username=<example@gmail.com>&password=<1234>";

  return new Promise((resolve, reject) => {
    request(
      {
        url: auth_url,
        method: "POST",
        auth: {
          user: "<your client id>",
          pass:
            "<you client secret>",
        },
      },
      function (error, res) {
        if (error) return reject(error);
        if (res.statusCode != 200) {
          return reject("Invalid Status Code");
        }
        let json = JSON.parse(res.body);
        resolve(json.access_token);
      }
    );
  });
};

That’s cool so now I generated a token and let’s store it in the cookie.

let access_token = req.cookies.access_token;

  if (access_token == "" || access_token == undefined) {
    access_token = await getToken();
    res.cookie("access_token", access_token, {
      httpOnly: true,
    });
  } else {
    console.log("Received token from cookie");
  }

Token now stored…what next? Obviously, we now should call our RAP service using this token.

app.post("/Travel", async (req, res) => {
  let travelID = req.body.TravelID;

  let access_token = req.cookies.access_token;

  if (access_token == "" || access_token == undefined) {
    access_token = await getToken();
    res.cookie("access_token", access_token, {
      httpOnly: true,
    });
  } else {
    console.log("Received token from cookie");
  }

  const url =
    "https://<enter your API url>.abap.us10.hana.ondemand.com/sap/opu/odata/sap/ZSB_TRAVEL_WEBAPI_U/Travel?$filter=%20(TravelID%20eq%20%27" +
    travelID +
    "%27)";

  const TravelDetail = function (url, access_token) {
    return new Promise((resolve, reject) => {
      request(
        {
          uri: url,
          method: "GET",
          headers: {
            "content-type": "application/json",
          },
          json: true,
          auth: {
            bearer: access_token,
          },
        },
        function (error, res, body) {
          if (error) return reject(error);
          if (res.statusCode != 200) {
            return reject("Invalid Status Code");
          }
          let myObject = body.d.results[0];
          let sTravelDetails = "";
          for (const [key, value] of Object.entries(myObject)) {
            if (typeof value !== "object") {
              if (typeof value == "string" && value.indexOf("/Date") == 0) {
                let date1 = new Date(parseInt(value.match(/\d+/), 10));
                sTravelDetails = sTravelDetails + key + ":" + date1 + " ";
              } else {
                sTravelDetails = sTravelDetails + key + ":" + value + " ";
              }
            }
          }
          resolve(sTravelDetails);
        }
      );
    });
  };

But my BOT is not ready yet so to test the POST call let’s built a small GET method and render a simple HTML page where I can test my node js application from. Yes, true, this is an optional step, as you can test with POSTMAN client or ARC, etc. but I just did this as it took me a few seconds to build 😉

app.get("/", (req, res) => {
  res.send(`
     <form action="/Travel" method="POST">
    <p>Enter Travel ID</P>
    <input name="TravelID" autocomplete=off>
    <button>Fetch Details</button>
    </form>
    `);
});

Cool! so let’s test my application and check if at all working.

Here is the video with full steps and a working demo:

Build Your BOT with SAP CAI – EP1

 

Step2- Building Travel BOT within SAP CAI Console:

So now my Node JS is built, let’s deploy now to the cloud, why? simply because I am now planning to integrate this Application with the Travel Bot to be built with SAP CAI.

Let’s deploy the code using VS CODE CLI and looks like it really deployed!

Can I test this now, yes I can see my stupid HTML page!!!!

Even response also.. cool 😉

 

Now build the actual BOT using SAP CAI, two things needed here:

  • SAP CAI login
  • Interest to build

I have used an excellent tutorial as used in SAP TechEd and that exactly solves my purpose, let’s use that and build it with necessary molding as per my need.

Create a Chatbot that Lets Customers Track Package

Finally, I could build and integrate the Node JS application and was able to test from the SAP CAI Console, that’s really cool!

 

Here you go with the detailed steps as a video tutorial:

Build your BOT with SAP CAI – EP 2

Step3- Integrating Travel BOT with my UI5 Application:

A great journey so far, finally I need to integrate this little cute bot (with silly skill) to my UI5 Application.

Alright, let’s head over to my UI5 Application and add a simple code block to do so:

    renderTravelBot: function () {
      if (!document.getElementById("cai-webchat")) {
        var s = document.createElement("script");
        s.setAttribute("id", "cai-webchat");
        s.setAttribute("src", "https://cdn.cai.tools.sap/webchat/webchat.js");
        document.body.appendChild(s);
      }
      s.setAttribute("channelId", "<channel id>");
      s.setAttribute("token", "<token>");
    },

Here is the detailed step:

Build your BOT with SAP CAI -EP3

Another blog post as ongoing explorations on CAI:

Integrate your SAP Bot with Google Assistant

Conclusion:

A little try to create a simple BOT and integrating with backend RAP service using Node JS and finally accessing the same from UI5 Application.

The journey continues… and this is not even 1% been explored from CAI perspective so will try to explore more on other aspects of Integrations and soon will come back with some stupid application 😛

Stay tuned and wish you all a Very Happy New Year 2021… 🙂

Happy Learning!

-BR, Somnath

Assigned tags

      Be the first to leave a comment
      You must be Logged on to comment or reply to a post.