1

I'm trying to configure my VUI to repeat a sentence in Dialogflow when it is prompted for this. Little back story, I am helping develop a social robot for elderly so repeating a sentence is a much needed feature. I just started on this project and the previous developer responsible for this is gone and not reachable, also, I have no experience in Node.js.

I am looking to use the multivocal for this. These are the steps I have done so far:

  1. Created an intent called 'Repeat'.
  2. Added training phrases for the intent
  3. Added 'multivocal.repeat' as an action
  4. Enabled webhook call for this intent
  5. In Node.js added 'intentMap.set('Repeat', repeat);' to my existing intentMap
// Run the proper function handler based on the matched Dialogflow intent name
  let intentMap = new Map();
  intentMap.set('Game_Rock_Paper_Scissors - Result', game_stone_paper_scissors);
  intentMap.set('Game_Rock_Paper_Scissors - Result - yes', game_stone_paper_scissors_again);
  intentMap.set('Conversation tree', conversation_tree);
  intentMap.set('Question date', question_date);
  intentMap.set('Question time', question_time);
  intentMap.set('Music', music);
  intentMap.set('Repeat', repeat);

Next, under the 'Fulfillment' tab, I want to enter the function inside the Inline Editor 'index.js' tab and make sure in the 'package.json' that the multivocal library is installed and usable. So far, there are a few things in my package.json

  "name": "dialogflowFirebaseFulfillment",
  "description": "This is the default fulfillment for a Dialogflow agents using Cloud Functions for Firebase",
  "version": "0.0.1",
  "private": true,
  "license": "Apache Version 2.0",
  "author": "Google Inc.",
  "engines": {
    "node": "8"
  },
  "scripts": {
    "start": "firebase serve --only functions:dialogflowFirebaseFulfillment",
    "deploy": "firebase deploy --only functions:dialogflowFirebaseFulfillment"
  },
  "dependencies": {
    "actions-on-google": "^2.2.0",
    "firebase-admin": "^5.13.1",
    "firebase-functions": "^2.0.2",
    "dialogflow": "^0.6.0",
    "dialogflow-fulfillment": "^0.5.0"
  }
}

So, how do I install the library? In the Read.me is says 'You can install it using npm install --save multivocal.' But where would I install this? Do I put this somewhere in the index.js or packages.js?

Also, in this example it shows the index.js code to be:

const Color = require('./color.js');
Color.init();

const Multivocal = require('multivocal');
exports.webhook = Multivocal.processFirebaseWebhook;

Should I just add this to the end of my index.js? Or should it be wrapped in a function? Sorry to be so not experienced in this but I hope I explained it clearly.

DeMelkbroer
  • 629
  • 1
  • 6
  • 21
  • Did you already have a look at a basic guide for NPM? It will tell you how to install packages such as multivocal using the command line. https://www.w3schools.com/nodejs/nodejs_npm.asp – Jordi Feb 05 '20 at 12:23
  • Yeah I saw those but I don't think I have a command line as I use the Inline Editor – DeMelkbroer Feb 05 '20 at 12:53

1 Answers1

4

Some answers for using multivocal using the Dialogflow Inline Editor:

How do I include this in the package.json file?

The directions for using npm are if you're writing the fulfillment locally and not using the Editor.

You need to add this line in the dependencies section:

    "multivocal": "^0.14.0"

and Dialogflow / Firebase Cloud Functions will take care of importing the library. You won't need the "actions-on-google", "dialogflow", or "dialogflow-fulfillment" libraries, so the section can look something like this:

  "dependencies": {
    "firebase-admin": "^5.13.1",
    "firebase-functions": "^2.0.2",
    "multivocal": "^0.14.0"
  }

How do I write my index.js?

The simple example assumes that you can put your configuration and code in a separate file ("color.js" in the example). Since you can't do that with the Inline Editor, the general boilerplate of your code will be something like this:

// Import the library on the first line, so you can call methods on it to setup your configuration
const Multivocal = require('multivocal');

// Your configuration and code go here

// Setup the webhook as the final line
exports.dialogflowFirebaseFulfillment = Multivocal.processFirebaseWebhook;

Where do the Intent Handler registration and functions go?

Unlike the dialogflow-fulfillment library, multivocal doesn't use an explicit intentMap. It maintains one itself, so to register an Intent Handler function you would use something like

Multivocal.addIntentHandler( intentName, handlerFunction );

BUT keep in mind that handler functions are also a little different.

What? How are they different?

Multivocal has a lot of things handled through configuration, rather than code. So there is no direct counterpart to the agent.add() function call that you'd have with dialogflow-fulfillment or the actions-on-google library.

Instead, your Intent Handler function should perform any logic, database calls, or whatever to get values that will be used in responses and save them in the Environment. Every Handler should return a Promise that contains the Environment.

You should also set configuration for your Intent - the most common of which is to set the possible "Response" templates. The most simple response templates just include text, and where to insert values from the environment. It is also best practice to prompt the user for what they can do next, so we might setup a "Suffix" template to use by default, or one to use for specific Intents, Actions, or Outents.

So if you had an Intent named "color.favorite", and had a value in the environment called "color" (that your handler may have loaded from a database), the configuration for this response in English may look something like this. It also includes a default suffix to prompt the user what they can do next.

  const config = {
    Local: {
      en: {
        Response: {
          "Intent.color.favorite": [
              "{{color}} is one of my favorite colors as well.",
              "Oh yes, {{color}} can be quite striking.",
              "I can certainly understand why you like {{color}}."
          ]
        },
        Suffix: {
          Default: [
            "What other color do you like?"
            "Tell me another color."
          ]
        }
      }
    }
  }

and you would register this configuration with

  new Multivocal.Config.Simple( config );

You can (and are expected to) register multiple configurations, although you can combine them in one object. So the Response section above could contain response sections for each of your Intents, by name.

Ok, but how do I handle a "repeat" Intent?

All you need to do is provide an Intent that has its "Action" set to "multivocal.repeat" in the Dialogflow UI and that has the webhook enabled. So something like this would work:

Intent illustrating where to configure the Action value

Multivocal already has registered a handler and configuration based on this.

If you want to change the possible responses, you can add configuration for the "multivocal.repeat" Action. Which may look something like this:

const enRepeat = [
  "Sorry about that, let me try again.",
  "I said:"
];

const config = {
  Local: {
    en: {
      Response: {
        "Action.multivocal.repeat": enRepeat
      }
    }
  }
}

and then either combine this configuration with other configurations you've written, or load it as above.

To emphasize - there is no need for you to write any code for this, just some optional configuration.

Prisoner
  • 49,922
  • 7
  • 53
  • 105
  • I have slightly added to my original question. So I think I should now added a function called 'repeat(agent)' in the second part of your boilerplate which uses the library function multivocal.repeat, is that correct? Would the implementation look something like: https://developers.google.com/assistant/conversational/tips#nodejs ? – DeMelkbroer Feb 05 '20 at 13:24
  • There is no need for you to add an implementation - multivocal has mostly done that for you. See the updates to the answer. – Prisoner Feb 05 '20 at 14:26
  • Is it true that if you use: 'exports.dialogflowFirebaseFulfillment = Multivocal.processFirebaseWebhook;' you cannot use 'exports.dialogflowFirebaseFulfillment = functions.https.onRequest((request, response) => ... ' ? The robot already has functions implement in this way so maybe using multivocal is not the easiest way after all in that sense. Would VoiceRepeater offer an escape in this sense? – DeMelkbroer Feb 05 '20 at 15:27
  • That is correct. As I mentioned both above and in other questions - multivocal is a library that does the same thing as dialogflow-fulfillment, so it replaces it. The two do not work together. In theory, VoiceRepeater would work, but it was designed for the actions-on-google v1 library and would require extensive rewriting to work with the dialogflow-fulfillment library. But the techniques outlined there and on the Actions on Google page you linked to above could both be applied if you choose not to switch to multivocal. – Prisoner Feb 05 '20 at 15:40