Search This Blog

Monday, April 17, 2017

How to call REST services using conversation service API Part 2 of IBM Watson Chabot series ?


REST API call from Watson conversation service


In our last tutorial on IBM Watson chatbot using conversation services we learnt how to setup the chatbot with demo and do a quick start.
In this tutorial we will see how can we instruct our chatbot to call our custom business logic, depending on the data entered by the user, this also explains how you can leverage this sample to build custom business logic around it.

Lets take a use case of Maximo application, where user will be reporting a problem with the application and the chatbot will raise a service request for that incident by collecting data from the user.
Please clone the following repo for this tutorial, customized for this use case.
https://github.com/systemoutgit/maximobot





For this we need to create three things:
> Intents/Entities/Dialogs

In our case intent will be #maximoproblems

image
This intent contains details on what a user might enter, it should contain all the queries which a user can type or think of.

Now lets create an entity for IBM Maximo application @maximo
@maximo (account lockout, service request)
I want the conversation for the bot to be centered around these two subjects so I created two entities for that.

image

Now we will create a dialog for this conversation, where a user will try to explain that the asset is broken and a service request has to be raised.
You will also see how to collect the input from another node of a dialog in the conversation service.


image

I renamed on of the demo node and added my condition for the intent I created.
It will match here if user enters any of the problem statements I explained in my intent.

Chat will go like this
=====================
Bot: Greeting on conversation_start
User: Hi
Bot : Greeting reply and waiting for user input.
User: Asset broken
Bot: May I know the problem are…?
User: Service Request
Bot: Oh I see you need to raise a service request, please provide asset number in format Assetnum-12345
====================================

Now the user will input the data in input.text node and we will capture that data which is the asset number in our case.


image

Now we will echo the asset number and a REST response(SR with Ticket ID) to user, we will see how is done via the Node JS code.

Now we will find the method in app.js(Express app) where it is sending the payload to conversation service and getting the responses to be sent to screen.

Code:
project_root/app.j( I use visual code editor for this syntax from command line > code app.js
==============================================

image

Our app has registered an endpoint called (/api/message), any message posted from front end will hit here and will send request and response objects.
In our request object we are sending workspace_id/context/input from user and the payload



Conversation is a wrapper around the watson conversation service and will be called from index.html every time a message is posted( payload is client data)
Now since payload is the incoming text by the user, we will try to request some keywords from user or input data in a specific format, so that we can detect that data in our method and do a REST call conditionally.

Here we are asking the user to input the asset number in Asset-12345 format and will put a condition on the input data and check if input text is of format (“Asset-“).
*If we find the unique identifier, we will extract the asset number by simple string parsing and will make a REST call and in the call back we will return the res object of the main app.post method.

image

Here you can see that we are making a conditional REST call and we are returning the post response in the callback handler of our request object.

Complete code for your reference(Also on github repo)
Code:
==============================================

conversation.message(payload, function(err, data) {
    if (err) {
      return res.status(err.code || 500).json(err);
if(data.output.text[0].includes("Asset-") & !data.output.text[0].includes('format'))
{
var assetNum = data.output.text[0].split("-");
assetNum=assetNum[1];
process.env.NODE_TLS_REJECT_UNAUTHORIZED = "0";
      request({
          headers: {
            'Authorization': 'Basic bWF4aW1vOnJlbW90ZTE=',
            'Content-Type': 'application/json',
           
          },
         
          url: 'https://maximo-demo75.mro.com/meaweb/os/MXSR',
          body: '<?xml version="1.0" encoding="UTF-8"?><max:CreateMXSR xmlns:max="http://www.ibm.com/maximo" creationDateTime="2008-09-29T07:19:45" >  <max:MXSRSet>    <max:SR action="Create" > <max:ASSETNUM changed="true">'+assetNum+'</max:ASSETNUM> <max:ASSETORGID changed="true">EAGLENA</max:ASSETORGID> <max:ASSETSITEID changed="true">FLEET</max:ASSETSITEID>  <max:AFFECTEDPERSON changed="true">MAXIMO</max:AFFECTEDPERSON>  <max:STATUS maxvalue="string" changed="false">NEW</max:STATUS>   <max:REPORTDATE changed="true">2017-04-06T11:24:06</max:REPORTDATE>    <max:REPORTEDBY changed="true">MAXIMO</max:REPORTEDBY>    </max:SR>  </max:MXSRSet></max:CreateMXSR>',
          method: 'POST'
        }, function (err, resp, body) {
          var ticketidindex = body.search('</TICKETID');
          console.log(body.substring(ticketidindex,ticketidindex-4));
          var ticketid =body.substring(ticketidindex,ticketidindex-4);
          if(resp.body.includes('500')){
          data.output.text[0]=data.output.text[0] +' but there was an error, try with fleet assets e.g 444165';
         return res.json(updateMessage(payload, data));        }
        else{
      data.output.text[0]=data.output.text[0] +' and SR is'+ticketid;
  return res.json(updateMessage(payload, data));
===========================================================================

The bold one’s are the app.post response, we are making our post call wait for the callback response else you won’t be able to show the result to user in a synchronous way.
So here you have to show a synchronous response to user in an asynchronous way.

Whenever you make changes, you can push your changes by
> npm rebuild
> cf push

Similarly you can stop the request any where and on any keyword you want and make REST calls or web service calls and later return the response conditionally from the callbacks.

This will be the end of the tutorial, so today you saw how you can call custom REST calls from the conversation API of IBM Watson platform, we will be adding the discovery service support to it soon. Stay tuned.

Keep Reading !

Action Item :  Subscribe and Share!

1 comment: