How to Create a Chatbot with Dialogflow, NodeJS, and Webhooks

Published on Jul 19, 2019

13 min read

NODEJS

cover_image

Originally published at Crowdbotics

Chatbots are the hottest things in the modern digital world. Every day, organizations and individuals are powering their digital products such as websites or messenger apps to provide conversational experiences for their users. Each conversational experience depends on the implementation of the chatbot to either be a good or poor experience for the user. The modern day world is living in the technology wave of Artificial Intelligence, and chatbots are a massive part of it.

In this tutorial, you are going to be introduced to an easy to use tool for such uses cases known as Dialogflow. Formerly known as API.AI, it can be customized to provide information such as weather in your user's city or information about a movie they like to see. This customization, however, can only be applied using a third party API that is consistent in delivering results for the specific search term.

By providing a step by step on setting up and running the chatbot and how to use a third party API with Dialogflow. You are going to create a custom webhook using Nodejs, deploy it as a service, and then use it with your Dialogflow setups to develop agents and intents. What are webhooks, you ask?

A Webhook is a simple HTTP callback that gets triggered based on some event. These events are defined by the user, for example, publishing a comment to blog post, or publishing a new tweet on your Twitter app.

You are going to build a movie chatbot that provides information about a movie using The Open Movie Database API. The webhooks will be used to fetch the details of a film.

Table of Contents

  • Requirements
  • Create a Node Server
  • Fetching the Movie
  • Deploy the Webhook on Heroku
  • Setup Dialogflow
  • Create Training Phrases
  • Enable the Webhook
  • Conclusion

Requirements

🔗

To follow this tutorial, you need the following:

  • Nodejs v8.x.x or higher installed along with npm/yarn as the package manager
  • Github Account
  • Crowdbotics App builder Platform account (preferably log in with your valid Github ID)
  • Dialogflow account (you can use your Google ID)
  • OMDb API API Key: make sure when you register the account, you request for an API key. It is very to get one, register an account.
  • Heroku or some similar service to deploy the webhook

Create a Node Server

🔗

The following steps have to perform inside the project directory you have set up to create the Nodejs server. Once you are inside the server folder, make sure you run the following commands sequentially using a terminal window. The first command will initialize the server directory as a node server and generate a package.json file. The second command will let you install all the required dependencies.

# to initialize
npm init --yes
# to install dependencies
npm install -save express dotenv

Once all the dependencies are installed, let us bootstrap a small server and see if everything is working or not. Create a new file index.js and add the following snippet to it.

1const express = require('express');
2// will use this later to send requests
3const http = require('http');
4// import env variables
5require('dotenv').config();
6
7const app = express();
8const port = process.env.PORT || 3000;
9
10app.use(express.json());
11app.use(express.urlencoded({ extended: true }));
12
13app.get('/', (req, res) => {
14 res.status(200).send('Server is working.');
15});
16
17app.listen(port, () => {
18 console.log(`🌏 Server is running at http://localhost:${port}`);
19});

The above server is simple as it can be with only one / home route for now. This route is created now only to test whether the server being bootstrapped in this section is going to work or not. Sometimes small errors are time wasters, so it is better to check out. The module dotenv enable the file to read environment variables and their values from the file .env. Here is how the .env the file looks like.

API_KEY=XXXX

The Xs are going to be the value of the API key that you have got from registering an account at OMDB API. Replace the value of these Xs with that key. Now, go to the terminal window and execute the command node index.js. This will prompt with the message you have defined in the above snippet. Visit the URL http://localhost:3000 from the browser window, and you will get the following result.

Fetching the Movie

🔗

In this section, you are going to create a route called /getmovie. It is going to be a post request. This request is going to search for the movie specified on the user's input. If that movie exists, it will return the user with the details of the movie such as the name itself, the year it was released, a summarised plot, and so on.

Open index.js file and the following after you have defined middleware functions.

1app.post('/getmovie', (req, res) => {
2 const movieToSearch =
3 req.body.queryResult &&
4 req.body.queryResult.parameters &&
5 req.body.queryResult.parameters.movie
6 ? req.body.result.parameters.movie
7 : '';
8
9 const reqUrl = encodeURI(
10 `http://www.omdbapi.com/?t=${movieToSearch}&apikey=${process.env.API_KEY}`
11 );
12 http.get(
13 reqUrl,
14 responseFromAPI => {
15 let completeResponse = '';
16 responseFromAPI.on('data', chunk => {
17 completeResponse += chunk;
18 });
19 responseFromAPI.on('end', () => {
20 const movie = JSON.parse(completeResponse);
21
22 let dataToSend = movieToSearch;
23 dataToSend = `${movie.Title} was released
24 in the year ${movie.Year}. It is directed
25 by ${movie.Director} and stars ${movie.Actors}.\n Here some glimpse of the plot: $
26 {movie.Plot}.
27 }`;
28
29 return res.json({
30 fulfillmentText: dataToSend,
31 source: 'getmovie'
32 });
33 });
34 },
35 error => {
36 return res.json({
37 fulfillmentText: 'Could not get results at this time',
38 source: 'getmovie'
39 });
40 }
41 );
42});

The http module is from Nodejs core. It is going to send the request which is the variable reqUrl and a callback function responseFromAPI. This function is going to trigger two events: data and end. The event data is going to return the information about the movie from API in chunks.

The completeResponse holds the data is parsed into JSON when the response from the API is ended. The customized response that is being returned in the above route's snippet should contain the field fulfillmentText and error response for cases that might now work at all.

On a side note, here is how an object for a specific movie data in JSON looks like from the OMDB API.

1{
2 "Title": "Flashbacks of a Fool",
3 "Year": "2008",
4 "Rated": "R",
5 "Released": "17 Oct 2008",
6 "Runtime": "109 min",
7 "Genre": "Drama",
8 "Director": "Baillie Walsh",
9 "Writer": "Baillie Walsh",
10 "Actors": "Emile Robert, Scoutt Lowe, Daniel Craig, Julie Ordon",
11 "Plot": "A fading Hollywood star looks back at
12 the days of his youth as he returns home from his
13 best friend's funeral.",
14 "Language": "English",
15 "Country": "UK",
16 "Awards": "N/A",
17 "Poster": "https://m.media-amazon.com/images/M/
18 MV5BMTIzMDk0MDc3OV5BMl5BanBnXkFtZTcwODMwODY5MQ@@.
19 _V1_SX300.jpg",
20 "Ratings": [
21 { "Source": "Internet Movie Database", "Value": "6.8/10" },
22 { "Source": "Rotten Tomatoes", "Value": "38%" }
23 ],
24 "Metascore": "N/A",
25 "imdbRating": "6.8",
26 "imdbVotes": "11,348",
27 "imdbID": "tt1037218",
28 "Type": "movie",
29 "DVD": "22 Sep 2008",
30 "BoxOffice": "N/A",
31 "Production": "Anchor Bay Entertainment",
32 "Website": "http://www.thefilmfactory.co.uk/flashbacks/",
33 "Response": "True"
34}

From this considerable object, you are only using some amount of information described in the previous snippet. To test that the result is being fetched from the OMDB API, start the server by going to the terminal window. Execute command node index.js.

Open your favorite rest clients such as Postman or Insomnia. Enter the URL http://localhost:3000/getmovie and even though it is POST request, and you will have to enter the parameters as shown below. Let us test out if the API is returning the details of the movie name entered or not. In the below image, you can verify that the information related to the data is being replaced.

Deploy the Webhook on Heroku

🔗

Since the route /getmovie is working, it is time to deploy the webhook you successfully build in the previous step. Login to your Heroku account or if you do not have one, create an account. You can upload up to five web applications that can run for free to some number of hours (called as dynos).

Before you proceed with any of the steps below, in the package.json file, make sure the start script exists as specified below.

1"scripts": {
2 "start": "node index.js",
3 "test": "echo \"Error: no test specified\" && exit 1"
4}

Once you log in, you will be welcomed by the screen known as Dashboard. Create on the button New on the top right corner and then create choose Create new app.

Fill in the name of the application. Once you have entered the details, click the button Create app.

Now, you will be welcomed by the following page that has instructions to deploy your current Node app. If you are using Github, go ahead and choose the Connect to Github deployment method. I am going to use heroku-cli.

To proceed with the following set of instructions, also as mentioned in the above screen under the section Deploy using Heroku Git. What this means is that the instance of your complete Node application is going to be deployed from the local development environment where the application is currently located. Once you have installed the Heroku CLI, enter the following command to proceed. Also, if you are using the Crowdbotics platform to generate the current demo app or have initialized the directory, you are working using the command git init, ignore the section Clone the repository in the above image.

# login
heroku login
# to deploy
$ git add .
$ git commit -am "deploy"
$ git push heroku master

The only thing to notice here is that you are not going to git push to the origin but heroku. Once the deployment is done, you will get a message like below in the terminal window.

remote: https://getmoviehook.herokuapp.com/ deployed to Heroku
remote:
remote: Verifying deploy... done.
To https://git.heroku.com/getmoviehook.git
* [new branch] master -> master

You will get the URL https://getmoviehook.herokuapp.com/ from the above deployment procedure. To test it out, you cannot merely send a GET request by visiting the URL https://getmoviehook.herokuapp.com/getmovie from a browser window. You can again use a REST client like Postman. Just replace the localhost URL with deployed one that is previously mentioned.

You will get successful results.

Setup Dialogflow

🔗

Dialogflow is a Natural Language Processing (NLP) service from Google. It has many integrations, SDKs for programming languages and some prebuilt agents. It works very straightforward with Google Assistant. Visit the Dialogflow website and create a new account or log-in with your existing Google ID.

Once you are logged in, you will be welcomed by a screen that consists of different Agents.

Click on the Create Agent button to make one for yourself. Name it something similar to OMDBbot. Fill in the details like below.

After filling out the details, click on the button Create.

Generally, for small applications, you will have one agent. In Dialogflow, the basic flow of conversation involves these steps:

  • The user giving input in the form of a query
  • Your Dialogflow agent parses the input from the training phrases
  • Your agent returns a response back to the user

These agents understand the varied nuances of human language. They can translate that to standard and structured meaning that chatbot applications and services can understand. Each agent contains different intents. The intent is the action taken based on the user's input. It can be the response sent back to the user in a chatbot application. It can contain different types of responses or actions. The next step in the process is to create your first intent.

Click on the button Create intent and fill in the name getmovie. You can name your intent anything.

Intent can be a simple text response that is displayed back to the user or a set of trained phrases. There are also actions and parameters that extract information from user queries. Examples of this kind of information include dates, times, names, places, and more.

Create Training Phrases

🔗

Let us create new training phrases in this section. To create a new phrase, go to the section Training phrases and a unique user expression as shows below.

For the movie chatbot, each user expression is going to contain the name of the movie. The Dialogflow agent is not smart enough to extract the name of the movie out of the user's expression. You have to provide an entity that can highlight the name of the movie every time a new training phrase is introduced to the bot.

From the sidebar menu, go to the entity section and click on the button Create Entity. Fill in the name of your entity as movie because this is what is being passed inside the webhook's request body. From the server, remember the following line:

1req.body.queryResult.parameters.movie;

Once you have saved your entity, go back to the intent.

Enable the Webhook

🔗

To test out that everything is working, let us use the default response provided by the Dialogflow intent. As shown below, on the right-hand side of the screen, you can test out by entering a user expression. The movie chatbot will return the default response.

This is okay and verifies that the intent has been created successfully. Now, to use the real-time data from the OMDB API, you are going to enable the webhook. From the sidebar menu, go to the Fulfillment section. You will be welcomed by the following screen.

Enable the Webhook and then enter the URL of the deployed endpoint.

Once that is done, go back to the Intents section, and scroll down to the bottom of the web page. There is a Fulfillment section. Toggle the button to Enable webhook call for this intent.

Once that is done, go to the right side of the screen to test it out. Fill in the user expression similar to a training phrase you have provided earlier. The agent will get a response back with the details of the movie.

Conclusion

🔗

You have successfully created, deployed, and tested a Nodejs Webhook for Dialogflow chatbot application. By the end of this tutorial, we are sure you have learned how easy it is to create a new chatbot agent using Dialogflow. The possibilities of using a powerful API such as Dialogflow are endless. In no time, you can build up your own chatbot interface for front-end clients using Reactjs, Angular, and even mobile cross-platform framework like React Native. We hope this tutorial provided you an easy walkthrough to grab the concepts and build something of your own.


More Posts

Browse all posts

Mico Dan

I'm a FullStack Developer and a technical writer. In this blog, I write about Technical writing, Node.js, React Native and Expo.