Dialogflow fulfillment chose among options - node.js

I am writing you to ask a question about Dialogflow fulfillments.
I am trying to create an agent for Google Home and my backend is basically a web hook implemented in TypeScript.
In the conversation that I designed, the user requests to the agent to perform an action, providing a category as paramter. Now, the set of possible categories can vary through time, so I am using the entity type #sys.any to detect the parameter.
My problem is that, when on the fulfillment I try to identify the specific category on which the agent needs to take action, it may be the case that the requested paramter matches multiple cateogries, so I'd need a followup intent to ask the user to clarify which is the actual category it wants to select.
E.g. the conversation could be the following:
Agent: 'Welcome.'
User: 'Do action on **category**'
Agent: 'I have found **categoryA**, **categoryB** and **categoryC**. Please specify which one you want to select.'
User: 'Select the second || Select **categoryB**'
Agent: 'Great, action performed on **categoryB**'
Now, I was able to build this conversation using followup events and contexts: for example I created two followup events, one that detects the numbers and another that detects the text, so the user is driven on one or another depending on what it says (if the user says 'The first', a number is detected and in the backend I cycle the categories selecting the one that is associated to that index. I do a similar operation if the user says "categoryX", but inside a different intent).
What I want to understand is: what is the proper way to achieve that kind of conversation through the Node.js fulfillment API?
Thank you for any help.

From your description - you've done precisely the right thing (although you don't need followup intents).
When you reply with the options the user has, you include a Context that may contain the array of possible results. You then create Intents that have this as an Input Context, match either the index of the array (lets call this the match.index Intent) or by name (the match.name Intent).
In your webhook, the match.index Intent would determine which category was actually chosen, and then call a function that takes care of that category. Similarly, the webhook for match.name would take the parameter with the name and call the same function to take care of that category.

Related

Using #Sys.Any Entity For my Chat bot / Assistant Service(Design Issue)

I am trying to develop a chatbot / google assistant service for food ordering service, and I currently have it designed this way:
There is a dynamic menu list that will be fetched through an API every time the user asks for menu (new Order Intent)
Then menu categories name list will be displayed
Then the user sends the category name
The second follow up intent (selected category intent) catches it and fetches the food items in the category
Then user sends the food item name
Then next follow up intent (selected item intent) catches it and asks for quantity.
The problem here is since it is dynamic list I can not make use of custom entity and slot filling and train it, so i am currently using #sys.any entity. getting the category name from user and checking if it is present in the menu list from the webhook, if present display item list. if not present check spelling or enter correct menu category and reenter prompt. then here since the "selected category intent" is already consumed so whatever i type now is taken as "item name" instead of "category"
I am preventing this by matching output context from "selected category intent" fulfillment and input context in the "selected item intent". But there are problems with this approach such as once a category is selected I can not go back and change that, and it only works 5 times(lifespan of parent intent context) before going to fallback intent
I know this is really bad design but is there any way to make this better?
Any way to say if the user enters a wrong category name, no do not consume this intent yet go back and get the right category name?
Or if the user selects a category or item by mistake. any way yo go back to that previous intent and do that again?
A few observations that may help:
Use Session Entities
Since you are loading the categories and menu dynamically, you can also set Entities for these dynamically. To do this, you'll use Dialogflow's API to create Session Entities that modify the Entity you have defined. Then you can train your Intent with phrases that use this Entity, but you'll dynamically modify the Entity when they start the conversation.
Don't use Followup Intents
Followup Intents are useful in very limited circumstances. Once you start chaining Followup Intents, it is usually a sign that you're trying to force the conversation to go in a particular way, and then you'll run into problems that you have when the conversation needs to take a slight turn.
Instead, go ahead and use top-level Intents for everything you're trying to do.
"But," I hear you asking, "How do I then make sure I handle the category selection before the menu selection?"
Well, to do that you can...
Use Contexts
You were on the right track when you said you were matching Output Context. You can not only match it, but go ahead and control which Contexts are set in your webhook. So you can use Input Contexts to narrow which Intent is matched at any state of your conversation, but only set the Output Context in your webhook fulfillment to determine which Contexts are valid at any stage of the conversation. You can clear Contexts that are no longer valid by setting their lifespan to 0.
So under this scheme:
When you tell them the categories, set the "expectCategory" context.
The "selected category" Intent is set to require the "expectCategory" Input Context.
In the handler for this context
You'll tell them the menu
Set the "expectMenu" context
Clear the "expectCategory" context
Most of all, remember...
Intents represent what the user says, and not how you react to what they say.

Dialogflow required parameters

In my dialogflow chatbot i am creating i have a scenario where a user can ask what are the available vacancies you have or they can directly ask i want to join as a project manager or something. Both are in the same intent called "jobs" and the position they want is a required parameter. If user don't mention the position (eg - "what are the available vacancies you have" ) it will list all available vacancies and minimum qualifications need for that vacancy and ask user to pick one (done with slotfilling for webhook.). Now since the intent is waiting for the parameter when user enter the position they like it will provide the details regarding that position. But even when user is trying to ask for something else (trying to call to a another intent or they don't have enough qualifications for that vacancy or the needed job is not listed with the available job list) since that parameter (the Job position) is not provided it ask again and again what is the position you want.
how do i call to another intent when the chatbot is waiting for a required parameter
There is a separate intent for "The job i want is not here". If i typed the exact same one i used to train that intent then i works. but if it is slightly different then it won't work
Try this:
make your parameter as "NOT" required by unchecking the required checkbox.
keep webhook for slot filling.
in the webhook, keep a track if the parameter is provided or not.
if the intent is triggered, check programmatically for parameter and ask the user to provide it by playing with the contexts.
if the user said something else, then there will be no "required" parameter as per Dialogflow and it will not ask repeatedly to provide the parameter.
Let me know if this helped.

how can we pass the user original query across all followup intent in dialogflow

I have one intent named "search.category" which has user queries like "32gb phones" and it has a follow up intent to get_brand question like "do you have any specific brand? ".
This can have two type of answers that user can enter brand name or he can say "I don't know."
Is there any way to pass the whole user query in main intent to followup intents.
How can we pass the original user query(32gb phones) as a parameter across the intents?
In the second picture, you can see that two entities are selected, so is there any way to select the other text from user query ( I want the "show me some under 40000")
To do this, you would create a new Output Context on the first intent. Output contexts created as part of an intent contain the parameters that were set by the user when they were created and are available in subsequent intents (for as long as their lifespan is active). You can access the context's parameters either in the response or in your fulfillment webhook.
If you're trying to use values that aren't set in the parameters, then in the fulfillment of the original intent you can set any value you want as a parameter of an Output Context that you create in your webhook.

Dialogflow: Determine product name or Select a product from a list which are fetched using a webhook

I am trying to build a bot(custom UI in my website) where a user will enter a product name to view the details of it and I will provide a link to the product full details page. I have a situation where if the user enters a name and there are multiple results from my database, I want to show him those products as quick replies so that he can select one from them.
How do I recognize that the user has entered the product name and anything else? I can use #sys.any, but all small conversation will also go there, which will be of no use.
The same problem occurs when I display him a list of products with matching name. But now when the user clicks on any of the button I am taking him to a custom follow-up intent where I have entered the template for a product entity. But, dialogflow only recognizes the products that have been defined in the entity(listed few products and checked auto expand).
I have tried using #sys.any instead, but the intent is called for any string the user types in. Lets say, the user does not respond and after a while he types in "hi", my intent with any is being called. How do I overcome this situation?
So far as I understand, I can see two ways to solve this query. First, using an entity & defining your product list over there for bot to understand user responses (which you have done) but this will become an overhead when you have a list of say 1000/more products. Second way, you can continue using #sys.any & define a parameter, write a webhook where you validate user entered response to product list in database & check if it is present over there, if yes, show product details or say, entered response is incorrect.

Parameter value filling with quick responses in messenger

I have created a bot using Dialogflow (api.ai) and integrated it with Facebook messenger. I want to get the parameter values from user: like city, date (today, tomorrow) by using the quick reply feature of messenger, where user is presented with select-box like options, and can tap on one of the options. The required parameter receives the user-tapped value, saving the user from typing it manually.
I cannot find anywhere in documentation any way to fill up parameter values (slots) using quick replies. There is an option to give quick replies in response section, but the response section is called on fulfilment, and if I take user input in response, then I have to create another follow up intent to process the user-response further, because the current intent gets fulfilled after response.
If I add quick replies in the response section, then I have to create multiple levels of follow-up intents. Ex: I take city input in one intent, and give two options to user (like New York, Delhi). Then I have to create two follow up intents, each for handling one reply (New York and Delhi), and then for each follow up intent, I will have to create more follow up intents to get more parameter inputs. Below is the flow diagram of this case. --->
This can get pretty complex when more levels are added! Amazon Lex has this feature of filling slots using quick replies. Can't I just fill up parameter values directly using the quick replies like Lex?
You don't have to go this far. There is a simple way of using entities & prompts in dialogflow.com. The workflow can be: Weather(intent)->quick reply(New york/Delhi)->City(intent) use entities here->quick reply(Today/Tomorrow)->Use different intents here for today & tomorrow as you will have different responses. You don't need to create different intents unless you have different responses. User says can have different parameters for which you can define different prompts as well. This will again reduce your complexity of creating follow-up intents. Let me know if you need more explanation on this.

Resources