Home / DialogFlow ES / Handling multiple intents in your NodeJS webhooks
DialogFlow ES | NodeJS | Webhooks

Handling multiple intents in your NodeJS webhooks

This website contains affiliate links. See the disclosure page for more details. 

In a previous article, I explained how you can get started with Firebase for your Dialogflow agent.

I got a question from a reader asking how we can handle multiple actions in the same Firebase code. I will explain the process in this tutorial.

Since we already wrote some code to handle a single intent in the tutorial, we can derive an example for handling multiple intents by adding to the old index.js file.

The display message intent

The actual intent is quite simple. The user will type “display message”, and we will have an action called displayMessage, and the intent will call the webhook which will send a message to be displayed in the console.

Since the index.js already handles another action (update firebase), by adding code to handle this new intent we will handle multiple intents in our code.

Here are the steps to do this:

Create a new intent

The display Message intent, as mentioned before, is a simple intent which will have a user says message as shown below.

Add an action to the new intent

In our case, we will add the action displayMessage to the newly created intent as shown below.

Enable webhook

And we will also make sure we enable webhook for the new intent:

Modify the code in index.js

Now we need to modify our index.js code to handle this new action. Here is what it looks like:

// The Cloud Functions for Firebase SDK to create Cloud Functions and setup triggers.
const functions = require('firebase-functions');

// The Firebase Admin SDK to access the Firebase Realtime Database.
const admin = require('firebase-admin');
admin.initializeApp(functions.config().firebase);


exports.dialogflowFirebaseFulfillment = functions.https.onRequest((request, response) => {
    console.log('Request headers: ' + JSON.stringify(request.headers));
    console.log('Request body: ' + JSON.stringify(request.body));

    // An action is a string used to identify what needs to be done in fulfillment
    let action = request.body.result.action; // https://dialogflow.com/docs/actions-and-parameters
    console.log('Actions = '+ JSON.stringify(action));

    let query = request.body.result.resolvedQuery;

    // Parameters are any entites that Dialogflow has extracted from the request.
    const parameters = request.body.result.parameters; // https://dialogflow.com/docs/actions-and-parameters

    // Contexts are objects used to track and store conversation state
    const inputContexts = request.body.result.contexts; // https://dialogflow.com/docs/contexts

    if(action === 'firebase.update'){
        //let userId = app.getUser().userId;
        let userId = 'bert.macklin';
        // Check if the user is in our DB
        admin.firestore().collection('users').where('userId', '==', userId).limit(1).get()
            .then(snapshot => {
                let user = snapshot.docs[0]
                if (!user) {
                    // Add the user to DB
                    admin.firestore().collection('users').add({
                        userId: userId
                    }).then(ref => {
                        sendResponse('Added new user');
                    });
                } else {
                    // User in DB
                    sendResponse('User already exists');
                }
            });
    }else if (action === 'displayMessage'){
        sendResponse('This is a message from the NodeJS webhook');
    }

    // Function to send correctly formatted responses to Dialogflow which are then sent to the user
    function sendResponse (responseToUser) {
        // if the response is a string send it as a response to the user
        if (typeof responseToUser === 'string') {
            let responseJson = {};
            responseJson.speech = responseToUser; // spoken response
            responseJson.displayText = responseToUser; // displayed response
            response.json(responseJson); // Send response to Dialogflow
        } else {
            // If the response to the user includes rich responses or contexts send them to Dialogflow
            let responseJson = {};

            // If speech or displayText is defined, use it to respond (if one isn't defined use the other's value)
            responseJson.speech = responseToUser.speech || responseToUser.displayText;
            responseJson.displayText = responseToUser.displayText || responseToUser.speech;

            // Optional: add rich messages for integrations (https://dialogflow.com/docs/rich-messages)
            responseJson.data = responseToUser.richResponses;

            // Optional: add contexts (https://dialogflow.com/docs/contexts)
            responseJson.contextOut = responseToUser.outputContexts;

            response.json(responseJson); // Send response to Dialogflow
        }
    }
});

Note that following code snippet, which is most relevant:

if(action === 'firebase.update'){
        //let userId = app.getUser().userId;
        let userId = 'bert.macklin';
        // Check if the user is in our DB
        admin.firestore().collection('users').where('userId', '==', userId).limit(1).get()
            .then(snapshot => {
                let user = snapshot.docs[0]
                if (!user) {
                    // Add the user to DB
                    admin.firestore().collection('users').add({
                        userId: userId
                    }).then(ref => {
                        sendResponse('Added new user');
                    });
                } else {
                    // User in DB
                    sendResponse('User already exists');
                }
            });
    }else if (action === 'displayMessage'){
        sendResponse('This is a message from the NodeJS webhook');
    }

As you can see, we simply add an else if condition, check for the action name, and do the appropriate tasks. (Here it is just a hard coded response from the webhook).

Deploy the code

When deploying the code, always remember to update your Firebase Tools SDK (a best practice suggested in the Firebase documentation).

So you will execute these three commands in your command prompt:

Inside the functions folder (which contains your index.js file)

npm install firebase-functions@latest --save
npm install -g firebase-tools

Now go one step up your folder hierarchy (i.e. the project folder) and deploy using:

firebase deploy --only functions

Test it

Here is what we see in the Dialogflow test console:

The recently released Zoho SalesIQ v2 allows non-programmers to build chatbots using an easy-to-use code less bot builder. What is really unique about Zoho SalesIQ is the fact that you can also integrate AI into their code less bot builder. In my Zoho SalesIQ chatbots course, I explain how to use Zoho SalesIQ to add a chatbot to your website.

"The magic key I needed as a non-programmer"

The custom payload generator was the magic key I needed (as a non-programmer) to build a good demo with rich responses in DialogFlow Messenger. I've only used it for 30 minutes and am thrilled. I've spent hours trying to figure out some of the intricacies of DialogFlow on my own. Over and over, I kept coming back to Aravind's tutorials available on-line. I trust the other functionalities I learn to use in the app will save me additional time and heartburn.

- Kathleen R
Cofounder, gathrHealth

Similar Posts