IBM Cloud Functions printing API response in Watson Assistant / node.js / json - node.js

With IBM cloud functions I am calling two Joke APIs. The first one gives me these results:
Results:
{
"response": {
"body": {
"body": [
{
"_id": "5f80ccd641785ba7c7d27bc0",
"punchline": "They always egg-cercise!",
"setup": "How do hens stay fit?",
"type": "general"
}
],
"success": true
},
I want to print the punchline and setup in Watson assistant so I tried this code:
$webhook_result_1.response.body.body.setup and $webhook_result_1.response.body.body.punchline but both gives me an error. When I use $webhook_result_1.response.body.body I get this:
[{"_id":"5f80ccd641785ba7c7d27c07","punchline":"A JOKE MACHINE!?","setup":"What do I look like?","type":"general"}]
So I guess I am on the right way. What am I doing wrong?
—
This is the response for the second joke API:
Results:
{
"response": [
{
"id": 299,
"punchline": "The meat-ball.",
"setup": "Where do hamburgers go to dance?",
"type": "general"
}
]
}
And I tried this: $webhook_result_2.response.punchline but it is not working as well.
How can I print the punchline and setup for each API?

The [] indicates an array, so you need to index it. Ideally you should check an array to see that it has at least one element, and then iterate through it, but your 1st element, if it exists, will be:
$webhook_result_1.response.body.body[0].setup
Based on the comments to your question, it appears that you are placing the opening bracket in the wrong place.

Related

I would like to add one more conversation to actions.json

I have an application within watson assistant that consumes many services from other endpoints. and I would like to call this conversation (from watson) within a google assistant conversation in a certain intention. for example i will develop a rich conversation on google assistant and in one of the options i will call watson's conversation.
I tried as follows, but it didn't work. does anyone know any example that can help me?
{"locale": "pt-BR",
"actions": [
{
"description": "Launch intent",
"name": "MAIN",
"fulfillment": {
"conversationName": "mainConversation"
},
"intent": {
"name": "actions.intent.MAIN"
}
},
{
"description": "Direct access",
"name": "BUY",
"fulfillment": {
"conversationName": "ExampleAction"
},
"intent": {
"name": "com.example.ExampleAction.BUY",
"trigger": {
"queryPatterns": [
"teste",
"azul",
"start"
]
}
}
}
],
"conversations": {
"mainConversation": {
"name": "mainConversation",
"url": "https://us-central1-ericanovo-798cc.cloudfunctions.net/webhook",
"fulfillmentApiVersion": 2
},
"BUY": {
"name": "ExampleAction",
"url": "https://orquestrador-sulamerica-teste.mybluemix.net/api/v1/chat/google?externaltoken=574213c0-e904-11e9-9970-ff484aa25334",
"fulfillmentApiVersion": 2
}
}
}
thanks
That won't work because the webhook for everything published under the same project has to be the same URL. You are expected to handle all the Intents and "actions" at that webhook.
In your case, you would also need to make sure the request is formatted the way the Watson API would be expecting it. The Assistant will send it using the Conversation Webhook Format, and it sounds like you would send it using Watson's Analyze Text API.
You're not showing any of your code, so it is difficult to be sure - but the first would be in a JSON format that you can extract. You can then use a library in Node (such as request-promise to make the calls to Watson. Based on the result from Watson, you'd need to format the results as a response and return it to the Assistant.
It isn't clear why you'd need multiple webhooks specifically, although it is certainly possible that some Intents may make different API calls than others.
Keep in mind that your custom Intents will only be valid on invocation. Subsequent Intents will all be TEXT Intents.

Sending JSON Payload to Slack via AWS Lambda

I am trying to build a Slack app by using AWS lambda and NodeJs. The issue I am facing is that I don't understand in what format does the SlackBot need the JSON payload from my AWS lambda code to display it.
I followed the tutorial video suggested on Slack linked here. In the video, the following JSON object is created and returned from the AWS lambda.
const response = {
statusCode: 200,
body: "Sample Response",
};
The SlackBot posts the text entered in the 'body' property (i.e. 'Sample Response' in this case) as a response. This seems to be working well. But, I need some more flair than simple text so I looked into their Block Kit UI builder. But there seems to be no documentation for how to do this with a similar 'response' JSON object like this. How exactly am I supposed to use the JSON object created by the UI builder?
I do not know much about Web development so sorry if this seems like a very basic question. I wish there was a sample Slack app on their website which showed this.
The following may work for you (I use a similar one on the production);
{
"channel": "your-channel-name",
"username": "channel-username",
"attachments": [
{
"title": "some-title",
"fallback": "some message",
"text": "some text",
"fields": [
{
"title": "sub-title",
"value": "sub-title-value",
"short": true
},
{
"title": "some-other-title",
"value": "some-value"
}
],
"color": "red"
}
],
"icon_emoji": "gun"
}
This link or this one may provide some extra information.

Dialogflow Fulfillment URLnot sending any data

I am building a bot for google assistant. I have enabled fulfillment section for some intents. Dialog flow sends the request to the fulfillment url. The url is executed and a hard coded response is returned. I can see the response in the assistant simulator. Everything works fine except one thing. The request is empty.I can't access fields that are supposed to be present in the request.
I have accessed the same url using post request from a python code and it displays the parameters. So, there are no issues in the code. I think I am missing some configuration option.
I was expecting the post body in the following format:
POST body:
{
"responseId": "ea3d77e8-ae27-41a4-9e1d-174bd461b68c",
"session": "projects/your-agents-project-id/agent/sessions/88d13aa8-2999-4f71-b233-39cbf3a824a0",
"queryResult": {
"queryText": "user's original query to your agent",
"parameters": {
"param": "param value"
},
"allRequiredParamsPresent": true,
"fulfillmentText": "Text defined in Dialogflow's console for the intent that was matched",
"fulfillmentMessages": [
{
"text": {
"text": [
"Text defined in Dialogflow's console for the intent that was matched"
]
}
}
],
"outputContexts": [
{
"name": "projects/your-agents-project-id/agent/sessions/88d13aa8-2999-4f71-b233-39cbf3a824a0/contexts/generic",
"lifespanCount": 5,
"parameters": {
"param": "param value"
}
}
],
"intent": {
"name": "projects/your-agents-project-id/agent/intents/29bcd7f8-f717-4261-a8fd-2d3e451b8af8",
"displayName": "Matched Intent Name"
},
"intentDetectionConfidence": 1,
"diagnosticInfo": {},
"languageCode": "en"
},
"originalDetectIntentRequest": {}
}
But when I print the post data using print(request.POST), the actual post request shown is
One more thing: Does dialog flow append the action at the end of the fulfillment url? If so, I will have to handle the logic separately. I have done it without considering the action name. But a lot of my stuff is hacked, so I just want to be sure.
On another note, is dialogflow good enough? It has worked fine on a few examples similar to what it was trained on. How many training samples does it need to work properly? What is the underlying algorithm used in dialogflow? Or should I use the fulfillment url and handle everything on my own? I am inclined towards the later. I do not have too much faith in the existing chatbots.
Any help is appreciated.
If the Fallback Intent is the one being triggered, then you wouldn't get any parameters since this means that nothing else matched.
Got it. Used request.body. This solves the problem. Then parsed it using json.loads and accessed the parameters.

Built in slot for capturing number like first, second or fifth

I am working on a skill, which asks the user for selection of an item from a particular list. Now user's most intuitive response will be to say something like first or second. But built in slots AMAZON.Number only does not capture input like first or second. Am I doing something wrong? Is it possible with some other hack?
Akshay,
AMAZON.Number is really only for numbers, where first, second and such are strings.
To do this, in the Developer console you would need to create a custom slot type called something like "positionChioces". Then enter in first, second, third, fourth, etc. Then add that slot type to your intent naming it choices, then picking "positionChioces".
This is from the JSON editor:
"types": [
{
"name": "positionChioces",
"values": [
{
"name": {
"value": "fourth"
}
},
{
"name": {
"value": "third"
}
},
{
"name": {
"value": "second"
}
},
{
"name": {
"value": "first"
}
}
]
From that point it would all depend on your code. You can pull that slot from your user then use some logic saying if response was first, it will be the fist item in your array and so on. Hope this helps.
D

Identifying numbers correctly

I have an intent where I might say 'Transfer 4 to Bob' and it identifies this as 'Transfer for to Bob'
Also I might say 'Transfer 10 to Bob and it identifies this as 'Transfer 102 Bob' treating to word to as 2 on the end of the previous number.
What is the best way to get API.AI to recognise these parts correctly so 4 is not for and to is not 2?
You mentioned that you're using the Actions on Google platform. This means that speech recognition - the process of translating what the user says into text - is happening before the data gets to API.AI.
The problem you're experiencing is that Actions on Google is misrecognizing some numbers as words, e.g. four becomes for.
Because this happens before - and separately from - API.AI, you won't be able to fix the misrecognition.
Below, I'll explain how you can work around this issue in API.AI. However, it's also worth thinking about how you could make your conversation design as robust as possible so that issues like this are less likely to cause problems.
One way you could increase robustness would be to mark the number as a required parameter in API.AI so the user is prompted if it isn't detected due to a recognition error. In that case, the dialog would go like this:
User: Give me four lattes.
App: Sure, four lattes coming up.
User: Give me for lattes.
App: How many do you want?
User: Four.
App: Sure, four lattes coming up.
Regardless, here's a workaround you can use to help recover from misrecognition:
In your intent, provide examples of these commonly misrecognized values. Highlight and mark them as numbers.
Test out your intent out in the console and you'll see that "for" is now matched as a "number" entity with value "for".
In your fulfillment webhook, check the parameter for this value and convert it to the appropriate number using a dictionary. Here's the JSON for the above query:
{
"id": "994c4e39-be49-4eae-94b0-077700ef87a3",
"timestamp": "2017-08-03T19:50:26.314Z",
"lang": "en",
"result": {
"source": "agent",
"resolvedQuery": "Get me for lattes",
"action": "",
"actionIncomplete": false,
"parameters": {
"drink": "lattes",
"number": "for" // NOTE: Convert this to "4" in your webhook
},
"contexts": [],
"metadata": {
"intentId": "0e1b0e72-78ba-4c61-a4fd-a73788034de1",
"webhookUsed": "false",
"webhookForSlotFillingUsed": "false",
"intentName": "get drink"
},
"fulfillment": {
"speech": "",
"messages": [
{
"type": 0,
"speech": ""
}
]
},
"score": 1
},
"status": {
"code": 200,
"errorType": "success"
},
"sessionId": "8b0891c1-50c8-43c6-99c4-8f77261acf86"
}

Resources