Webhook generated list fetch option selected by user - node.js

I'm pretty new in API.AI and Google Actions. I have a list of items which is generated by a fulfillment. I want to fetch the option selected by user. I've tried reading the documentation but I can't seem to understand it.
https://developers.google.com/actions/assistant/responses#handling_a_selected_item
I also tried setting follow up intents but it wont work. It always ends up giving fallback responses.
I'm trying to search a product or something and the result is displayed using list selector format. I want to fetch the option I selected. This a search_product intent and I have a follow up intent choose_product

You have two options to get information on a Actions on Google list/carousel selection event in API.AI:
Use API.AI's actions_intent_OPTION event
As Prisoner already mentioned, you can create an intent with actions_intent_OPTION. This intent will match queries that include a list/carousel selection as documented here.
Use a webhook
API.AI will pass the list/carousel selection to your webhook which can be retrieved by either:
A) using Google's Action on Google Node.js client library using the app.getContextArgument() method.
B) Use the originalRequest JSON attirbute in the body of the reques to your webhook to retrieve list/carousel selection events. The structure of a list/carousel selection event webhook request will look something like this:
{
"originalRequest": {
"data": {
"inputs": [
{
"rawInputs": [
{
"query": "Today's Word",
"inputType": "VOICE"
}
],
"arguments": [
{
"textValue": "Today's Word",
"name": "OPTION"
}
],
"intent": "actions.intent.OPTION"
}
],
...

This is a sideways answer to your question - but if you're new to Actions, then it may be that you're not really understanding the best approaches to designing your own Actions.
Instead of focusing on the more advanced response types (such as lists), focus instead on the conversation you want to have with your user. Don't try to limit their responses - expand on what you think you can accept. Focus on the basic conversational elements and your basic conversational responses.
Once you have implemented a good conversation, then you can go back and add elements which help that conversation. The list should be a suggestion of what the user can do, not a limit of what they must do.
With conversational interfaces, we must think outside the dialog box.

Include 'actions_intent_OPTION' in the event section of the intent that you are trying to trigger when an item is selected from list/carousel (both work).
Then use this code in the function that you will trigger in your webhook instead of getContextArguments() or getItemSelected():
const param = assistant.getArgument('OPTION');
OR
app.getArgument('OPTION');
depending on what you named your ApiAiApp (i.e.):
let Assistant = require('actions-on-google').ApiAiAssistant;
const assistant = new Assistant({request: req, response: response});
Then, proceed with how it's done in the rest of the example in the documentation for list/carousel helpers. I don't know exactly why this works, but this method apparently retrieves the actions_intent_OPTION parameter from the JSON request.

I think the issue is that responses that are generated by clicking on a list (as opposed to being spoken) end up with an event of actions_intent_OPTION, so API.AI requires you to do one of two things:
Either create an Intent with this Event (and other contexts, if you wish, to help determine which list is being handled) like this:
Or create a Fallback Intent with the specific Context you want (ie - not your Default Fallback Intent).
The latter seems like the best approach since it will also cover voice responses.
(Or do both, I guess.)

Related

How to Trigger a Different Intent in Dialogflow V1

I am well aware that Dialogflow V1 is being deprecated at the end of May 2020. However, I am wondering does anybody know how to trigger an intent in Dialogflow via webhook fulfillment? I have google searched the past few days looking everywhere and there seems to be a consensus that while events are available to trigger intent matching, they shouldn't be used. Right now, I have javascript function that is sending a webhook response with context out. I put that context into my dialogflow intent context input but when I run the agent, the intent is never triggered.
Javascript code:
function createTextResponse() {
let response = {
"speech": "Nice! Let's keep going.",
"displayText": "displayed response",
"contextOut": [
{
"name": "trythis",
"lifespan": 5
}
]
}
return response;
}
Here is a picture with my contexts
contexts in dialogflow
Been having a hard time with this lately and would appreciate any help/explanation in order so that I can move forward.
First, remember that Intents represent what the user says or does and not how you react to them. So in general it doesn't make sense to "trigger an Intent". This is why the advice usually is to not use events - while they do make some sense in limited cases, those cases usually represent a user event and not your program trying to do something.
If you want your fulfillment to do something - just do it. Multiple Intent handlers can all call the same function to respond the same way.
Setting a Context does not automatically trigger an Intent. Setting the Input Context for an Intent restricts under what conditions that Intent can be triggered. While it still requires one of the training phrases to be matched, it also requires that all the Input Contexts be active.
This is exactly what events are provided for. Just invoke an event from your webhook.

DialogFlow parameter on all intents without using context/event

we are using DialogFlow for NLP. Our agent has several hundreds of intent. In many of those we need country parameter available (we are retrieving customers' country during specific interactions/dialogs, for some input channels we are retrieving this information from channel directly, e.g. from whatsapp number, etc.). Is there any way how we could propagate country parameter without using events or contexts to all intents? The motivation is obvious: we do not want to create context on all intent manually, some smart solution would be handy here.
What you can do is to always send a detectIntent request with a yourCustomContext context in req.queryParams.contexts with country parameter, as described here. Then, in any intent you'd like, you can access it as #yourCustomContext.country in the parameters.
The context has the following structure, you can use something like the following:
{
"name": "yourCustomContext",
"lifespanCount": number,
"parameters": {
"country": "Zimbabwe"
}
}
The advantage here is that this custom context is easily extendable, in case you need to send additional details all the time, too.
If you use these parameters in a subsequent webhook call and need more complex JSON structure, you can also use req.queryParams.payload object.
Hope that helps!

Trigger one intent at the end of another

Sorry - very newbie question. I have a number of separate intents (let’s call them intent1, intent2, intent3, etc) which constitute a basic FAQ chatbot.
I want users to be able to trigger these independently but I’d also like to guide them from one to the next. So I’d like to be able, at the end of responding to intent1 to ask ‘would you like to hear about intent2 or ask another question’ and respond appropriately.
So far I’ve not messed with node backends etc so there is a possibility the answer lies there.
You don't need to use a fulfillment webhook, but it does make things somewhat easier.
First, remember that Intents handle what the user says, and not what you do with that. Dialogflow's responses appear to suggest they do, but once you get into more complicated interactions (where two different things from the user need to respond the same way), you find that the response section becomes less useful, and you should store your responses in code.
Those responses should include the prompt about the next question.
During fulfillment you should also set a Context (and possibly clear older contexts) to keep track of which question you are suggesting for them next.
This way - the next response will be triggered by two possible Intents:
One that directly asks a question.
In these cases, you'll use the Intent or action name to determine which question was asked, and provide an answer (and followup prompt).
One that responds "yes".
For this, you'll get the Context that includes information about the question you prompted them for, and provide that answer (and followup prompt).
While the "Followup Intent" feature sounds tempting, it is likely not what you want to use, since it does not allow multiple ways to access it and forces a very narrow path.
You may also wish to take a look at Thinking For Voice: Design Conversations, Not Logic for more about designing your conversation (and how to model it in Dialogflow, in a followup article).
okay, I am late here! Yes, It is possible with the event. I have recently done this.
function helloIntent(agent){
agent.add("Hi, how are you ?");
agent.setFollowupEvent({ name: 'NextIntentEvent', parameters: {} }); // this will do the trick
}
app.js
let intentMap = new Map();
intentMap.set("Hello Intent", helloIntent);
NextIntentEvent should be an event name defined in the intent that you want to trigger.
some code removed for brevity
If you want to make chain of conversation there are few options for that.
Slot filling
Here you need to add your questions as prompt and you can make that optional so if user wants to make the conversation they proceed by answering that question. Example
Contexts
You can set the follow-up question with contexts, Example
Events
Events are something that you can trigger from your web hook once you send the response of your current question,
To trigger the event, Example
POST Authorization: Bearer <AccessToken>
https://dialogflow.googleapis.com/v2/projects/<ProjectID>/agent/sessions/<SessionID>:detectIntent
{
"queryInput": {
"event": {
"name": "event-name",
"parameters": {
"parameter-name-1": "parameter-value-1",
"parameter-name-2": "parameter-value-2",
...
},
"languageCode": "en-US"
}
}
}

actions_intent_CANCEL not working as expected

I am trying to follow this great article on Medium written by Jessica Dene. When users say a global cancel command such as "quit", I want my action to respond with a "goodbye" message. I have tried to follow the instructions provided by Jessica as illustrated below:
Add the actions_intent_CANCEL event to my end intent
Know More - no - no is my end intent. As you can see below, when I try to add "actions_intent_CANCEL" under Events, I can't see it as a suggestion in the drop down
But given that actions_intent_CANCEL does exist according to docs, I added it
Error
I saved the intent and tried in the web simulator, I see the below error
Any idea why I am getting this error?
Typing actions_intent_CANCEL in directly was completely appropriate. Most of the ones in the dropdown are for Welcome-like intents rather that in-conversation events that can occur. You have the right action name.
It sounds like you're handling it mostly correctly. The only additional thing you need to do is to explicitly close the conversation.
If you are using a webhook for fulfillment, how you do this depends on the library you're using (assuming you're using a library).
If you're using the actions-on-google library you would use the conv.close() function:
conv.close(`Okay, let's try this again later.`);
With the dialogflow-fulfillment library, it would be agent.end():
agent.end(`Okay, let's try this again later.`);
If you're using multivocal, you can either set the environment setting ShouldClose to true, or set it to true in a Response.
Response: {
"Action.multivocal.welcome": [
{
Template: {
Text: "Hello world."
},
ShouldClose: true
}
]
}
If you are using JSON, you can set payload.data.expectUserResponse to false.
Finally, if you are not using a webhook for fulfillment, but are just using the Responses section of Dialogflow, you would turn "Set this intent as end of conversation" on.
Yes, the actions_intent_CANCEL is removed from the docs and also from the dropdown list of events in Dialogflow.
So for exiting the conversation, you can try the following:--
(1) make an entity entry having all quotes for exiting the conversation e.g:-- bye, goodbye, bbye, talk to you later.
(2) make an intent having examples of the users leaving the conversation e.g:- I have some work, bye for now.
(3) And select the end conversation tap at the bottom of the intent so that conversation ends with the sample response.
(4) Also make a suggestion example for BYE/CANCEL with all the intents for better conversation flow
Using the above steps, you can mimic the actions_intent_CANCEL event

Dialogflow / Actions on Google: Provide dynamic response data for link out suggestions

I've tried to implement an Dialogflow app (Actions on Google) and it works quite well so far. However: does anyone know if it is possible to define further action parameters / context via node.js, so I can use them somehow to create dynamic "link out suggestions" in Dialogflow?
In Detail: I try to request some parameters from the users, map them on a set of urls (=implemented as some kind of database) and then write the result url into the json response. Goal: include these response url as $url, #deeplink.url (or similar) in Dialogflow's "Response > Google Assistant > Enter URL".
Is this possible in any way? Thank you in advance.
UPDATE: I also tested the approach of building a rich reponse, but it does not seem to work. Example:
const richResponse = app
.buildRichResponse()
.addSimpleResponse('Flight from ' + origin + ' to' + destination)
.addSuggestions("Find your flight:")
.addSuggestions("Basic Card", "List", "Carousel")
.addSuggestionLink("Search now", url);
(app is an instance of require('actions-on-google').DialogflowApp)
However, he seems to stop after "addSimpleResponse".
Yes. You can create a context in your webhook, and include parameters in that context that contain the values that you want. To use your example, you could create a context "deeplink" and set a parameter in it named "url" with the URL you're going to link to. You should probably also have a "title" parameter, since the Link Out Suggestion and Basic Card requires a title or website name in addition to the link.
Creating a context is fairly simple, but depends on exactly how you're generating the JSON. If you're using the actions-on-google library for node.js, you would create it with a command something like
var contextParameters = {
title: "Example Website!",
url: "http://example.com/"
};
app.setContext( "deeplink", 1, contextParameters );
If you're creating the response JSON yourself, you will have a contextOut array with the context objects you want to set. This portion of the JSON might look something like
"contextOut": [
{
"name": "deeplink",
"lifespan": 1,
"parameters": {
"title": "Example Website!",
"url": "http://example.com/"
}
}
]
Then, in the fields for the Link Out or Basic Card, you would reference them as #deeplink.title and #deeplink.url. For a Link Out, it might look something like this:
However, once you're doing fulfillment, sometimes it becomes easier to generate the VUI and GUI elements in the webhook instead of setting them as part of the Dialogflow builder. This is particularly true if you have a varying number of cards or carousel items that you want to generate.
The Actions on Google documentation provides the various UI elements that can be returned along with sample JSON and node.js code to generate each. These are the same elements that Dialogflow offers through the Actions on Google response tab - just that you can generate them from your webhook instead.

Resources