Search code examples
node.jsdialogflow-esactions-on-googlechatbotdialogflow-es-fulfillment

how to extract parameters from the context for list response using dialogflow fulfillment


Is it possible to pass the value of selected list item to any other intent. in my case I am passing a list and user select an item from the list, now I want to show this selected item name in another intent but I can't do that. is anything wrong with my code

code runs properly only problem is instead of "selected item name" it returns "undefined".

this is my code

'use strict';

const functions = require('firebase-functions');
const {dialogflow, SimpleResponse} = require ('actions-on-google');
const {Suggestions, List, Image, BasicCard} = require ('actions-on-google');

const SHOW_PHONE_INTENT = 'Default Welcome Intent';
const FALLBACK_INTENT = 'Default Fallback Intent';
const SELECTED_PHONE_INTENT = 'SelectedPhoneIntent';
const ADD_TO_CART_INTENT = 'AddToCartIntent';

const AppContexts = {AWAITING_PHONE: 'awaiting-phone'};
const AppContexts1 = {AWAITING_REPLY: 'awaiting-reply'};

const app = dialogflow();

const PhoneDetail = {
  'Phone1': {
    text: `screen size = 5 inches  \n
    price = $100`,
    subtitle: 'This is phone1',
    title: 'Phone1 Details',
    image: new Image({
      url: 'https://img.icons8.com/plasticine/2x/name.png',
      alt: 'pic1',
    }),
    display: 'WHITE',
  };

  'Phone2': {
    text: `screen size = 5.5 inches  \n
    price = $150`,
    subtitle: 'This is phone2',
    title: 'Phone2 Details',
    image: new Image({
      url: 'https://img.icons8.com/plasticine/2x/name.png',
      alt: 'pic2',
    }),
    display: 'WHITE',
  };

  'Phone3': {
    text: `screen size = 6 inches  \n
    price = $200`,
    subtitle: 'This is phone3',
    title: 'Phone3 Details',
    image: new Image({
      url: 'https://img.icons8.com/plasticine/2x/name.png',
      alt: 'pic3',
    }),
    display: 'WHITE',
  };  
};

app.intent(FALLBACK_INTENT, (conv) => {
    conv.ask("Sorry! Could you please repeat that?");
});

app.intent(SHOW_PHONE_INTENT, (conv) => {
  conv.contexts.set(AppContexts.AWAITING_PHONE, 1);
  conv.ask("Here's the list of phone's.");
  conv.ask(new List({
    title: "Select a phone to see details.",
    items: {
      "Phone1": {
        title: "phone1",
        description: "Click here to check phone1 details.",
        image: new Image({
          url: 'https://img.icons8.com/plasticine/2x/name.png',
          alt: 'p1',
        }),
      },
      "Phone2": {
        title: "phone2",
        description: "Click here to check phone2 details.",
        image: new Image({
          url: 'https://img.icons8.com/plasticine/2x/name.png',
          alt: 'plc',
        }),
      },
      "Phone3": {
        title: "phone3",
        description: "Click here to check phone3 details.",
        image: new Image({
          url: 'https://img.icons8.com/plasticine/2x/name.png',
          alt: 'obj',
        }),
      },
    },
  }));
});

app.intent(SELECTED_PHONE_INTENT, (conv, input, option) => {
    const context = conv.contexts.get(AppContexts.AWAITING_PHONE);
    if (option) {
      conv.ask(`${option} Details`);
      conv.ask(new BasicCard(PhoneDetail[option]));
      conv.ask(new Suggestions(['Show List', 'Add to Cart']));
    } else {
      conv.close('Sorry! there might be some issue, please contact support.');
    }
    conv.contexts.set(AppContexts1.AWAITING_REPLY, 1);
});

app.intent(ADD_TO_CART_INTENT, (conv, parameters) => {
  const context1 = conv.contexts.get(AppContexts1.AWAITING_REPLY);
  const selectedPhone = context1.parameters;
  const qty = context1.parameters.qty;
  if ('Add to Cart'){
    let missingSlots = [];
    if (!qty) { missingSlots.push('qty'); }
    if (missingSlots.length === 1){
      conv.ask(`How many phone's do you need?`);
    } else {
      conv.ask(`You have ordered ${qty} ${selectedPhone}. `);
      conv.close("Thanks for shopping with us.");
    }
  } else {
    conv.close('Sorry! there might be some issue, please contact support.');
  }
});

exports.dialogflowFirebaseFulfillment = functions.https.onRequest(app);

let suppose user selects phone1 and orders 2 qty

then my response comes as "You have ordered 2 undefined. Thanks for shopping with us."

need help in getting the selected item name instead of undefined.

Here is the Intent that handles selecting the item from the list:

SelectedPhoneIntent


Solution

  • The issue is that you're not actually setting the parameters in the Context, so no values are preserved between the calls to your webhook.

    In the SELECTED_PHONE_INTENT handler, the line should be something more like

    conv.contexts.set(AppContexts1.AWAITING_REPLY, 5, {
      phone: option
    });
    

    while in the ADD_TO_CART_INTENT handler, you would get this information with a line such as

    const selectedPhone = context1.parameters.phone;