3

I know this may seem complicated but I have spent a week and a half trying to do this and can not figure it out. Hopefully someone can point me in the right direction. Thank you so much!

I am working with IBM Watson and Node.js to create a conversation bot. I have created the bot and used one of IBM's example programs (Conversation-Simple) to make a website to interact with the bot. Everything with it works. I am now trying to use Watson's Discovery to search documents and answer a question with the query response. I have Discovery working where you can query it and have a Node.js program to query it.

I am now trying to connect the two! When Conversation is ready to query Discovery it will move to the intent called query.

It looks like this is where Watson gives the response and the variable of the response is currentText. I could be wrong but it looks like it is.

  function buildMessageDomElements(newPayload, isUser) {
    var textArray = isUser ? newPayload.input.text : newPayload.output.text;
    if (Object.prototype.toString.call( textArray ) !== '[object Array]') {
      textArray = [textArray];
    }
    var messageArray = [];

    textArray.forEach(function(currentText) {
      if (currentText) {
        var messageJson = {
          // <div class='segments'>
          'tagName': 'div',
          'classNames': ['segments'],
          'children': [{
            // <div class='from-user/from-watson latest'>
            'tagName': 'div',
            'classNames': [(isUser ? 'from-user' : 'from-watson'), 'latest', ((messageArray.length === 0) ? 'top' : 'sub')],
            'children': [{
              // <div class='message-inner'>
              'tagName': 'div',
              'classNames': ['message-inner'],
              'children': [{
                // <p>{messageText}</p>
                'tagName': 'p',
                'text': currentText
              }]
            }]
          }]
        };
        messageArray.push(Common.buildDomElement(messageJson));
      }
    });

    return messageArray;
  }

When it goes to respond here (or if it is somewhere else) how can I check if the intent is query and if it is query Watson Discovery?

This is how I currently query Discovery:

url2 = 'fakeURL'

var request = require("request");
var myJSON = require("JSON");
global var body1;
function getMyBody(url, callback) {
  request(
  {
    url: url,
    auth: {'user': 'fakeUsername','pass': 'fakePassword'},
    json: true
  },
  function (error, response, body) {
    if (error || response.statusCode !== 200) {
      return callback(error || {statusCode: response.statusCode});
    }
    else{
      callback(null, JSON.parse(JSON.stringify(body.results)));
    }
  });
}

getMyBody(url2, function test8(err, body) {
    body1 = body[0];
    console.log(body1)
  }
);

This code currently prints:

{ id: 'a3990d05fee380f8d0e9b99fa87188a7',
    score: 1.0697575,
    os: { OperatingSystem: 'Windows 10 Professional' },
    price: '174.99',
    text: 'Lenovo ThinkCentre M58 Business Desktop Computer, Intel Core 2 Duo 30 GHz Processor, 8GB RAM, 2TB Hard Drive, DVD, VGA, Display Port, RJ45, Windows 10 Professional (Certified Refurbished)',
    url: 'https://www.amazon.com/Lenovo-ThinkCentre-M58-Professional-Refurbished/dp/B01M4MD9C1?SubscriptionId=AKIAJXXNMXU323WLP4SQ&tag=creek0a-20&linkCode=xm2&camp=2025&creative=165953&creativeASIN=B01M4MD9C1',
    highlight: { text: [Array] } }

The response to the user I want to be the value of text and the value of URL.

This is the whole program from IBM https://github.com/watson-developer-cloud/conversation-simple

Sayuri Mizuguchi
  • 5,250
  • 3
  • 26
  • 53
James
  • 1,928
  • 3
  • 13
  • 30

1 Answers1

1

Like this example from IBM Developers: conversation-with-discovery. You can follow the same logic programming. But I really recommend check out the project and the video in the end of this answer.

Summary:

You can see in the workspace, the call for discovery is one action variable inside the Advanced JSON (Dialog node) called call_discovery.

"action":{"call_discovery: ""},

Basically, have one intent with the name out_of_scope, because if the user tells something that doesn't have any answer in the intents or some conditions in the Conversation, the call for discovery will happen and return one object with the documents according to the message from user.

Create one context variable inside the Conversation service:

{
  "context": {
    "callDiscovery": true
  },
  "output": {
    "text": {
      "values": [
        "Wait for the response, I'll check out."
      ],
      "selection_policy": "sequential"
    }
  }
}

After creates one context variable (Example: "callDiscovery": true) inside the Node in your Chatbot in the Advanced JSON for call the discovery service, you need to use code for identify if you arrived at the part where you need to make call for Discovery. Will be something like using the function updateMessage inside the conversation-simple example:

function updateMessage(input, response) {
  var callDiscovery ;
  if (!response.output) {
    response.output = {};

    //THE CONTEXT VARIABLE callDiscovery
  } else if (response.context.callDiscovery === true){
      //CREATE ONE NEW FUNCTION WITH YOUR CODE
      getMyBody(url, callback, response); //response parameter for send the message
    }
}

And, in your function getMyBody (THE FUNCTION that returns the prints in your Question[id, text, url, etc]), you need to send the message to the user, something like:

url2 = 'fakeURL'

var request = require("request");
var myJSON = require("JSON");
var body1;
function getMyBody(url, callback, response) {
  request(
  {
    url: url,
    auth: {'user': 'fakeUsername','pass': 'fakePassword'},
    json: true
  },
  function (error, response, body) {
    if (error || response.statusCode !== 200) {
      return callback(error || {statusCode: response.statusCode});
    }
    else{
      callback(null, JSON.parse(JSON.stringify(body.results)));
    }
  });
}

getMyBody(url2, function test8(err, body) {
    body1 = body[0];
    console.log(body1);
    var sendMessage = ("I've find this results: "+ body1.text + "And you can see the url: "+ body1.url)// you said body1.text and body1.url
    response.output.text[0] = sendMessage;
    return res.json(response);  
  });   

}

Note: According to the project conversation-simple, you need to use the response parameter for sending the message for the user, then, you need to set the parameter in your function that calls for Discovery, and to add the following code above in your function.

  • See the Official video by IBM Watson talking about this project and showing one good example to call the Discovery service and sends the result for the user.
Sayuri Mizuguchi
  • 5,250
  • 3
  • 26
  • 53
  • So I was trying to use that project but had trouble calling "call_discovery". How do I call that in the dialog of conversation? Thanks so much for your help too! – James Sep 10 '17 at 22:21
  • You need to create one context variable inside the Watson conversation, in the dialog node that you want to call to discovery service and returns the text queried – Sayuri Mizuguchi Sep 10 '17 at 22:23
  • Do I call it `call_discovery`? – James Sep 10 '17 at 22:26
  • Yes, like my example with the code above. But you need to [create](https://stackoverflow.com/questions/43187373/how-to-extract-current-date-in-watson-conversation/43190215#43190215) in the Conversation service in your Dialog chatbot, and when you code to find the context variable, will call the function with your code. – Sayuri Mizuguchi Sep 10 '17 at 22:37
  • So what would I put in the callDiscovery function? I am assuming something similar to the code I had? – James Sep 10 '17 at 22:37
  • I would like to make it work with the conversation-simple one since I have already edited a lot of it. – James Sep 10 '17 at 22:38
  • I wish I could do more than mark your answer as correct too. You are SO helpful! I will mark it once I figure out what to do! – James Sep 10 '17 at 22:39
  • Yes, is your code. But you need to identify inside your chatbot creating one context variable called `callDiscovery` set to `true`, like my example in the link above. and you will identify with my code in my answer: `response.context.callDiscovery` for calling your function that returns the query and send the message with my last code above. – Sayuri Mizuguchi Sep 10 '17 at 22:50
  • but what do I put in the queryDiscovery function? – James Sep 10 '17 at 22:51
  • I did edit. Please, you need to follow the logic to understand, but try to watch the video and take a look in the project by IBM to understand better. – Sayuri Mizuguchi Sep 10 '17 at 23:04
  • Try to delete the global name. Like my edit.... and debugg your code slowly. If you have some doubt create one new ask with the error and your code. – Sayuri Mizuguchi Sep 10 '17 at 23:13
  • Let us [continue this discussion in chat](http://chat.stackoverflow.com/rooms/154089/discussion-between-brendan-and-sayuri-mizuguchi). – James Sep 10 '17 at 23:13
  • Do you think you can help with this? Thanks so much! https://stackoverflow.com/questions/46268101/change-html-attribute-from-node-js – James Sep 17 '17 at 19:47