watson-developer-cloud / botkit-middleware

A middleware to connect Watson Conversation Service to different chat channels using Botkit
https://www.npmjs.com/package/botkit-middleware-watson
Apache License 2.0
206 stars 254 forks source link

Context Variable #126

Closed BlueRoyy closed 6 years ago

BlueRoyy commented 6 years ago

In my dialog I have a webhook which takes a user input and returns output to context variable. In watson testing the output show correctly but when using both slack and facebook integration the variable name $PollingStation.msg is returned instead of the value.

Naktibalda commented 6 years ago

It looks like an issue of Watson Conversation itself to me.

BlueRoyy commented 6 years ago

How so? It works there. It also works with the Wordpress plugin on our site. I believe I'm not doing the right things. My question is how does middleware resolve variables. Should I be using something different than message.watsonData.output.text for returning the value of context variable?

Naktibalda commented 6 years ago

Middleware doesn't play part in that. Variables are already resolved in output.text.

Naktibalda commented 6 years ago

Is version_date parameter specified in your constructor call of middleware? Example here Are you using a recent version of middleware?

BlueRoyy commented 6 years ago

Yes I have version date declared version_date: '2017-05-26'. and just in case "botkit-middleware-watson": "^1.7.1"

BlueRoyy commented 6 years ago

Am I the only one experiencing this issue?

BlueRoyy commented 6 years ago

Here's some more context: User asks for info (parent node); Follow up asks users for input and declares context.PollingStation as a result variable (child node) according to instructions here https://console.bluemix.net/docs/services/conversation/dialog-actions.html#create-action. Then I call cloud function and return the response {msg:output} to the result variable such that the output is not in $PollingStation.msg . In subsequent child node I display the response once an error hasn't occurred. The response has some HTML in it. When I test in Watson, I see the response with the html tags. On our website I see the response as it should look. Using botkit middleware its as if there isn't a $PollingStation.msg and $PollingStation is empty

mitchmason commented 6 years ago

you have the callout type set to server correct?

pgoldweic commented 6 years ago

I've just noticed this question by @BlueRoyy from earlier: Should I be using something different than message.watsonData.output.text for returning the value of context variable? I believe this answer is YES. (disclaimer: I have not used cloud functions though - my bot app executes actions itself and then returns updated context back to Watson via sendToWatsonAsync, as described in the readme file for this middleware), According to my understanding, the value of a context variable would not be set within watsonData.output.text. When setting a value within Conversation service itself, context variables are always stored within 'context' and not the 'output' fields . This would therefore suggest watsonData.context instead of watsonData.output.text (unless you are specifically indicating in your programmatic call the fact that you want the results to be part of the 'input' or 'output' part of the messages, instead of being in the context. In this last scenario, I imagine that context variables in the conversation service would then not be set - just from reading the docs in the url you linked -).

BlueRoyy commented 6 years ago

@mitchmason yes I do. watsconv

BlueRoyy commented 6 years ago

@pgoldweic I'll give the watsonData.context a try

BlueRoyy commented 6 years ago

No luck so far. So i set up locally and here is the output from the log.

Fatal TypeError: Cannot read property 'output' of undefined at Object. (C:\Users\KRoach.ELECT\Desktop\electbot\bot-slack.js:25:41) at Object. (C:\Users\KRoach.ELECT\Desktop\electbot\node_modules\botkit\lib\CoreBot.js:753:28) at Object.Botkit.botkit.trigger (C:\Users\KRoach.ELECT\Desktop\electbot\node_modules\botkit\lib\CoreBot.js:779:49) at Object. (C:\Users\KRoach.ELECT\Desktop\electbot\node_modules\botkit\lib\SlackBot.js:589:34) at Object.Botkit.botkit.trigger (C:\Users\KRoach.ELECT\Desktop\electbot\node_modules\botkit\lib\CoreBot.js:779:49) at C:\Users\KRoach.ELECT\Desktop\electbot\node_modules\botkit\lib\CoreBot.js:866:32 at Object.bot.findConversation (C:\Users\KRoach.ELECT\Desktop\electbot\node_modules\botkit\lib\Slackbot_worker.js:594:9) at C:\Users\KRoach.ELECT\Desktop\electbot\node_modules\botkit\lib\CoreBot.js:862:21 at next (C:\Users\KRoach.ELECT\Desktop\electbot\node_modules\ware\lib\index.js:82:27) at C:\Users\KRoach.ELECT\Desktop\electbot\node_modules\wrap-fn\index.js:121:18 at C:\Users\KRoach.ELECT\Desktop\electbot\node_modules\botkit-middleware-watson\lib\middleware\index.js:128:9 at tryCatcher (C:\Users\KRoach.ELECT\Desktop\electbot\node_modules\bluebird\js\release\util.js:16:23) at Promise._settlePromiseFromHandler (C:\Users\KRoach.ELECT\Desktop\electbot\node_modules\bluebird\js\release\promise.js:512:31) at Promise._settlePromise (C:\Users\KRoach.ELECT\Desktop\electbot\node_modules\bluebird\js\release\promise.js:569:18) at Promise._settlePromise0 (C:\Users\KRoach.ELECT\Desktop\electbot\node_modules\bluebird\js\release\promise.js:614:10) at Promise._settlePromises (C:\Users\KRoach.ELECT\Desktop\electbot\node_modules\bluebird\js\release\promise.js:693:18) npm ERR! code ELIFECYCLE npm ERR! errno 2 npm ERR! botkit-middleware-watson-multi-bot-example@0.0.1 start: node server.js npm ERR! Exit status 2 npm ERR! npm ERR! Failed at the botkit-middleware-watson-multi-bot-example@0.0.1 start script. npm ERR! This is probably not a problem with npm. There is likely additional logging output above.

For whatever reason the botkit middleware has the context variable $PollingStation as being undefined therefore the it can't read the property 'output' returned in the promise. Since there doesn't appear to be a solution for this Ifiure my best bet is to detect the user input in the middleware.before, make the call to the webhook directly, and then send back the response to the conversation.

Naktibalda commented 6 years ago

You have to check message.watsonError before using message.watsonData.

Please look at this update: https://github.com/watson-developer-cloud/botkit-middleware/pull/127/files

mitchmason commented 6 years ago

why do you have it defined as context.PollingStation ? If it works in tryout panel I have to assume thats acceptable, but Ive always done $PollingStation or <? context.PollingStation ?> But if its working in the tryoutpanel those shouldnt make a difference, really botkit is sending the API, its seeing the action, doing the action, and returning a response after all of it, so botkit should have no part in it.

BlueRoyy commented 6 years ago

@Naktibalda and @mitchmason I took both your advice in using $PollingStation as well as message.watsonError. It didn't immediately show anything so I switched and started analyzing the output from the message object and as it turns out the actions array is empty and there is an error about not recognizing the credentials. As you can see from the pic I uploaded my credentials are inside my actions array and I defined them on my welcome node to make sure that they can be referenced in any subsequent node. What do I check next? Do credentials have to be defined a different way from Node? Do they have to be submitted along with message object even though they are in WatsonConversation?

BlueRoyy commented 6 years ago

{ type: 'message', channel: 'D8S52291R', user: 'U8MH99T25', text: '8301180017', ts: '1518203519.000114', source_team: 'T8MRVN7JN', team: 'T8MRVN7JN', watsonData: { intents: [], entities: [ [Object] ], input: { text: '8301180017' }, output: { text: [], nodes_visited: [Array], error: 'Mandatory action property "credentials" missing or invalid for server-side Cloud Functions action call. The value must be a string that references a variable such as "$my_creds" that expands to an object like {"user":"..", "password":".."}. Dialog node: [follow up polling station] (and there are 3 more errors in the log)', log_messages: [Array] }, context: { conversation_id: '9b9b5d41-5597-484f-8a84-49b08e5a3250', system: [Object], nat_reg_number: 'nat_reg_number' }, actions: [] }, event: 'direct_message', match: [ '8301180017', index: 0, input: '8301180017' ] }

BlueRoyy commented 6 years ago

The issue is a scope problem with javascript. And let me be first to apologize. It was not a botkit issue. The credentials as a context variable seem to have limited scope of parent and children nodes (and maybe grandchildren). I got it fixed thanks a lot for your assistance.

germanattanasio commented 6 years ago

Closing, but please re-open if it still occurs.

Sandhyakripalani commented 6 years ago

@BlueRoyy im facing a similar problem with Java. Can you please tell me how you had solved this?

BlueRoyy commented 6 years ago

I had to define the credentials in the parent of the node I made the call to the function. E.g. If the user asked for their registration info. My parent node would ask the user for a number, then my child node would call the external function using the user's number and return the result to the user. I had to define my credentials the same time I asked the user for the number. If I defined it before the parent-child branch (like my welcome node at the beginning) it would work in Watson Conversation but not elsewhere since it was like defining a local variable in one function and trying to call it from another. And of course you can't create the variable in the same node that you make the call to the external function since it would be undefined.

Sandhyakripalani commented 6 years ago

Thanks @BlueRoyy. But what if my parent node makes a call to the function and does not need any info from the user. Let's say the intent is identified and is good enough to make the call. The context variable i am passing is credential needed for the IBM cloud fucntion call. image In the above screenshot, CaseList is the parent node and makes the call to the function

Sandhyakripalani commented 6 years ago

I have also tried creating a child node that makes a call.

image

Still unable to resolve the issue.

BlueRoyy commented 6 years ago

What you can try is passing your username and password through the code using $private.mycred. Otherwise like @pgoldweic said you may have to make the calls directly from the code and update the context with Watson

Sandhyakripalani commented 6 years ago

To connect to the IBM function itself,the credentials need to be present. That is where it is failing. It does not find the context variable and so it is not able to reach the function code itself. I am sure im doing something wrong and unable to figure out what. When i print the response ( MessageResponse in the java-sdk), i can see context set. But somehow Watson fails to read it.

"context": { "mycred": "{\"user\":\"xxxxxxxx\",\"password\":\"yyyyyyyy\"}", "system": { "dialog_stack": [ { "dialog_node": "root" } ], "dialog_turn_counter": 3.0, "dialog_request_counter": 3.0, "_node_output_map": { "Welcome": [ 0.0 ], "node_10_1528962431602": [ 0.0, 0.0 ], "node_13_1528962490659": [ 0.0, 0.0 ], "node_1_1528822165222": [ 0.0 ] }, "branch_exited": true, "branch_exited_reason": "fallback" }, "conversation_id": "16a3b2e5-f221-474a-b233-504b024888a6" }

Zakria999 commented 4 years ago

Hello Beautiful People!!! I am continuously getting an error (Invalid )whenever i try to write $name or $city in my context variable. Urgent help is needed.

luigimorel commented 2 years ago

@Zakria999 are you still continously getting the error? 😏