Build a Chatbot from Scratch - Dialogflow on Node.js

Build a Chatbot from Scratch - Dialogflow on Node.js

Build a fullstack chatbot that can intelligently interact with your users, featuring Dialogflow, Cloud Functions, and Angular - make it possible for the average developer to deliver excellent (and affordable) customer service at scale - Fuilding conversational experiences has never been easier thanks to the Dialogflow conversation platform.

Dialogflow is a free tool on Google Cloud for creating voice and text conversational interfaces. It uses Natural Language Processing NLP technology, allowing you to create experiences similar to Google Assistant or Amazon Alexa...

======================================

Thanks for reading

If you liked this post, share it with all of your programming buddies!

Follow me on Facebook | Twitter

Learn More

☞ NestJS Zero to Hero - Modern TypeScript Back-end Development

☞ The Complete Node.js Developer Course (3rd Edition)

☞ Complete Next.js with React & Node - Beautiful Portfolio App

☞ Angular & NodeJS - The MEAN Stack Guide

☞ NodeJS - The Complete Guide (incl. MVC, REST APIs, GraphQL)

☞ Docker for Node.js Projects From a Docker Captain

☞ Intro To MySQL With Node.js - Learn To Use MySQL with Node!

☞ Node.js Absolute Beginners Guide - Learn Node From Scratch


Top 7 Most Popular Node.js Frameworks You Should Know

Top 7 Most Popular Node.js Frameworks You Should Know

Node.js is an open-source, cross-platform, runtime environment that allows developers to run JavaScript outside of a browser. In this post, you'll see top 7 of the most popular Node frameworks at this point in time (ranked from high to low by GitHub stars).

Node.js is an open-source, cross-platform, runtime environment that allows developers to run JavaScript outside of a browser.

One of the main advantages of Node is that it enables developers to use JavaScript on both the front-end and the back-end of an application. This not only makes the source code of any app cleaner and more consistent, but it significantly speeds up app development too, as developers only need to use one language.

Node is fast, scalable, and easy to get started with. Its default package manager is npm, which means it also sports the largest ecosystem of open-source libraries. Node is used by companies such as NASA, Uber, Netflix, and Walmart.

But Node doesn't come alone. It comes with a plethora of frameworks. A Node framework can be pictured as the external scaffolding that you can build your app in. These frameworks are built on top of Node and extend the technology's functionality, mostly by making apps easier to prototype and develop, while also making them faster and more scalable.

Below are 7of the most popular Node frameworks at this point in time (ranked from high to low by GitHub stars).

Express

With over 43,000 GitHub stars, Express is the most popular Node framework. It brands itself as a fast, unopinionated, and minimalist framework. Express acts as middleware: it helps set up and configure routes to send and receive requests between the front-end and the database of an app.

Express provides lightweight, powerful tools for HTTP servers. It's a great framework for single-page apps, websites, hybrids, or public HTTP APIs. It supports over fourteen different template engines, so developers aren't forced into any specific ORM.

Meteor

Meteor is a full-stack JavaScript platform. It allows developers to build real-time web apps, i.e. apps where code changes are pushed to all browsers and devices in real-time. Additionally, servers send data over the wire, instead of HTML. The client renders the data.

The project has over 41,000 GitHub stars and is built to power large projects. Meteor is used by companies such as Mazda, Honeywell, Qualcomm, and IKEA. It has excellent documentation and a strong community behind it.

Koa

Koa is built by the same team that built Express. It uses ES6 methods that allow developers to work without callbacks. Developers also have more control over error-handling. Koa has no middleware within its core, which means that developers have more control over configuration, but which means that traditional Node middleware (e.g. req, res, next) won't work with Koa.

Koa already has over 26,000 GitHub stars. The Express developers built Koa because they wanted a lighter framework that was more expressive and more robust than Express. You can find out more about the differences between Koa and Express here.

Sails

Sails is a real-time, MVC framework for Node that's built on Express. It supports auto-generated REST APIs and comes with an easy WebSocket integration.

The project has over 20,000 stars on GitHub and is compatible with almost all databases (MySQL, MongoDB, PostgreSQL, Redis). It's also compatible with most front-end technologies (Angular, iOS, Android, React, and even Windows Phone).

Nest

Nest has over 15,000 GitHub stars. It uses progressive JavaScript and is built with TypeScript, which means it comes with strong typing. It combines elements of object-oriented programming, functional programming, and functional reactive programming.

Nest is packaged in such a way it serves as a complete development kit for writing enterprise-level apps. The framework uses Express, but is compatible with a wide range of other libraries.

LoopBack

LoopBack is a framework that allows developers to quickly create REST APIs. It has an easy-to-use CLI wizard and allows developers to create models either on their schema or dynamically. It also has a built-in API explorer.

LoopBack has over 12,000 GitHub stars and is used by companies such as GoDaddy, Symantec, and the Bank of America. It's compatible with many REST services and a wide variety of databases (MongoDB, Oracle, MySQL, PostgreSQL).

Hapi

Similar to Express, hapi serves data by intermediating between server-side and client-side. As such, it's can serve as a substitute for Express. Hapi allows developers to focus on writing reusable app logic in a modular and prescriptive fashion.

The project has over 11,000 GitHub stars. It has built-in support for input validation, caching, authentication, and more. Hapi was originally developed to handle all of Walmart's mobile traffic during Black Friday.

Learn how to build a SlackBot with Node.js and SlackBots.js

Learn how to build a SlackBot with Node.js and SlackBots.js

In this article, I'll walk you through building your first Slack bot from start to finish with Node.js and SlackBots.js

Slack is an American cloud-based set of proprietary team collaboration software tools and online services, developed by Slack Technologies. Slack is a workspace where teams can communicate and collaborate.

Teamwork in Slack happens in channels — a single place for messaging, tools and files — helping everyone save time and collaborate.

One of the awesome features of Slack is Slack Apps, integrations and Slack Bots.

A Slack bot is a type of Slack App designed to interact with users via conversation. Your bot can send DMs, it can be mentioned by users, it can post messages or upload files, and it can be invited to channels. Cool right?

If you use Slack already, you should be familiar with some creative Slack bots like Standupbot, Birthdaybot and more.

In this article, I'll walk you through building your first Slack bot from start to finish with Node.js and SlackBots.js

SlackBot Description

We're going to build a simple Slackbot that displays random inspiring techie quotes and jokes for developers/designers.

I built a chrome extension that displays random inspiring techie quotes for developers/designers on your new tab (you can download it here). We'll be using the quotes JSON from this extension as our quotes API and the Chuck Norris Jokes API for the jokes.

When a user mentions our bot and adds inspire me, the bot returns a random quote from inspireNuggets. When the user types random joke, it returns a random joke from the Chuck Norris API. And when the user types help, it returns the instruction guide.

@inspirenuggets inspire me
@inspirenuggets random joke
@inspirenuggets help

This article is not really about what we'll be building - it's just to show you the concept behind Slack bots and how to build yours. After you go through it, you can think about something else and build a different bot, as there're many possibilities.

You can clone or fork the final project here.

Pretty interesting right? Let's get started.

Prerequisites

We'll build this bot with Node.js and SlackBots.js. You don't need to know how to write Node.js, since I'll walk you through it. Still, knowing it is an advantage. You should also have

Setup environment

Let's set up and install Node.js and Npm first.

  • Download node here. If you have it installed already, skip this step. If you prefer to use a package manager to install, read this for all operating systems.
  • Check if you have Node installed
node -v

  • Node.js comes with Npm, so you don't have to install that again.
npm -v

Now that we have Node.js setup, let's initialize our project.

Create your project directory (I called mine Slackbot) and initialize git:

git init

Next, create an index.js file:

touch index.js

And initialize Npm:

npm init

Simply answer all questions that come afterwards. If you're having issues, here's my own package.json:

{
  "name": "slackbot",
  "version": "1.0.0",
  "description": "A simple Slackbot that displays random inspiring techie quotes for developers/designers.",
  "main": "index.js",
  "scripts": {
    "start": "index.js"
  },
  "repository": {
    "type": "git",
    "url": "git+https://github.com/BolajiAyodeji/slackbot.git"
  },
  "author": "Bolaji Ayodeji",
  "license": "MIT",
  "bugs": {
    "url": "https://github.com/BolajiAyodeji/slackbot/issues"
  },
  "homepage": "https://github.com/BolajiAyodeji/slackbot#readme"
}

Install Dependencies

Now let's install and setup all the libraries we need.

SlackBots.js

SlackBots.js is a Node.js library for easy operation with the Slack API.

npm install slackbots

In index.js:

const SlackBot = require('slackbots');

Axios

Axios is a promise-based HTTP client for the browser and node.js. If you know Fetch or AJAX, this is just a library that does the same thing with way cooler features. You can see them here.

npm install axios

In index.js:

const axios = require('axios')

Nodemon

To run a script in Node.js, you have to run node index.js. Whenever you make changes to this file, you have to rerun node index.js. This sucks when you're making so many changes like we'll be doing. That's why we need nodemon, a tool that helps develop node.js based applications by automatically restarting the node application when file changes in the directory are detected.

npm install -g nodemon

In package.json, locate the scripts section and add a new start script:

"scripts": {
    "start": "node index.js"
  }

If you run npm start, the file will run but won't restart on change. To fix this, use the nodemon we installed instead of node like so:

"scripts": {
    "start": "nodemon index.js"
  }

Dotenv

I won't explain this in-depth. In a few days, I'll publish an article around environmental variables, but for now just know that we use this to hide secret keys and tokens like the Slack Access Token we would be using. This way you don't have to push your secret keys to GitHub.

There are several ways to do this, but I prefer using dotenv. Dotenv is a zero-dependency module that loads environment variables from a .env file into process.env.

npm install dotenv

In index.js:

const dotenv = require('dotenv')

dotenv.config()

After all installation, your package.json should look like this:

{
  "name": "inspireNuggetsSlackBot",
  "version": "1.0.0",
  "description": "A simple Slackbot that displays random inspiring techie quotes and jokes for developers/designers.",
  "main": "index.js",
  "scripts": {
    "start": "nodemon index.js"
  },
  "repository": {
    "type": "git",
    "url": "git+https://github.com/BolajiAyodeji/inspireNuggetsSlackBot.git"
  },
  "author": "Bolaji Ayodeji",
  "license": "MIT",
  "bugs": {
    "url": "https://github.com/BolajiAyodeji/inspireNuggetsSlackBot/issues"
  },
  "homepage": "https://github.com/BolajiAyodeji/inspireNuggetsSlackBot#readme",
  "devDependencies": {
    "dotenv": "^8.0.0"
  },
  "dependencies": {
    "axios": "^0.19.0",
    "slackbots": "^1.2.0"
  }
}

Create your Slack workspace

Now that we have that all set up, we need a Slack workspace to run our bot in development. Creating a workspace is pretty easy, read this to learn more.

Register your Slack Bot

Now that you have a workspace, you should have a Slack URL with your workspace name. Mine is mekafindteam.slack.com.

Now you'll need to create a Slack App. Create one here.

Enter your App name and ensure you're in the workspace you created if you're in multiple workspaces.

Now you'll see the settings > Basic Information page. Click the first tab Add features and functionality:

Since we're building a bot, select the Bots field.

Now you'll see the Bot user page:

Click the Add a Bot User button.

Your display name will automatically be filled in from your already chosen App name. You can update it, but I'll advise you use the same name everywhere with the same alphabet case to avoid errors.

Now, toggle the Always Show My Bot as Online switch to always show your bot as Online. Remember this bot is just like a user in your workspace. Afterwards, click the Add Bot User button.

Save all changes now:

Next, return to the Basic Information page and select the Install your app to your workspace tab.

Click the Install App to Workspace:

Click allow and wait to be redirected back to the Basic Information page.

Note the Manage distribution tab: this section is needed when you want to make your Bot available for installation by others. For now we're just building in development and I won't be covering distribution in this article. In my next article, I'll show you how to deploy your Slack bot and make it available as an App to other workspaces.

If you check your Slack workspace now, you should see the App installed in the Apps section.

For now, it's offline - once we start building the bot, we'll turn this on.

Customize your Slack bot

Now we've created our bot, let's do some customization.

Still, on the Basic Information page, scroll down to the Display Information section:

This is basic stuff: just upload a logo, change your background color, and add a short description.

Your icon should be 512x512px or bigger and your background color should be in HEX. Read more on the App guidelines here.

Here's what mine looks like after customization:

Slack bot OAuth Tokens

Now that we have our Slack bot setup, let's grab out token keys.

In the navigation bar, locate the Features section and click the OAuth & Permission tab:

You'll see two Access Tokens:

  • OAuth Access Token
  • Bot User OAuth Access Token

Copy the Bot User OAuth Access Token.

This will change every time you re-install this app or when you install it in another workspace. The token should start with xoxb-.

Keeping credentials secure is important whether you're developing open source libraries and tools, internal integrations for your workspace, or Slack apps for distribution to workspaces across the world. - Slack

This is why we have installed Dotenv - we'll set that up in the next section.

Building the bot

Now let's build our bot :).

First, let's keep our Access Token somewhere.

Create a .env file and add this:

BOT_TOKEN=YOUR_SLACK_ACCESS_TOKEN_HERE

Now let's start our SlackBot.js:

const bot = new SlackBot({
    token: `${process.env.BOT_TOKEN}`,
    name: 'inspirenuggets'
})

We've just created a bot variable that initializes a new SlackBot instance which has two values, our token and app name.

I used the ES6 template string syntax to bring in our token key from our .env file. dotenv has this covered for us.

Make sure you use the same name you used while creating your Slack app, or else you'll have authentication errors.

Now start the app:

npm start

nodemon should be running now and our Slack app should be online too.

Start handler

Our Bot does nothing now even though it's running. Let's return a message.

bot.on('start', () => {
    const params = {
        icon_emoji: ':robot_face:'
    }

    bot.postMessageToChannel(
        'random',
        'Get inspired while working with @inspirenuggets',
        params
    );
})

The bot.on handler sends the welcome message. We passed two parameters, the 'start' and a function which holds a params variable which also holds the slack emoji. Slack emoji have codes, and you can find them here. I used :robot_face:, but you can change this to your preferred emoji.

We also initialized the bot.postMessageToChannel function which is a SlackBot.js method to post a message to a channel. In this function, we pass the channel name we want to post to, the message in a string, and the params variable we declared earlier for the emoji. I used the #random channel and sent Get inspired while working with @inspirenuggets to it. Your app should restart automatically and your bot should do this:

Cool right?
You can also post messages to users and groups.

    // define existing username instead of 'user_name'
    bot.postMessageToUser('user_name', 'Hello world!', params); 

    // define private group instead of 'private_group', where bot exist
    bot.postMessageToGroup('private_group', 'Hello world!', params); 

Error Handler

Let's also write a function to check for errors and return them:

bot.on('error', (err) => {
    console.log(err);
})

Message Handler

Now let's build the main bot functionality.

Like I said earlier, we'll be using the quotes JSON from the extension I built as our quotes API. The JSON can be found with this URL: https://raw.githubusercontent.com/BolajiAyodeji/inspireNuggets/master/src/quotes.json

When a user mentions our bot and adds inspire me, the bot returns a random quote from inspireNuggets. When the user types random joke, it returns a random joke from the Chuck Norris API. And when the user types help, it returns the instruction guide.

First, let's check for our command words from the user message (inspire me, random joke, and help):

function handleMessage(message) {
    if(message.includes(' inspire me')) {
        inspireMe()
    } else if(message.includes(' random joke')) {
        randomJoke()
    } else if(message.includes(' help')) {
        runHelp()
    }
}

Now let's create the three function we need

inspireMe()

Our demo JSON is not really an API, it's just some JSON I used in the Chrome Extension. We're only accessing it from GitHub raw contents. You can use any API you prefer, you'll just have to iterate differently to get your data depending on if your API returns an array or object - whichever it returns, it's not a big deal.

Check out my previous articles on:

function inspireMe() {
    axios.get('https://raw.githubusercontent.com/BolajiAyodeji/inspireNuggets/master/src/quotes.json')
      .then(res => {
            const quotes = res.data;
            const random = Math.floor(Math.random() * quotes.length);
            const quote = quotes[random].quote
            const author = quotes[random].author

            const params = {
                icon_emoji: ':male-technologist:'
            }

            bot.postMessageToChannel(
                'random',
                `:zap: ${quote} - *${author}*`,
                params
            );

      })
}

We just used Axios to get the JSON file which returns some data:

[
    {
        "number": "1",
        "author": "Von R. Glitschka",
        "quote": "The client may be king, but he's not the art director."
    },
    {
        "number": "2",
        "author": "Frank Capra",
        "quote": "A hunch is creativity trying to tell you something."
    },
.
.
.
.
]

This JSON currently contains 210 quotes and I update them frequently. So we want to get a random quote plus the author name every time the user request it. From our Axios response, we just do this:


const quotes = res.data;
const random = Math.floor(Math.random() * quotes.length);
const quote = quotes[random].quote
const author = quotes[random].author

And just like we did with the welcome message, we just return the quote and author instead of a string message:

`:zap: ${quote} - *${author}*`

Let's test this:

Type @inspirenuggets inspire me

Yayyy! It worked!

PS: You can always change the emoji type for every request. If you noticed I changed the inspireMe() to :male-technologist:

randomJoke()

We're getting the jokes from the Chuck Norris API from this endpoint https://api.chucknorris.io/jokes/random.

{
"categories": [],
"created_at": "2016-05-01 10:51:41.584544",
"icon_url": "https://assets.chucknorris.host/img/avatar/chuck-norris.png",
"id": "6vUvusBeSVqdsU9C5-ZJZw",
"updated_at": "2016-05-01 10:51:41.584544",
"url": "https://api.chucknorris.io/jokes/6vUvusBeSVqdsU9C5-ZJZw",
"value": "Chuck Norris once choked a wildcat to death with his sphincter muscle."
}

This is a real API that returns a random joke on every request, so we don't have to do Math.floor() again.

function randomJoke() {
    axios.get('https://api.chucknorris.io/jokes/random')
      .then(res => {
            const joke = res.data.value;

            const params = {
                icon_emoji: ':smile:'
            }

            bot.postMessageToChannel(
                'random',
                `:zap: ${joke}`,
                params
            );

      })
}

By now, you should understand how this works already. Make a post with the channel name, message and params.

runHelp()

This is similar to our welcome message: we just want to return a custom text when the user adds help to the request.

function runHelp() {
    const params = {
        icon_emoji: ':question:'
    }

    bot.postMessageToChannel(
        'random',
        `Type *@inspirenuggets* with *inspire me* to get an inspiring techie quote, *random joke* to get a Chuck Norris random joke and *help* to get this instruction again`,
        params
    );
}

Now let's test all three commands:

Everything works fine now, congratulations!!!! You just built your SlackBot.


There are an endless number of possibilities of Bots you can build with this to automate your own work or teamwork.

You can build a bot that:

  • Fetches your tasks from somewhere and reminds you when you type hey what next,
  • Welcomes every user to your workspace (I built this during one of the HNG Internship's),
  • Gives you football matches updates while you're working,
  • Tells your team when you hit a milestone in number of registered users,

and many more...

It's just about having somewhere to get the data from, and some basic iteration skills and the bot.postMessageToChannel() method.

Automation is one thing we should learn as developers. We have a lot to do, so we should automate the simpler tasks so we have time for the more difficult ones. I hope with this you can automate your tasks and I look forward to the creative ideas you'll bring to life.


Final Code

Here's our final index.js

const SlackBot = require('slackbots');
const axios = require('axios')
const dotenv = require('dotenv')

dotenv.config()

const bot = new SlackBot({
    token: `${process.env.BOT_TOKEN}`,
    name: 'inspirenuggets'
})

// Start Handler
bot.on('start', () => {
    const params = {
        icon_emoji: ':robot_face:'
    }

    bot.postMessageToChannel(
        'random',
        'Get inspired while working with @inspirenuggets',
        params
    );
})

// Error Handler
bot.on('error', (err) => {
    console.log(err);
})

// Message Handler
bot.on('message', (data) => {
    if(data.type !== 'message') {
        return;
    }
    handleMessage(data.text);
})

// Response Handler
function handleMessage(message) {
    if(message.includes(' inspire me')) {
        inspireMe()
    } else if(message.includes(' random joke')) {
        randomJoke()
    } else if(message.includes(' help')) {
        runHelp()
    }
}

// inspire Me
function inspireMe() {
    axios.get('https://raw.githubusercontent.com/BolajiAyodeji/inspireNuggets/master/src/quotes.json')
      .then(res => {
            const quotes = res.data;
            const random = Math.floor(Math.random() * quotes.length);
            const quote = quotes[random].quote
            const author = quotes[random].author

            const params = {
                icon_emoji: ':male-technologist:'
            }

            bot.postMessageToChannel(
                'random',
                `:zap: ${quote} - *${author}*`,
                params
            );

      })
}

// Random Joke
function randomJoke() {
    axios.get('https://api.chucknorris.io/jokes/random')
      .then(res => {
            const joke = res.data.value;

            const params = {
                icon_emoji: ':smile:'
            }

            bot.postMessageToChannel(
                'random',
                `:zap: ${joke}`,
                params
            );

      })
}

// Show Help
function runHelp() {
    const params = {
        icon_emoji: ':question:'
    }

    bot.postMessageToChannel(
        'random',
        `Type *@inspirenuggets* with *inspire me* to get an inspiring techie quote, *random joke* to get a Chuck Norris random joke and *help* to get this instruction again`,
        params
    );
}

Node.js Tutorial for Beginners | Node.js Crash Course | Node.js Certification Training

This courseis designed for professionals who aspire to be application developers and gain expertise in building real-time, highly-scalable applications in Node.js. The following professionals can go for this course :

Why learn Node.js?

Node.js uses JavaScript - a language known to millions of developers worldwide - thus giving it a much lower learning curve even for complete beginners. Using Node.js you can build simple Command Line programs or complex enterprise level web applications with equal ease. Node.js is an event-driven, server-side, asynchronous development platform with lightning speed execution. Node.js helps you to code the most complex functionalities in just a few lines of code...

Thanks for reading :heart: If you liked this post, share it with all of your programming buddies! Follow me on Facebook | Twitter

Learn More

The Complete Node.js Developer Course (3rd Edition)

Angular & NodeJS - The MEAN Stack Guide

NodeJS - The Complete Guide (incl. MVC, REST APIs, GraphQL)

Docker for Node.js Projects From a Docker Captain

Intro To MySQL With Node.js - Learn To Use MySQL with Node!

Node.js Absolute Beginners Guide - Learn Node From Scratch

React Node FullStack - Social Network from Scratch to Deploy

Selenium WebDriver - JavaScript nodeJS webdriver IO & more!

Complete Next.js with React & Node - Beautiful Portfolio App

Build a Blockchain & Cryptocurrency | Full-Stack Edition