Can't update dialog node in watson conversation service via node-red - ibm-cloud

In node-red in ibm cloud. I am able to use the IBM Watson node "assistant workspace manager" to retrieve a particular dialog node. However, I am unable to use the same "assistant workspace manager" to update a dialog node. I keep getting the error message "Invalid Request Body".
It is not a matter of incorrect credentials, because I use the same credentials for both instances.
Below is the code in my functions module that passes the information to my "assistant workspace manager" node so that it can update a dialog node in my watson conversation workspace.
var uptime = msg.payload[1].d.uptime;
var message = "Server uptime is " + uptime + " seconds.";
msg.topic = "";
msg.dialog_node.output.generic[0].values[0].text = message;
msg.payload = msg.dialog_node;
return msg;
I literally took the dialog node that was returned to me and combined it with the message that had the info I wanted to inject, then modified the payload (before attempting to update my dialog node) so that the payload looked exactly like the dialog node that was returned to me (except with the text for the message modified).
I have successfully done this in the past, by manually formatting the msg.payload object similar to the format that it is returned in. I tried that also, but when that didn't work, I attempted this method.
Any advice would be appreciated.
Thanks in Advance.

This is because the underlying Node.JS SDK for watson-developer-cloud has been updated. https://cloud.ibm.com/apidocs/assistant?code=node#update-dialog-node
The JSON that you supply needs to have at least one field with a new_ prefix as a key.
So in this example the condition is being updated:
{
"type":"standard",
"title":"Entry Point For Up Down Commands",
"output":{},
"context":
{
"appl_action":"increase"
},
"next_step":
{
"behavior":"jump_to",
"selector":"condition",
"dialog_node":"node_11_1467233013716"
},
"new_conditions":"#turn_up",
"dialog_node":"Entry Point For Up Down Commands",
"previous_sibling":"node_1_1487022155950"
}
I need to amend the node info tab with this information.

Related

Getting response from API - DialogFlow Chatbot

I am creating a chatbot using DialogFlow. Here, I am trying to get response from the API, which has been created by my development team (using python). They provided the API URL and requested to fetch data from it according to the users query. I have created a function in the inline editor and pasted the given API URL.
Below is the API format they have created,
{
“data”: [{
“pincode”: “”,
“location_formatted_address”: “”,
“user_id”: “”,
“department_name”: “Education”,
“locality”: “”,
“status”: “Select_Status”
}]
}
Here, when a user gives a department name, it must respond the user with locality of that specific department.
In the Inline editor, I have applied the following logic to fetch the locality,
function getDatafromApI(agent){
const name = agent.parameters.name;
return getAPIData().then(res => {
res.data.map(issues => {
if(issues.department_name === name)
agent.add(`${name}. ${issues.locality}`);
intentMap.set('Fetch API', APIData);
In the above code, "name" is the parameter given in the intent section.
But, I am not getting any response. Any help?
The inline editor uses Firebase. You will have to upgrade to Firebase "Blaze" OR "Flame" plan as the "Spark"(free) plan does not allow external api calls.
However if you have already upgraded Firebase plan and still seeing this error, you can see the execution logs by clicking "view execution logs" link at bottom of Dialogflow fulfillment window.

Watson Assistant API V2 "manages the context automatically" - more details?

This is a question about Watson Assistant API V1/V2 difference. The doc says like this:
Note that if your app uses the v1 API, it communicates directly with the dialog skill, bypassing the orchestration and state-management capabilities of the assistant. This means that your application is responsible for maintaining state information. This is done using the context, an object that is passed back and forth between your application and the Watson Assistant service. Your application must maintain the context by saving the context received with each response and sending it back to the service with each new message request.
An application using the v2 API can also use the context to access and store persistent information, but the context is maintained automatically (on a per-session basis) by the assistant.
It seems that in V2, "the context is maintained automatically by the assistant". What does this mean exactly ? If I'd like to pass some data to the dialog flow, I might use context on "/message". Is is allowed in V2?( yes, it seems.) Then in V1 days, I have to receive context from responses and send it back on every request. Does assistant also send the context back in V2? What should my client-app do in V2? Any detailed info is welcomed ..Thanks.
Answering your second question first - If you check the API docs for Watson Assistant V2 here, there is a MessageContext object in the response with Global Context and skill specific context values.
You also have a sample Request where you can manually pass the context (both global and user-defined)
curl -u "apikey:{apikey}" -X POST -H "Content-Type:application/json" -d "{\"input\": {\"text\": \"Hello\"}, \"context\": {\"global\": {\"system\": {\"user_id\": \"my_user_id\"}}}}" "https://gateway.watsonplatform.net/conversation/api/v2/assistants/{assistant_id}/sessions/{session_id}/message?version=2018-11-08"
From the client side, you can use this code
service.message({
assistant_id: '{assistant_id}',
session_id: '{session_id}',
input: {
'message_type': 'text',
'text': 'Hello'
},
context: {
'global': {
'system': {
'user_id': 'my_user_id'
}
},
"skills": {
"main skill": {
"user_defined": {
"my_result_variable": "result_value"
}
}
}
}
}
Reference link
Check the API Methods Summary to understand what is supported in V2 as of today.
There is a new concept in V2 called Session. A session is used to send user input to a skill and receive responses. It also maintains the state of the conversation which is Context automatically for you.
V2 API as of today supports Runtime Methods, methods that enable a client application to interact with (but not modify) an existing assistant or skill. You can use these methods to develop a user-facing client that can be deployed for production use, an application that brokers communication between an assistant and another service (such as a chat service or back-end system), or a testing application.
The complete cURL example that works for me
curl -u "apikey:<API_KEY>" -X POST -H "Content-Type:application/json" -d "{
\"input\": {
\"text\": \"What's the time?\",
\"options\": {
\"alternate_intents\": true,
\"debug\": true,\"return_context\": true
}
},
\"context\": {
\"global\": {
\"system\": {
\"user_id\": \"derp\",\"turn_count\":1
}
}
},
\"skills\": {
\"main_skill\":{\"user_defined\": {
\"chosen_service\": \"dental\"
}}
}
}" "https://gateway.watsonplatform.net/assistant/api/v2/assistants/{ASSISTANT_ID}/sessions/{SESSION_ID}/message?version=2018-11-08"
for session ID, run this command
curl -u "apikey:<API_KEY>" -X POST "https://gateway.watsonplatform.net/assistant/api/v2/assistants/{ASSISTANT_ID}/sessions?version=2018-11-08"
The response includes user_defined skill context
{"output":{"generic":[{"response_type":"text","text":"Hey ! how are you today? Let me know if you need any help or get stuck looking for information."}],"debug":{"nodes_visited":[{"dialog_node":"node_6_1475611948267","title":null,"conditions":"conversation_start"}],"log_messages":[],"branch_exited":true,"branch_exited_reason":"completed"},"intents":[{"intent":"General_Greetings","confidence":0.32179955244064334},{"intent":"General_Jokes","confidence":0.296911633014679},{"intent":"goodbye","confidence":0.2852578103542328},{"intent":"General_Ending","confidence":0.2513303637504578},{"intent":"off_topic","confidence":0.24435781836509707},{"intent":"select_detail","confidence":0.24206179082393647},{"intent":"list_options","confidence":0.22829059958457948},{"intent":"still-here","confidence":0.22606439888477325},{"intent":"select_service","confidence":0.22488142400979996},{"intent":"General_Security_Assurance","confidence":0.2210852071642876}],"entities":[]},"context":{"global":{"system":{"turn_count":1,"user_id":"derp"}},"skills":{"main skill":{"user_defined":{"chosen_service":"dental"}}}}}
Thanks, #Vidyasagar Machupalli #data_henrik.
(I created "answer" section to paste the images below .)
1) Now it worked fine. I set the variable reference in dialog editor like this.
Then I post user-variable in context like this.
context={
"skills": {
"main skill": {
"user_defined": {
"myname": "ishida"
}
}
}
}
then the response was:
{'output': {'generic': [{'response_type': 'text', 'text': 'Hi, ishida .'}], 'intents': [], 'entities': []}}
It seems that "skills"->"main skill"->"user_defined" section is a case-sensitive / FIXED keyword.
From what I see, if I change one of them, I cannot read the variable on dialog editor.
2) I also found the documentation issue. The starting point of my question was : "API V2 doc says that I should use "skills" entry to handle the user variables, but no detailed info more than that .. ". #Vidyasagar Machupalli says "As per the V2 API documentation, user_defined is arbitrary variables ".. but I cannot find the paragraph in the API doc.
Then I found that
a) when I select "curl" tab, "user_defined" explanation appears.
b) when I select other(Java/Node/Python) tab, no explanation appears.
I knew that the info was not there as I refered the "Python" tab. I'd appreciate this be fixed soon to avoid same confusion. And I think that the fact of "skills->main skill->user_defined section is a case-sensitive / FIXED keyword" should be noted, as it is not clear in the current description. Thanks!

watson chatbot dialog flow not hitting child node

Please take a look at the images. The response that I am getting on IBM UI side is not showing in the Java console. It is empty or null, but the intent is hit correctly.
I am developing a chatbot using the java watson conversation api, but I am facing an error while hitting the child node. Is it a context issue or something else? I am not able to figure it out. I attached the code.
Please help.
input_gui is user input
MessageRequest newMessage = new
MessageRequest.Builder().inputText(input_gui).context(context).build();
MessageResponse response = conversationService.message(workspaceId, newMessage).execute();
newMessage = new MessageRequest.Builder()
.inputText(input_gui)
.context(response.getContext()) // output context from the first message
.build();
System.out.println("watson response"+response);
Please look at image i am attaching. This image is .......
Here is working code I got my error I called service credential every time so context get initialize on every input message that why I am not able to get single conversation id in conversation now it's working
MessageRequest newMessage = new MessageRequest.Builder().inputText(input).context(context).build();
MessageResponse response = service.message(WORKSPACE_ID,newMessage).execute();
context = response.getContext();
System.out.println(response);
I'm not one expert in Java but, trying to help you, check the Java SDK examples for Watson Conversation. You can check out this project from IBM Developers, they are using Conversation Service with Java.
See the code that I did a few months ago for one test:
MessageRequest.Builder messageRequestBuilder = new MessageRequest.Builder();
messageRequestBuilder.inputText(input_gui);
messageRequestBuilder.context(question.context); //this context comes from a previous step
ServiceCall<MessageResponse> response = conversationService.message(workspaceId, messageRequestBuilder.build());
MessageResponse mAnswer = response.execute();
Object textObject = mAnswer.getOutput().get("text");

How to give personalised greeting in Watson Conversation?

While Defining the Dialog in the Watson Conversation I'm not able to greet user with his/her name or I'm not able to detect contact number sent by the user and rephrase it to the user. Is it possible to do it in the Watson Conversation Api or not.
Although Mitch's response is correct, here is an example of doing a personalised response.
1. Set your conversation_start node text to "Hello <? context.username ?>".
2. In your code you would do something like this (Python).
import json
from watson_developer_cloud import ConversationV1
conversation = ConversationV1(
username='SERVICE_USERNAME',
password='SERVICE_PASSWORD',
version='2016-07-11')
workspace_id = 'WORKSPACE_ID_CONVERSATION'
response = conversation.message(workspace_id=workspace_id, context= {'username':'Simon'})
print json.dumps(response)
3. When you run this, it should output the following, with the "text" part being what the user sees.
{
"entities":[],
"intents":[],
"output":{
"log_messages":[],
"nodes_visited":["node_1_1472298724972],
"text":["Hello Simon"]
},
"context":{
"username":"Simon",
"conversation_id":"9dc1501b-ac53-4b51-a299-37f5314ebf89",
"system":{
"dialog_turn_counter":1,
"dialog_stack":["root"],
"dialog_request_counter":1
}
},
"input":{}
}
One thing to be aware is that, the context object is used to maintain the state of the conversation. So if you plan to use just REST API's then you need to merge your context variables into the preceding context object before sending it. You do only need to do this at points where you do know the conversation needs that context.
Do you already have access to this information? You can send these values through as context, and refer to them using $context_variable
The same goes for collecting information from a user. You can capture things using regular expressions via your application, or using some Spring Expressions, you can see the text.matches here:
https://www.ibm.com/watson/developercloud/doc/conversation/dialog_reference.shtml
You would store this as context, and then refer to it using $context_variable again.
Information like names and phone numbers is quite open ended, so can be difficult to capture without using an open entity extraction engine, which we are researching best ways to incorporate this.
To get the user's input, use:
"context": {"yourVariable": "<?input.text?>"}
And to show:
"output": {"text": "You entered this $yourVariable"}

IoT Phone recipe connects but not sending data

I am working with Bluemix tutorial recipe "Real Time Data Analysis Using IBM Watson IoT Platform Analytics" presented here:
https://developer.ibm.com/recipes/tutorials/real-time-data-analysis-using-ibm-watson-iot-platform-analytics
I am not seeing the behavior in my Watson IoT dashboard as described; the phone device does connect and register itself but I see no events or data.
In the node server logs a couple things seem concerning:
404 on fetch of util.js; in fact that file is not in my code repository downloaded from the recipe's github.
Three deprecated warnings:
...deprecated multipart: use parser (multiparty, busboy, formidable) npm module instead at node_modules/express/node_modules/connect/lib/middleware/bodyParser.js:56:20
...deprecated limit: Restrict request size at location of read at node_modules/express/node_modules/connect/lib/middleware/multipart.js:86:15
...deprecated methodOverride: use method-override npm module instead at app.js:63:17
The phone device shows some fluttering data values but stays in state "connecting". On the WatsonIoT dashboard it shows registered but "Disconnected".
Is the missing util.js a fatal condition? If not then how next to troubleshoot it as I am new to the whole package?
Solved. The recipe checks for whether it needs to create its cloudant database, unaware that I'm sharing my cloudant service instance with other apps; it finds a db exists, blithely assumes that's the one it needs, and skips the create. Change app.js from:
cloudant.db.list(function(err, all_dbs) {
if (all_dbs.length == 0) {
// first time -- need to create the iotzone-devices database
cloudant.db.create('device_credentials', function()
to e.g.:
cloudant.db.list(function(err, all_dbs) {
if (all_dbs.indexOf(dbName) < 0) {
// first time -- need to create the iotzone-devices database
cloudant.db.create(dbName, function()
[etc...]
With the db in place, WatsonIoT accepts events coming from phone and shows the data as expected.
I found this by following the print statements in log.