Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Is there a way to trigger different query while filling the required slots in dialogflow

I have an intent orderPizza and entities as @pizzaOptions @pizzaSize @qty

happy path (working fine)

user: order 2 pizza
bot: which pizza you want?
user: pepperoni
bot: and pizza size?
user: large
bot: okay! your order for 2 large pepperoni pizza has been placed.

CASE_2

user: order 2 pizza
bot: which pizza you want?
user: which pizza options do you have?
bot: which pizza you want?

so in case 2 when user ask for the pizza Options then bot re-prompt the same question

I want bot to answer the user query or bot can present the options (different re-prompt) instead of same re-prompt

is there a way to handle this use case

like image 645
Vikas Patidar Avatar asked May 30 '20 04:05

Vikas Patidar


People also ask

What is slot filling?

Slot filling is identifying contiguous spans of words in an utterance that correspond to certain parameters (i.e., slots) of a user request/query. Slot filling is one of the most important challenges in modern task-oriented dialog systems.

What is enable webhook call for slot filling?

This process is called slot filling. By default, Dialogflow does not send a fulfillment webhook request until it has collected all required data from the end-user. If webhook for slot filling is enabled, Dialogflow sends a fulfillment webhook request for each conversational turn during slot filling.


Video Answer


1 Answers

The best setup for this would be to have 2 intents.

  1. Order pizza intent ("Order x Pizza")
  2. Get Pizza option intent ("What pizza options do you have?")

The reason for this is, because the user is trying to get two completely different results from you bot. When the user asks for Pizza type, they aren't always ordering a pizza, they could just be interested in your available types.

  • The Get Pizza option intent you just return an response which gives the user an example of the available pizza types.
  • If you make sure both these intents don't require any input context, you should be able to implement the usecase that you are trying to go for.

If you use this setup and make sure that the parameters aren't set as required, you should be able to switch between these two intents during the slot filling. In the example you gave you can see that you bot in Case2 keeps asking the user about the pizza type, this is because it expects a pizza type entity as input.

Some example conversations would be:

User: I want to order a pizza.
Bot: Sure, which Pizza do you want? // Order Pizza Intent

User: I don't know, which pizzas do you have?
Bot: We currently sell Pepperoni Pizza and Vegan Pizza, what else can I Help you with?  // Get Pizza Option Intent

User: I'd like to order 2 large Pepperoni Pizzas
Bot: Okay! your order for 2 large pepperoni pizza has been placed. // Order Pizza Intent

User: Hey, what types of pizza do you have? // Order Pizza Intent
Bot: We currently sell Pepperoni Pizza and Vegan Pizza, what else can I help you with? // Get Pizza Option Intent

User: Hhm, I'm looking for something else, I'll go look somewhere else.
Bot: Sorry to hear that, I hope you have a nice day. 

Slot filling in the webhook

Because we chose to not make the parameters required, we now have save and check all the paramters ourself. Each time the user mentions an order, we should check if it is complete.


function orderIntent(conv) {

const pizzaOption = conv.paramters.pizzaOption;
const pizzaSize = conv.parameters.pizzaSize;
const quantity = conv.parameters.qty;

if (!pizzaOption) {
  return conv.ask("Which pizza do you want?");
}

if (!pizzaSize) {
  return conv.ask("Which size pizza do you want?");
}

if (!quantity) {
  return conv.ask("How many pizzas do you want?");
};

This will now allow us to prompt the user until they provide all the information to complete the order, if you would use this code, the bot would keep looping until the user mentions a single phrase that includes a pizzaType, pizzaSize and quantity entity.

Because it is unlikely that the user will ever do this, we need to expand the code to allow the order to be split up in multiple steps and understand which step we are in. We will do this by adding context and follow-up intents.

Remembering the users order

Firstly, lets add the follow-up intent. Because we want to be able to split up the reservation, we should add a follow-up intent for each step. My dialogflow agent that I used to test this looks like this:

enter image description here

Each follow-up intent takes one of the entities as a example phrase:

  • Missing PizzaTypes, @PizzaOption entity as trained phrase
  • Missing PizzaSize, @PizzaSize entity as trained phrase
  • Missing Quantity, @system.integer as trained phrase

After setting these up, you need to enable fulfillment for these follow-ups and add them to the same handler as with the order intent. Now that the intents are setup, we need to add the reservation context and save any valid data.

// All the order follow-ups and the order intent use the same handler.
    app.intent(
      ["Order Intent", "Complete Order - Missing PizzaType", "Complete Order - Missing Pizza Amount", "Complete Order - Missing PizzaSize"],
      (conv) => {

        // Check if any reservation info is available.
        const order = conv.contexts.get("reservation");

        // If the user has already mentioned pizza info, use context, otherwise take it from the user input.
        const pizzaType = order?.parameters.pizzaType ?? conv.parameters.pizzaType;
        const pizzaSize = order?.parameters.pizzaSize ?? conv.parameters.pizzaSize;
        const pizzaAmount = order?.parameters.pizzaAmount ?? conv.parameters.pizzaAmount;

        // Allow the fallback intents to be triggered
        conv.contexts.set("OrderIntent-followup", 2);

        // Validate the input
        if (!pizzaAmount) {
          return conv.ask("How many pizza's would you like to order?");
        }

        // Save input if valid
        conv.contexts.set("reservation", 5, { pizzaAmount });

        if (!pizzaType) {
          return conv.ask("Which pizza would you like?");
        }

        conv.contexts.set("reservation", 5, { pizzaAmount, pizzaType });

        if (!pizzaSize) {
          return conv.ask("What size should your pizza be?");
        }

        return conv.ask(`Alright, your order has been completed: ${pizzaAmount} ${pizzaSize} ${pizzaType}`);
      },
    );

The final result

enter image description here

like image 76
Jordi Avatar answered Nov 15 '22 08:11

Jordi