My organization is setting up a chatbot to help handle simple problems, and we'd like to differentiate answers depending on the user. For some questions, depending on whether the user is a student, faculty, or staff may change the answer (whether or not the request is allowed/access/etc.).
Within Dialogflow I set up an entity called #Affiliation to capture "student", "faculty", or "staff" but now the problem is how do I access that entity in other intents? Is it possible to store that entity somewhere in the session or context such that other intents can read the value and change their response?
The general approach for this would be to store any values you want to store between turns in the conversation as a parameter in an Output Context. You should set the lifespan for this to a large number, 99 is typical, or re-set this as the Output Context each time.
Then, you can read the parameter in the named Context when you need the information.
Related
I wanted to know if it possible for dialog flow to store value of parameter without set the entities for it. For example The bot ask the user What is your name? and the user respond with Jack. So dialogflow will store value “John” in the parameter. Thank you.
Dialogflow Web UI
So when working with the Dialogflow Web UI your options are a bit more limited compared to fulfillment and you won't really get around using entities. In the Web UI the best way to extract values from the user input is by using entities and parameters. The only way of using "raw" input via the Web UI is by using the #sys.any entity, but you should be careful with this.
The #sys.any entity takes the complete input from the user and gives it to you, but it doesn't provide any information on what entity the input might be off. For instance, if you ask the user "What is you name?" the user might respond with "John", but they also could respond by saying "Oh.. uhh. My name is John" and if you use #sys.any you get the whole string and you have to detect what is a name and extract it from the input yourself. Entities and parameters do this for you.
You can use the input from the user in your response by using $parameterName in your response
Dialogflow Fulfillment
When working with code the issues with raw input remain the same, you will get the whole user input, but have to do recognition or regexing to retrieve the values yourself.
One benefit of working with fulfillment is that you always have access to the raw input, you can call agent.query to retrieve the raw input, so you are not required to use a #sys.any entity in your parameter setup.
Conclusion
So as I mentioned in the above, there are a couple ways of retrieving the raw input of the user, but in both cases you lose the automatic detection provided by entities and parameters when you do so. While at first it might seem a hassle to work with entities and parameters, if you are going to use the user input for anything, like saving the name or making a decision, I really recommend sticking to the entity approach because it automatically detect the input from the string, you don't have to worry about how the user answers your question, which is a big part of developing a bot.
There are very few cases where using raw input has made developing easier for me in the long run.
Good day,
I am currently trying to create an intent that is able to put out responses depending on the user input. (The chatbot should be implemented on a website later)
Let's say we have an entity called cars with three entries: "Volkswagen" "Audi" "Ford".
Now when the user types in something with e.g. Audi in it, the response will correspond to this. Something like this: If Audi then give this response, if Ford then this response.
I couldn't find anything helpful yet.
Thank you in advance!
Remember that Intents represent what the user says and not how you handle this or how you reply. Although Dialogflow does offer the ability to respond to Intents, these aren't based on specific values that may appear in parameters.
There are, however, a variety of ways you can handle what you're doing, based on the rest of what you're trying to do.
Multiple Intents
One solution is to create an Intent for each type of thing that the user may talk about. You could then put the response you want for each in the response section of that Intent.
This is probably a bad approach, but may be useful in some ways. It requires you to duplicate phrases between the different Intents, which leads to a lot of duplication. On the upside, it does let you vary the replies, and truly represents the Intent of what the user is trying to say.
Using Parameters with Fulfillment
A better approach is to have a single Intent with many phrases representing what the users can ask. These phrases would have parameters of your Entity Type.
You can then enable Fulfillment for this Intent and write a Fulfillment webhook for the Intent that would look a the value of the parameter and send back an appropriate reply.
Using Parameters with DetectIntent
Since your ultimate goal is to embed this on a website, it may be more appropriate to have your website show something different based on what the user has said. (For example to show a picture of the car in another pane or links to different pages, to use your example of cars.)
In this case, your chat client (or a proxy) would be calling the DetectIntent API. You can structure your Intent similar to above, with parameters of the Entity Type, and the reply that is sent to your client would contain the Intent along with the value of the parameter. Your client then can check the value of the parameter and change the display accordingly.
I've got a few intents. They all just use a single fallback intent and this fallback intent has the webhook enabled.
In the fallback function what I was hoping to do is switch on the output context and then determine what should happen next depending on which intent the fallback came from.
But the line
var context = request.body.queryResult.outputContexts;
When debugged to the console gets output:
[ { name: 'projects/xxxxproj-xxxx/agent/sessions/xxxxxx-xxxxxx-xxxxx-xxxxx/contexts/xxxxxxx-context' } ]
For the switch statement i just want the last bit with the xxxxx-context. Am I going to have to split that up to get the output context?
In the "Diagnostic Info" section I am a bit surprised there is no reference to the intent from which the fallback came and the only way to work it out seems to be using the outputcontext but as show above that is quite a long string.
Thanks
Yes, the context name is just the last part of that path. Most libraries will take care of that for you, but if you're working with the JSON directly, you need to do this yourself.
There is no reference to "the Intent from which the fallback came" because this isn't quite the model of what an Intent is. Intents represent what the user has said or done, not the current state of the conversation or where you are in the conversation. That current state is represented by Contexts, should you choose to set them.
In that sense, how you use the contexts can vary. They can store parameters, so are a good way to keep information between rounds of a conversation, and you can use them the way you are - to see what state the conversation is in general. But they also take on additional uses when defining Intents.
In an Intent definition, the Intent will only be triggered if all the Contexts listed in the Input Context field are set (ie - have a lifespan greater than 0). Dialogflow uses this when it makes followup Intents, for example, and it is common so you can do things such as have "help" trigger different Intents based on Context. In an Output Context, it will automatically capture all of the parameters specified in the Intent, including those filled in by the user's response, so this can be an easy way to remember what the user has said from round to round.
To answer your question in the comments - it doesn't specifically say which Intents were previously triggered, or which most recently, although if you're consistent in how you use your Output Contexts and what lifespan you give them, you can use it this way. What it does say is in what state your conversation is in, which is generally much better anyway.
Remember - Intents represent what a user has said or done. It doesn't represent anything else about the conversation. Only the state of the system represents that, and one tool we have to control that state is through Contexts.
I am trying to make a search algorithm with dialogflow that could take any combination of: first name, address, phone number, zip code or city as input to a search algorithm. The user does not need all of them, but we will refine our search with each additional answer until we only have one result. Basically we are trying to identify which customer we are talking to.
How should this type of intent (or set of intents) be structured? We have tried one intent with multiple parameters, but we do not need all of them to be required. We have also written a JavaScript function for fulfillment but how can we communicate back to dialogflow as to whether we need more information?
Thank you very much for your help.
Slot filling is designed for this purpose.
Hope that helps.
Please post more code/details to help answers be more specific.
First, keep in mind that Intents reflect what the user is saying, and not typically what you're replying with or what other information you need. Slot filling sometimes bends this rule, but only if you have required slots.
Since you don't - you need a different approach.
This can be done with a single intent, although you may find that multiple intents make it easier in some ways. The approach is broadly the same:
When you ask the question, make sure you set an Outgoing Context with a relatively short lifespan (2-3 is good) to indicate you are collecting user info.
Create an Intent (or Intents) that have sample phrases that capture the information you need.
Some of these will have obvious entity types (phone number and zip code) while others will be more difficult (First name has a system entity type, but it doesn't include all possible first names).
You will need to create sample phrases that collect the parameters by themselves, along with phrases that make sense. You're the best judge of this, and you should probably write some sample conversations before you write the phrases.
In your fulfillment, you'll figure out if you have enough information.
If you do, you can reply and clear the Context that was set. (Clearing it is important so Dialogflow doesn't match the information collecting Intent again.)
If you do not, you can add the information you have as parameters to the Context so you can save it for later processing, make sure you reset the Context lifespan (so it doesn't expire), and prompt the user for additional information. Again, having a conversation mocked out ahead of time will help here.
I am trying to jump to a random question with followup event, and at the same time store the question number in the context. But dialogflow only jumps to the event without storing the question number. Is there a way to do followup event and store a context in one intent?
app.intent('Quiz - random', (conv) => {
let rand = Math.floor(Math.random() * quiz_len) + 1;
conv.data.current_qns = rand;
conv.followup(`quiz-question${rand}`);
});
Not really. The point of using conv.followup() is to make it as if the new Intent is the one that was actually triggered by the user. Remember - Intents represent what the user is saying not what you're replying with. You can include a parameter with the redirect, which I guess you can use to send the question, but this still would be the equivalent of a parameter sent by the user.
It isn't entirely clear why you feel you need to direct to a different Intent. Is it just to ask the question as part of the reply? Go ahead and ask it in the Intent handler you're in and store the number in the context directly.
Update
You've indicated in the comments that you want to structure things so you have a "random dispatcher" that then redirects to an Intent to ask a question, and that Intent has a Followup Intent that accepts the right answer (and possibly ones that deal with wrong answers).
This requires you to build a lot of extra Intents for all the various questions, and then the conditions on each question. This requires you to re-build this structure every time you want to add a new question.
Dialogflow works very well to navigate the structure of a conversation - so you don't need to use it to navigate specific questions, answers, and responses. Remember - Intents model what a user says in broad terms, not how our agent responds.
Here is a structure that might work better:
There is an Intent that handles the user asking for a random question. The Intent fulfillment for this (ie - the handler function in your webhook) does the following:
Selects a question
Sets a context to indicate which question is being asked
Sends the context and the question to the user
There is another Intent that handles user responses. All user responses. If this is a multiple choice question, you can set very specific phrases, but otherwise you may need to make this a Fallback Intent that has the context specified above as an Input Context.
Your handler for this compares the answer.
If correct, you clear the context, say so, and ask if they want another question. (Which would then loop to the Intent specified in step 1.)
If incorrect, you make sure the context is still valid and tell them they're wrong. Possibly increase a counter so you don't let them guess indefinitely.
This means you're only building two Intents that handle the question itself. You should add a few more. Here are a few to think about:
What happens if the user doesn't say anything at all? The "No Input" scenario should be handled differently than a bad answer.
If you're asking a multiple choice question, perhaps you'll use a list and need to handle a list response.
Finally, if you're using a list, you may want to do something fancy and use Dialogflow's API to set a Session Entity Type for just that question. This allows you to set what you're expecting (with some aliases) for what is correct and incorrect, and then use a Fallback Intent for the context to say that what the user said didn't make sense.