I want to set entity values based on condition. How to do that in dialogflow? - dialogflow-es

I am making a bot for booking rooms. For booking rooms a user can choose "Premium Service" or "Standard Service".
However the hotels available to be booked depends on "Premium" or "Standard".
How to do this in dialog flow?
I tried to set entities "Service_type" and "Hotels". However how to set values for entity "Hotels" based on "Service_type" the user has selected?
Please note that the intent of the bot is book rooms. And there are many other steps to be followed to complete it.

You can start by creating an entity like quality and it's helpful to think of other ways that the user might refer to the quality that you define as "standard" and "premium"
Now when you create your intents you should see that Dialogflow automatically detects your entity in the training phrases
If Dialogflow doesn't already detect your entity, you can highlight a word in the training phrase and associate it to a type of your choosing
That's the easy part.
In order to present a different set of hotels depending on which standard that was selected, you should look into developing a fulfillment endpoint that handles the logic.
The quality choice that the user made in the first question will be passed as a parameter and you can easily make conditional logic to select hotels depending on that
conv.ask(`Here is a list of ${quality} hotel options for you`);
if (quality === "premium") {
conv.ask(getPremiumHotelOptions()); // Carousel or list
} else {
conv.ask(getStandardHotelOptions()); // Carousel or list
}

You can create an empty Hotels entity and then populate it with the relevant entity values for that session in your fulfillment webhook.
If you're using node.js for your webhook, you can look into the Dialogflow library to do much of this work. The call might look something like this:
const sessionEntityTypeRequest = {
parent: sessionPath,
sessionEntityType: {
name: sessionEntityTypePath,
entityOverrideMode: entityOverrideMode,
entities: entities,
},
};
const [response] = await sessionEntityTypesClient.createSessionEntityType(
sessionEntityTypeRequest
);
(See a more complete example at https://github.com/googleapis/nodejs-dialogflow/blob/master/samples/resource.js in the createSessionEntityType() function)

Related

Is it possible for users to choose between a few intents for Bot Framework Composer (LUIS)?

I'm trying to get something like this Stack Overflow question but within Bot Framework Composer. In Power Virtual Agents, if the bot is not sure about which 'Topic' aka 'Intent' is the right one, it gives the user a few options. How can I achieve that in Bot Framework Composer, or at least extend the bot with code?
In your dialog, create a trigger for "Duplicated intents recognized" :
Duplicated intents recognized automatically sets some variables for the turn that you use to customize your logic in how to handle duplicate intent recognition.
From here I refer to the Enterprise Assistant template :
conversation.lastAmbiguousUtterance = turn.activity.text
You don't really need to use this, but it's set in the Enterprise template in case you want to use the user input in the bot's response
dialog.candidates =
=take(sortByDescending(where(flatten(select(turn.recognized.candidates,
x, if (x.intent=="ChooseIntent", x.result.candidates, x))), c,
not(startsWith(c.intent, "DeferToRecognizer_QnA")) && c.score >
turn.minThreshold), 'score'), turn.maxChoices)
This basically organizes the duplicate intents into a list, dialog.candidates, by
sorting the intent recognized in descending order (so first element is the highest recognition score intent)
filtering out intents starting with "DeferToRecognizer_QnA" that are automatically generated from cross-training
filtering out intent scores that don't meet the minimum threshold that you set
getting only the number of intents for max choices that you set
From here you can set your logic so that if
count(dialog.candidates) = 0
, you emit an UnknownIntent event, or emit a recognizedIntent for
=first(dialog.candidates).result
if your dialog.candidates has at least one result.
Or, you can customize your logic to handle however which way you want, which in your case is inputting dialog.candidates in an adaptive card so the user can choose which intent they wanted.

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.

how to handle product names, ticket number in dialogflow?

Suppose, I have questions about the product name, or ticket number or product id which are going to be unique every time. How to define intents for such questions and how to use entities to store it in a variable ?
For example:
For room booking intents, entities for room type could be single-bed room, double-bed room, king size bed or queen size.
Similarly, suppose for an enterprise product for bug tracking system, if I want to create entities for ticket number which could be anything (ex. TRS-6527).
Apologies, if this is very naive or unrelated questions.
You can define room_type entity using Create Entity in Entites section of your dialogflow console.
And train your intent by adding training phrases accordingly as below (Please Ignore the error here ):
Now you can access the room_type as a string in your fulfillment as params
app.intent('get_room_type', (conv, params) => {
const roomType = params.room_type;
// remember to use the same variable name that you defined as
// Parameter name in your intent to access in params
});
Similarly you can achieve for ticket number as well.
Refer this Codelab for example.
Hope that helps !

Alexa Skill Kit - To save user input

Is there a way to save the user input to a variable in ALexa Skill kit.
Yeah You can do that. You can store any information given by user using slots. You can use built in slots or you can also define your custom slots.
You can use built in slots if you want to get or store numbers or date or name of person etc.
Refer this link for list of Built In slots : https://developer.amazon.com/docs/custom-skills/slot-type-reference.html
If you want to store whole statement given by user then you can use AMAZON.SearchQuery:
As you think about what users are likely to ask, consider using a built-in or custom slot type to capture user input that is more predictable, and the AMAZON.SearchQuery slot type to capture less-predictable input that makes up the search query.
Make sure that your skill uses no more than one AMAZON.SearchQuery slot per intent. The Amazon.SearchQuery slot type cannot be combined with another intent slot in sample utterances.
When you are creating an intent using Skill Builder, you can specify the Slot using curly brackets.
You can also define a Slot Type. You can define your own types or choose from built-in types.
Check the complete list here: https://developer.amazon.com/docs/custom-skills/slot-type-reference.html
From your Alexa skill (lambda function) you capture that a user is saying. You can get it from:
this.event.request.intent.slots.<SlotName>.value
Then you do with the value what do you want.
Update:
Interaction schema would be:
{
"name": "MyColorIsIntent",
"samples": [
"my favorite color is {Color}"
],
"slots": [
{
"name": "Color",
"type": "LIST_OF_COLORS"
}
]
},

Webhook generated list fetch option selected by user

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.)

Resources