how do I trigger an intent using DialogFlow? - dialogflow-es

I have a conversation with dialogflow to select a favourite type of drink and then depending on the category of drink there are follow up questions (ie follow up intents).
Under the intent tab I have the following intents:
Default Welcome Intent
Favourite drink Intent
Coffee Intent
follow up
Soft Drink Intent
follow up
Juice Intent
follow up
I use the training phrase in the Favourite Drink Intent and ask:
"What is your favourite drink?"
And store the response in an entity #drink.
But I don't know how then to trigger the intent "soft drink", "juice" or "coffee" intents depending on the users response. If I was writing code I'd use a switch statement or if/else but that prob doesn't apply here.
I wasn't sure if I had to use the fulfillment inline editor or I could just do that from within the Intent UI.
Thanks

In general - think of Intents as capturing what the user could be saying. Although Intents also have replies, this isn't their primary purpose.
Depending what, exactly, you're trying to do, there are a few approaches. All three of them require fulfillment code, which you can do using the built-in editor, or (better) use a webhook more under your control
If you want to use Intents to determine how to reply
This isn't really the best idea, but it is possible. In your fulfillment code, you would have a switch statement against the parameter with the user's selection. Based on this, you would trigger a followup event from your fulfillment. Your other Intents would have the Event section populated with the possible events, and the system would pick which one to trigger and use for fulfillment/response.
This is a bit of a kludge for what you want, probably.
Update to clarify based on questions in the comments. Sending an event directly triggers a different Intent. Sometimes this is what you want, but it is somewhat exceptional. Most of the time you want to use one of the methods below. In particular, you should remember that Intents are mostly meant to represent what the user is trying to do (what they "intend" to do), and this is mostly represented by what they're saying. Intents are good to capture the complex ways people talk instead of forcing them into a phone-tree-like "conversation".
If you just want to reply to each possible user response differently
You can use the fulfillment webhook code to determine what response should be sent to the user. You don't indicate what library you're using, but in general you'd write code that would determine what message should be sent to the user based on the drink type selected and include that as the speech and/or display text in the response.
You wouldn't use the other, drink specific, Intents in these cases. There isn't any need for them. Unless...
You want to reply to each user response differently, and the followup conversation might be different
Remember - Intents are really best for specifying what you expect the user to say. Not what you expect to reply with. So it is reasonable that you may have a different conversation based on if they selected Coffee (where you might ask how much sugar they want) or Juice (where you might ask if they want a straw).
In this case, you would still do as you have in the previous case (use your fulfillment to include a tailored message in your reply, possibly to prompt them for that info) and include in the reply an Output Context indicating what their choice was. You should do this as part of the response, rather than setting it in the Intent, since you'll want to name it differently for each beverage type.
Then you can create Intents specific to each beverage type with what you expect the user today. For those specific to Coffee, you would set the Input Context to require that the coffee context has been set. The soda context if they specified soda, and so forth.
Update, since you indicated in your comment that this sounded like the avenue you were interested in.
In this scenario, you'd do as you described (almost):
Get the value for the drink parameter with code something like
const drink = request.body.queryResult.parameters.drink;
Do a switch based on this, and in the body of each case set what we'll reply with and what context we should remember. Something like this pseudocode, perhaps:
switch( drink ){
case 'coffee':
context = 'order_coffee';
msg = 'Do you want sugar with that?';
break;
case 'soda':
context = 'order_soda';
msg = 'Do you want a bottle or can?';
break;
case 'juice':
context = 'order_juice';
msg = 'Would you like a straw?';
break;
}
// Format JSON setting the message and context
You would then have Intents that would be triggered based on a combination of two things:
What the context is
What the user has said
For example, you would want a context (let's call it "coffee.black") which would be triggered if the order_coffee context is active and the user answered your question with "No" or "Just black" or other valid combinations.
But you'd want a different context (say, "juice.nostraw") if the order_juice context is active and the user replied "No".
And it wouldn't make much sense at all if the user said "No" while the order_soda context was active, so you'd want to try and direct them back to the subject at hand.
Remember, the Intent is for what the user says. Not for what your voice agent is saying. Your agent doesn't normally "trigger" an Intent - the user triggers it based on what they say.
In the example I gave, there might be other Intents that are valid for each of those contexts. For example, you might have a "coffee.sugar" Intent that is valid for the order_coffee context and responds to them saying "Yes". And another one where they might say "Just cream". There are lots of other things they might say as well, but it is important to your agent that the directions they're giving you have to do with ordering coffee.
As for your original question...
(To answer your original, now edited, question: Yes, you can create Intents from within your fulfillment. You almost certainly don't want to do this, however.)

Related

How to prevent user from hopping to another intent in the middle of the conversation?

Let say I have 2 basic intents i.e Set Appointment and Cancel Appointment.
Each of the intents has its own follow up questions and so on. When the user is in the follow up chain for the intent, Set Appointment, I want to prevent the user from hopping to another intent if he/she says "cancel appointment for abc"
Since both intents have empty input contexts so they can be called from the Google Assistant's invocation i.e Tell XYZ App to set appointment for...., it seems that this allows the user to be able to hop between intent mid conversation.
How do I limit this behavior? Or is there some kind design best practices here?
First of all, remember that Intents represent what the user says, not what you're doing with that the user says.
Second, remember that users can change the course of the conversation at any time. So it makes sense that if they start adding an appointment, that they might want to cancel that appointment.
The best approach is that, if they try to cancel in the middle of making an appointment, you decide how you want to handle this change in conversation. And then just reply that way. You may choose to change tracks. Or you may choose to say something like "let's add this new appointment first, and then we can cancel the old one". With this scheme:
You have one Intent that matches "set the appointment for 10am"
In your handler:
If you aren't taking any action, you'd start prompting them for additional appointment setting info, or whatever.
If you are already setting an appointment, prompt them if they want to change the time to 10am
If you're cancelling an appointment, tell them that you'll talk about canceling the old one when you're done with the new one.
I tend to go with this approach in most (tho not all) cases. It lets me code the logic and lets me determine the best way to reply based on the entire state.
Another approach that you can use is to create an Intent with the Input Context that matches your current contextual line of questioning that matches the phrases from the Intent you don't want to match. (This might even be reasonable as part of a negative training phrase for a context-specific Fallback Intent.) Context matches are handled before context-free matches. So under this scheme you would have:
An Intent, without input context, that matches "set the appointment for 10am". The handler for this Intent would set the "set" context and start prompting for additional info.
An Intent, with your "set" input context, that matches "set the appointment for 10am". This could do something like re-start the prompting, or just change the time they're requesting.
An Intent, with your "cancel" input context, that matches "set the appointment for 10am". This handler would let them know that you'll ask about cancelling older appointments at the end.
Which method you use depends on how you're handling other state management in your code.

Dialogflow parameter entity similar to Alexa's AMAZON.SearchQuery

I've developed an Alexa skill and now I am in the process of porting it over to a Google action. At the center of my Alexa skill, I use AMAZON.SearchQuery slot type to capture free-form text messages. Is there an entity/parameter type that is similar for google actions? As an example, see the following interactions from my Alexa skill:
Alexa, tell my test app to say hello everyone my name is Corey
-> slot value = "hello everyone my name is Corey"
Alexa, tell my test app to say goodbye friends I'm logging off
-> slot value = "goodbye friends I'm logging off"
Yes, you have a few options depending on exactly what you want to accomplish as part of your Action.
Using #sys.any
The most equivalent entity type in Dialogflow is the built-in type #sys.any. To use this, you can create an Intent, give it a sample phrase, and select any of the text that would represent what you want included in the parameter. Then select the #sys.any entity type.
Afterwards, it would look something like this.
You may be tempted to select all the text in the sample phrase. Don't do this, since it messes up the training and parsing. Instead use...
Fallback Intents
The Fallback Intent is something that isn't available for Alexa. It is an Intent that gets triggered if there are no other Intents that would match. (It has some additional abilities when you're using Contexts, but thats another topic.)
Fallback Intents will send the entire contents of what the user said to your fulfillment webhook. To create a Fallback Intent, you can either use the default one that is provided, or from the list of Intents select the three dot menu next to the create button and then select "Create Fallback Intent"
So you may be tempted to just create a Fallback Intent if all you want is all the text that the user says. If that is the case, there is an easier way...
Use the Action SDK
If you have your own Natural Language Processing / Understanding (NLP/NLU) system, you don't need Dialogflow in the mix. You just want the Assistant to send you the result of the speech-to-text processing.
You can do this with the Action SDK. In many ways, it is similar to how ASK and Dialogflow work, but it has very basic Intents - most of the time it will just send your webhook a TEXT intent with the contents of what the user has said and let you process it.
Most of the Platform based ASR systems are mainly built on 3 main parameters
1. Intent - all sorts of logic will be written here
2. Entity - On which the intent will work
3. Response - After executing all the process this is what the user will able to hear.
There is another important parameter called webhook, it is used to interact with an external API.
the basic functionalities are the same for all the platforms, already used dialogflow(google developed this platform- supports most of the platforms even Alexa too), Alexa, Watson(developed by IBM).
remember one thing that to get a precise result giving proper training phases is very much important as the o/p hugely depends on the sample input.

Dialogflow inline editor ask for additional info

I am developing a google assistant app on Dialogflow.
And I have a intent that receives two entities: #name and #age
Using the fulfillment throught the inline editor I verify if the #age is below 18.
In that case I need to ask for additional info, I need to ask the name of the person responsible for the child.
I looked around the internet, including the fulfillment samples at https://dialogflow.com/docs/samples
I believe it would look something like this:
let conv = agent.conv();
conv.ask('As your age is under 18 I need the name of the person responsible for you:');
//Some code to retrieve user input into a variable
agent.add(conv);
But I was unable to find how to do it.
Can someone help me to achieve this?
Thanks in advance.
While you are handling an Intent, there is no way to "wait for" the user to respond to your question. Instead, you need to handle user input this way:
You send a response back from your Intent.
The user replies with something they say.
You handle this new user statement through an Intent.
Intents always represent the user taking some action - usually saying something.
So one approach would be to create a new Intent that accepts the user's response. But somehow you need to distinguish this response from the initial Intent that captured the person's name.
One way to do this would be, in the case you ask the question about who the responsible adult is, is to also set a Context. Then you can have a different Intent be triggered only when that Context is set and handle this new Intent to get the name of the adult.

How to get Dialogflow to trigger an intent with ANY input without using fulfillment

Not much to add to this question I don't think. Basically, I have a series of questions the user needs to answer, but they are veeeery open-ended, so the user input could be pretty much anything. Once the user responds to a question I want the system to simply ask the next one, regardless of what they said (unless they say something like "help" or "I don't understand", etc, which I can deal with).
I know I can include contexts, but without supplying the next intent with adequate user input, there doesn't seem like a way to get it to trigger the next question (even when the output and input contexts match).
Is there something I'm missing, or do I really need to just supply dozens and dozens of potential user inputs from across the board and hope the machine learning component extrapolates adequately?
For open-ended responses, the easies way to handle this is through Fallback Intents. You can create more than one Fallback Intent - but each one needs to have a different Input Context which will indicate under what conditions it will be triggered.
To be clear - Fallback Intents are slightly different than regular Intents, and you create them slightly differently as well. In the most simple configuration, they are only triggered if the user input does not match the input for any other Intent. Dialogflow provides a "Default Fallback Intent", which is what will be triggered if no other Intent of any sort matches. You'll need to set the Input Context of your Fallback Intents to indicate when it should handle it with that Fallback Intent and then also set the Output Context to indicate which question you have asked and, therefore, what the next expected Fallback Intent will be.
To create a Fallback Intent, don't click on the "Create Intent" button, instead, click on the three dots next to it.
In the menu that appears, click "Create Fallback Intent"
The screen that shows is very similar to a regular Intent editing screen, but it is specifically for Fallback Intents. You'll do the usual things about adding the name and (not shown) showing the replies (ie - the next questions you'll be asking).
You can tell it is a Fallback Intent because of the message at the top. As noted, you should then enter the Input and Output Contexts you plan to use for this.
You will notice there is a "Training Phrases" section. In your case - you will leave this blank. These are actually Negative Training Phrases - phrases that will not match other Intents (even if they should) and will always be handled by the Fallback Intent instead. Since you aren't trying to mask out phrases that might match elsewhere - leave it blank.

Simple chat bot with a single context matching api.ai?

I want to do some thing like this with api.ai. I am doing it as a telegram bot.
1st question: Tell me a joke?
Bot: Tells a joke ( picks it from text response that I specified )
2nd input from user: Some more.
Bot: It should tell another joke from the same list of responses.
One thing I could do is include MORE as a user input is joke intent and it would pick a response.
But I can not do this, because then even without asking 1st question if I give "more" as input it would pick a response from the list. Basically that wouldn't pick response based on context.
Any help onn the structure I should be using on api.ai to achieve something like this.
So the first intent where the user asks "tell me a joke?" sets an outgoing context- 'jokes'.
Follow-up intents for telling more jokes have 'jokes' for the incoming context, and, if you want to chain repeatable requests, set the outgoing context as 'jokes' as well.
If the user input like "tell me more" outside the 'jokes' context is still triggering the followup intent, either train your bot to recognize the difference, or create an explicit "tell me more" example in a fallback intent outside the jokes context.

Resources