I'm building a chatbot on Telegram with Watson Assistant and Node RED. I need to take a date and time from the user for booking an appointment, so I used a slot that require the insertion of the two information. Using the trial chatbot offered by Watson, I have no problem with slot; but using Node RED, I can't go beyond entering the date. Through the debug, I saw that after entering the date, then after running the first slot, this error is returned "msg.payload.content is empty". Moreover, going to see the body of the output message returned by the assistant, the msg.payload.output.generic field is empty. On the other hand, it should contain the response of the assistant who requests, after having entered the date, also to insert the time. It seems that the bot is stuck on entering the date, but in reality I don't think so, because in the trial chatbot, it works perfectly.
What could be the problem?
Neither the Assistant V1 nor the V2 set or look at msg.payload.content. On input they look at msg.payload and on exit they assign the response from Watson Assistant to msg.payload.
If you are getting a "msg.payload.content" is empty error, then that will be happening somewhere in your flow. Most likely at the end where you are trying to process the response. If msg.payload.content is empty then the assistant dialog is not returning any output. This is strange as it should be returning the prompt for the currently empty slot.
What does msg.payload look like?
Are you using the V1 or the V2 node, and which version of node-red-node-watson nodes are you using? You can tell, by going to the palette.
Both V1 and V2 nodes, however, have been tested with slots, and the response does end up on msg.payload.content. Current released version of node-red-node-watson is 0.9.0.
Related
Introduction:
I feel like I'm missing something terribly obvious about how Watson Assistant should be designed at an architecture level, but maybe I'm not.
The specific problem I'm having is that I can't seem to get API calls for information back into the conversation.
The bigger issue is that I'm not sure I setting this all up correctly for the long-haul of what I'm trying to accomplish.
Purpose:
I am building a 24/7 customer-service Tier 1 helpdesk for our managed networks. A user of one of our networks should, via SMS, Web chat, Facebook messenger, and eventually phone call, be able to ask for:
Instructions on how to connect their specific device (PC, Mac, Chromebook, Xbox, Apple TV, etc.)
Ask for help troubleshooting if the instructions don't result in a successful connection. (Step by step instructions for deleting the saved network, restarting the wireless card, etc.)
Help creating a case - at which point the conversation becomes Watson asking for a bunch of information, like what time and date they first experienced the problem, any other times/dates they experienced the problem, their MAC address, etc. etc.
Problems:
I have most of the dialog built and working well. Getting information via Entities, saving to context variables, spitting them back out to make the conversation work, digressions, etc. all working.
I cannot, for the life of me, figure out what I am doing wrong when trying to GET information from an external API.
We have a 'daily password' for our guest networks, and we would like a user who asks for the daily password to receive it. This involves a very simple GET request to a publicly accessible server.
I have built a BlueMix/IBM Cloud function that works perfectly, but I can't seem to successfully call or receive information back from it.
Watson Error:
Error when updating output with output of dialog node id [node_66_xxxxxxxxxx]. Node output is [{"text":{"values":["Today's password for <? $guestNetwork.ssid ?> is <? $guestNetwork.password ?>"],"selection_policy":"sequential"}}] SpEL evaluation error: Expression [ $guestNetwork.ssid ] converted to [ context['guestNetwork'].ssid ] at position 0: EL1007E: Property or field 'ssid' cannot be found on null (and there is 1 more error in the log)
This error leads me to believe I am not properly defining the result variable in Watson, or improperly trying to retrieve it in conversation - because I do know my code returns the SSID and Password when I run it in BlueMix Console.
JSON for the action itself (and yes, I am setting the credentials in the previous node):
{
"output": {
"text": {
"values": [
"Today's password for <? $guestNetwork.ssid ?> is <? $guestNetwork.psk ?>"
],
"selection_policy": "sequential"
}
},
"actions": [
{
"name": "get-http-resource/getGuestNetworkPassword",
"type": "server",
"credentials": "$private.myCredentials",
"result_variable": "$guestNetwork"
}
]
}
Question:
Is my idea of a 'serverless' Watson possible by using Watson <-> IBM Cloud <-> external services? We don't currently have an 'application' or a server, it's all integrations between existing services.
Can anyone help me understand what I'm doing wrong when trying to access that variable?
Bonus points: How do I know to access the variable only after the action has completed successfully in IBM cloud? Basically, if accessing the information via the IBM Cloud function I wrote takes 1.5 seconds, do I need to pause the dialog for 1.5 seconds? Or am I completely missing the point for how to get external info in and out of Watson?
EDIT:
After watching Mitch's video, I have changed a couple things around, and the error message has evolved to this:
"Error when updating output with output of dialog node id
[node_66_1533646714776]. Node output is [{"text":{"values":["Today's
password for is "],"selection_policy":"sequential"}}] SpEL evaluation error:
Expression [ $guestNetwork['ssid'] ] converted to [
context['guestNetwork']['ssid'] ] at position 24: EL1012E: Cannot
index into a null value" error.
Without seeing your dialog, its a guess, but most common error I see is that you just need to jump to a child dialog node after doing the action call. You cannot do the action call and show the response in the same dialog node, as dialog needs a chance to run the action.
Its outlined in my video here:
https://ibm-dte.mybluemix.net/ibm-watson-assistant?refresh
see the video on dialog callouts. Its 13 minutes long I'm sure you only need about 2 of them, but still, should help.
What you are trying to do is definitely possible, especially if it works from within the cloud function environment.
We re-created the action using the default package (not having it in a sub-package), and it started working immediately.
Things to note: Watson dialog editor does not like dashes in the package name.
Thanks Mitch!
I am making an app that predicts clothes the user is wearing. It uses the Visual Recognition tool, too, and for Conversation and VR to be communicating, I attach the intent 'suggestClothing' or 'clothResult' to the cloth items it found. I use an entity for Conversation to recognize the cloth items and respond accordingly.
The flow should be as follows:
User: how do I look?
-classifies clothes-
App to conversation: clothSuggest blackJacket
Conversation to user: "You picked the black jacket! Try out the green shirt with this outfit and show me how you look."
-classifies clothes-
App to conversation: clothResult blackJacket greenShirt
Conversation to user: "You look great in that outfit!"
All nodes have multiple responses as all clothes are in pairs. Either the user is wearing one or the other, and Conversation will then always suggest it's match.
Conversation flow looks like this
I also attempted this. Here sq123 is suggestClothing (first intent) and cq123 is clothResult:
This works fine in 'Try it out', too, but in the app, it immediately exits the branch on 'clothResult item1 item2' and matches with other conditions in the app.
What's the best way to optimize my flow to make it work in the app?
A typical reason why it works in "Try it out" and not in the app is that the context object is not returned properly.
When the app invokes the message method of the Watson Assistant API, a context object is passed. The calls are stateless and everything needed for Watson Assistant to continue a dialog is included in the context object. Thus, when your app retrieves the results from the message API, it needs to save the context and pass it back to Watson Assistant the next time the message method is invoked again (for that session and user).
In the DialogFlow console, you can set an input and output context for an intent.
I would like to have the same functionality using the Actions SDK.
Since I can set the context in my fullfilment webhook in the code, the output SDK is covered.
However, how do I set the input context for an intent to only trigger if that context was fetched?
I could not find this in the documentation examples.
I don't believe you can in the same way, which is part of why they added Dialogflow.
Although as part of your response you can indicate the ExpectedInput for the next Intent, the documentation for the ExpectedIntent makes it clear that your Intents are only used for speech biasing - you'll always get the built-in TEXT Intent.
In fact, this documentation says that you'll only get custom Intents for the initial call - later Intents are always triggered with a built-in one.
Update: One thing you can do is to include information in the response that will be sent back to you in the next request.
If you're using the JavaScript SDK, this is done with the second parameter to ask() and is available via the getDialogState() function.
If you're sending back JSON, this is done using the conversationToken attribute and is available in conversation.conversationToken in the request object you're sent the next round.
I am developing an app using wit ai and facebook messenger, everything is working as expected but I am stuck on a expression which is always returning wrong role.
I have added similar expression for that intent but when I test the same sentence it returns wrong role. Please see screenshot attached
Below image shows that expression is properly validated, here mumbai is recognized as wit/location:origin
But When I test the same expression, it only returns location against mumbai rather than location:origin..
Any help ?
I checked and your training was stuck for some reason. I just restart it manually and it works now.
Training Status Icon
I just recently started working with the PayPal API to start processing credit cards for a client and have run into an odd issue. I managed to get everything mostly working (the 400 Bad Request error that is all over SO is still outstanding for me) minus one thing. When I try to run a CC against the sandbox area with nothing specified for line 2 of the address I see the following error get logged:
Error Response: {"name":"VALIDATION_ERROR","details":[{"field":"payer.funding_instruments[0].credit_card.billing_address.line2","issue":"Must not be blank"}],"message":"Invalid request - see details","information_link":"https://developer.paypal.com/webapps/developer/docs/api/#VALIDATION_ERROR","debug_id":"cbaa2c4dfdb77"}
Why would address 2 be required? Their own documentation (https://developer.paypal.com/webapps/developer/docs/api/) says it isn't so I'm completely lost here.
This is using the RestAPISDK library downloaded from their GitHub instance and everything I'm doing is in C#.
When you have a blank value in a REST API call it will return an error. It isn't required to provide a line2 value but if you include the variable with a blank value the system will flip out. Remove the variable entirely and you should be good to go.