Reputation: 669
I am using actions on google and dialogflow agent to build a chatbot. I am developing an open ended conversation where the user gives response to a question and then a new question has to be asked.
Here is the code:
app.intent('First', (conv) => {
const ans = conv.parameters.any;
if(type[0] === 'RATING'){
if(ans == 1){
senddata[0] = qstion[0] + ans;
conv.ask(qstion[1]);
}
else if(ans == 2){
senddata[0] = qstion[0] + ans;
conv.ask(qstion[1]);
}
else if(ans == 3){
senddata[0] = qstion[0] + ans;
conv.ask(qstion[1]);
}
else if(ans == 4){
senddata[0] = qstion[0] + ans;
conv.ask(qstion[1]);
}
else if(ans == 5){
senddata[0] = qstion[0] + ans;
conv.ask(qstion[1]);
}
else{
conv.add('Please give a number between 1 and 5.');
}
}
});
When a question has been asked the user needs to give the answer from 1 to 5. If the user provides any other answer then they will be prompted with an alert message that 'Please give a number between 1 and 5.' Then the flow needs to be in the 'First' intent itself and it needs to stay there till the user enters the number from 1 to 5. But as I have set the flow in dialogflow that it should go from First to Second. So, even after prompting the message the flow goes to the 'Second' intent.
How do I keep the flow in the 'First' intent itself?
Upvotes: 1
Views: 361
Reputation: 50701
The problem is that Intents are supposed to determine what the user has said and not what you do with it or the conversation flow. So, in general, you would want a single Intent that captures the user giving a rating, and your code would determine what question they were replying to and handle it appropriately.
You may be tempted to use Followup Intents, which use contexts behind the scenes, to manage the flow. This will only make things more of a mess - especially if all your Intents have the same training phrases. Similarly, while you can manage conversation through using input and output contexts, if all your Intents would have the same training phrase, you're making a lot more work for yourself.
Best is to use Context parameters that you set to keep track of the current question. You could then have a single "rating" Intent which captures when a user gives a rating, reads which question was being worked with, saves the value against that question, and advances to the next question.
Simplifying your code to remove redundant parts, it might look something like this:
app.intent('Rating', (conv) => {
// Determine what question we're working with
const questionContext = conv.contexts.get( 'question' );
const questionNumber = (questionContext && questionContext.parameters['number']) || 0;
const ans = conv.parameters.any;
if(type[0] === 'RATING'){
if( ans >= 1 && ans <= 5 ){
// Record the rating
senddata[questionNumber] = qstion[questionNumber] + ans;
// Set the context for the next question with a long lifespan
conv.contexts.set( 'question', 99, {
number: questionNumber+1;
});
// Ask the next question
conv.ask(qstion[questionNumber+1]);
} else {
// They didn't answer between 1 and 5, so this is an error
conv.add('Please give a number between 1 and 5.');
}
}
});
There are a few other things to note:
@sys.any
type. This can be pretty inefficient, and doesn't really take advantage of what Intents can do. Remember - Intents represent what the user has said.
@sys.number
entity type, since you know you want a number.Upvotes: 3