Ankit
Ankit

Reputation: 669

How to keep the flow in the same intent in dialogflow

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

Answers (1)

Prisoner
Prisoner

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:

  • It looks like you're accepting a @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.
    • An improvement might be to make that a @sys.number entity type, since you know you want a number.
    • Even better might be to create a custom entity type that only has ratings from 1 through 5.
    • In both these cases, you would have a Fallback Intent which is designed to capture things that don't match and reprompt with what you want.
  • Since you're building for the Google Assistant, you may wish to look at Actions Builder which does provide conversational flow design using a scene-based approach.
    • Intents still exist - but they more clearly represent what the user has said, and not the state of the conversation.

Upvotes: 3

Related Questions