DialogFlow CX calculate values

2.6k views Asked by At

I collect data from user input and to finish I want to calculate a value based on that input.

For example, I collect the person's weight and then the height to calculate the person's BMI, General Flow. How can I calculate BMI in the last step and show the result to the user?

2

There are 2 answers

0
Riel On

In addition to jess’ post, here's another approach you might try in order to calculate the BMI based on the user’s inputs. Here are the differences from the first approach provided:

  • Composite custom entities

    This will allow you to create entities wherein you can easily extract the numbers provided by the user instead of getting a string and converting this string to a number in your webhook. With these entities, it’s not necessary to list every other option for height and weight.

  • Form Parameters

    Instead of defining parameters in an intent adding the parameters, you can add the parameters in a page where the agent can interact with the end-user for multiple turns until the parameters are fulfilled.

Here’s the step-by-step procedure to implement these features.

  1. Create composite custom entities in order to collect form parameters from the end-user for the page. You can design your custom entities as follow:

    a. Create custom entities for height and weight unit names.

    unit-height unit-weight

    b. Then, create the composite custom entities containing the number and the unit names for each. Note that you should add an alias to ensure that these values will be returned individually.

    weight height

  2. Create an intent that will be used to trigger the start of the flow. Note to add enough training phrases for what end-users might type or say.

    intent

  3. Create a page where you can transition from your Default Start Page when the Intent.BMI intent has been triggered. This page will also be used to collect the form parameters which you can use to calculate the BMI.

    page

  4. Create the flow by adding an intent route for Intent.BMI intent where the transition is BMI page. The flow would look like this.

    flow

  5. Now, proceed to the BMI page and add the form parameters accordingly. Make sure to set these parameters as required. Add condition routes as well wherein you can return the response from your webhook once the parameters are fulfilled.

    a. The BMI page may look like this. BMI page

    b. For parameters, here’s an example on how to add these parameters. parameters

    c. For condition routes, I added a condition to return a response once the form parameters are fulfilled. If not yet fulfilled, the agent will keep prompting the user for a valid input. I used a webhook to return the responses wherein this webhook extracted the value for each parameter and was able to calculate the BMI. condition

  6. In your webhook, create a function that will extract the form parameters and calculate the BMI based on these values. Here’s another example using Node.js.

index.js

'use strict';

const express = require('express');
const bodyParser = require('body-parser');
const app = express();

var port = process.env.PORT || 8080;

app.use(
    bodyParser.urlencoded({
      extended: true
    })
);
  
app.use(bodyParser.json());

app.post('/BMI', (req, res) => processWebhook4(req, res));

var processWebhook4 = function(request, response ){

    const params = request.body.sessionInfo.parameters;
    
    var heightnumber = params["height.number"];
    var weightnumber = params["weight.number"];
    var heightunit = params["height.unit-height"]
    var weightunit = params["weight.unit-weight"]
    var computedBMI;

    if (heightunit == "cm" && weightunit == "kg") { //using metric units
        computedBMI = ((weightnumber/heightnumber/heightnumber )) * 10000;
    } else if (heightunit == "in" && weightunit == "lb") { //using standard metrics
        computedBMI = ((weightnumber/heightnumber/heightnumber )) * 703;
    }

    const replyBMI = {
        'fulfillmentResponse': {
            'messages': [
                {
                    'text': {
                        'text': [
                            'This is a response from webhook! BMI is ' + computedBMI
                        ]
                    }
                }
            ]
        }
    }
    response.send(replyBMI);
}

app.listen(port, function() {
    console.log('Our app is running on http://localhost:' + port);
});

package.json

{
   "name": "cx-test-functions",
   "version": "0.0.1",
   "author": "Google Inc.",
   "main": "index.js",
   "engines": {
       "node": "8.9.4"
   },
   "scripts": {
       "start": "node index.js"
   },
   "dependencies": {
       "body-parser": "^1.18.2",
       "express": "^4.16.2"
   }
}
  1. Here's the result. result
0
Jessica Rodriguez On

In order to calculate the values of the input you collected from the bot, you will need to set-up a code using a webhook to calculate the BMI and connect the Webhook URL in the Dialogflow CX Console. Here’s a simple flow you can try:

  1. First, create composite custom entities which can be used to match values in the training phrases in an intent, for example, weight and height. https://cloud.google.com/dialogflow/cx/docs/concept/entity#custom.

enter image description here

enter image description here

  1. Then create an intent with training phrases that match the values with the entities you created.

enter image description here

  1. There are two ways to set the parameter values: Intent parameters and Form parameters. In my example, I used Intent parameters to get the parameter values that are stored when you query the flow of the conversation from the “Test Agent” section:

enter image description here

  1. Then prepare your code in the webhook to process the values to calculate the BMI: https://cloud.google.com/dialogflow/cx/docs/concept/webhook. Here’s a sample code using NodeJS:

index.js

const express = require('express') // will use this later to send requests 
const http = require('http') // import env variables 
require('dotenv').config()
const app = express();
const port = process.env.PORT || 3000

/// Google Sheet 
const fs = require('fs');
const readline = require('readline');

app.use(express.json())
app.use(express.urlencoded({ extended: true }))
app.get('/', (req, res) => { res.status(200).send('Server is working.') })
app.listen(port, () => { console.log(` Server is running at http://localhost:${port}`) })

app.post('/bmi', (request, response) => {
    let params = request.body.sessionInfo.parameters;
    let height = getNumbers(params.height); // 170 cm from the example
    let weight = getNumbers(params.weight); // 60 kg from the example

    let bmi = (weight/(height/100*height/100));

    let fulfillmentResponse = {
        "fulfillmentResponse": {
            "messages": [{
                "text": {
                    "text": [
                        bmi 
                    ]
                }
            }]
        }
    };
    response.json(fulfillmentResponse);
});

// Extract number from string
function getNumbers(string) {
  string = string.split(" ");
  var int = ""; 
  for(var i=0;i<string.length;i++){
    if(isNaN(string[i])==false){
    int+=string[i];
    }
  }
 return parseInt(int);
}

package.json

{
  "name": "server",
  "version": "1.0.0",
  "description": "",
  "main": "index.js",
  "scripts": {
    "start": "node index.js",
    "test": "echo \"Error: no test specified\" && exit 1"
  },
  "keywords": [],
  "author": "",
  "license": "ISC",
  "dependencies": {
    "dotenv": "^8.2.0",
    "express": "^4.17.1"
  }
}
  1. Deploy your webhook
  2. Add the webhook URL in the Dialogflow CX Console

enter image description here

  1. Use the webhook in Dialogflow CX Page wherein you will need to set the response for BMI output:

enter image description here

Here's the result: enter image description here