How To Build a Chatbot From Scratch In 3 StepsMay 18th, 2021
Before showing you how to build a chatbot from scratch, let’s get through the basics.
What is a chatbot?
A Chatbot is a software which can simulate a human-like conversation with a user in natural language, through chats, applications, websites, phone, etc.
There are mainly two chatbot types:
Rule-based – the chatbot doesn’t use any kind of artificial intelligence to extract intent, actions, entities from the user input and usually presents the user with possible options in order to proceed, like a “if – else or a Switch - case”;
AI-based – the chatbot uses artificial intelligence to dynamically produce natural language feedback and can extract intent, actions, entities, etc. from user input.
How does it work?
There are two main tasks of a chatbot:
User request analysis – the chatbot receives the user input and analyses it, comparing it to its rules or extracting the user’s intent and relevant entities;
Returning the response to the user – after identifying the user’s intent, the chatbot provides an appropriate response to the user, being it a predefined text, an AI-generated text, information or data, the result of an action or another question which helps it understand the user’s request.
Why so many companies use them, and why would you use one?
Chatbots enhance the interactions between users and services and can reduce support time/costs. For instance, if a chatbot can perform simple support tasks, a user doesn’t need to be on the line with someone to solve their problem and, usually with a chatbot, the task can be done quite quickly and automatically. That said, companies need fewer people in their call centers, and the clients tend to be happier since they don’t need to wait (for the next morning if the problem happens during the night!) to get their things done.
So… if you have a company, kudos to you: you have some valid reasons to use a chatbot!
If you don’t have a company, why would you use a chatbot?
Because it’s fun and it looks cool! Imagine you sending a message from your messaging app of choice to your chatbot to automatically open or close your windows, make you a coffee and/or put some mood in your room! How cool is that? 🤯
That said, let’s start building your own chatbot so we can brag about it later to our friends!
Building a chatbot from scratch:
1 - Making the AI:
So, to make things interesting, we will make an AI-based chatbot, so we need an AI. For the sake of this article (but mainly… for my own sake!) I will be using an existing AI, Microsoft’s LUIS – instead of training my own. Basically, this is a cognitive service that can be used via a REST API and is smart enough to extract intents and data from sentences!
That said, let’s go to LUIS (Language Understanding) - Cognitive Services - Microsoft and sign up for a free account!
After that, we need to create a Resource Group on Azure in order to attach LUIS to that group.
After creating the resources, we still need to add the “Cognitive Services” to our free subscription. In order to do that, on the main page, click on “Subscriptions”, click on your free subscription, go to “Resources”, “Add”, search for “cognitive services” and create that resource.
Warning ⚠ probably that resource won’t appear right away on your resources table (it didn’t for me) just wait a little bit and it’ll pop up.
Once the group and the resource are created, we can go to LUIS’s website (Conversation apps (luis.ai)) and create our app!
If it’s your first time here, you’ll see a popup to choose your subscription and your “authoring resource”. Choose your free subscription and create a new Authoring resource.
If you get a “Missing Subscription Registration”, then it means your “Cognitive Services” resource was not created. Go back, try to create it again and return here!
When all that is done, we can finally create our app! Click on “New app” and fill the form. You only need to fill in the “name” and “culture”.
Congrats! You have your LUIS app created! 🎉 And while you’re at it, grab your App ID from the settings page and save it somewhere, we’ll need it!
Ok… we have our LUIS app but… the app still doesn’t know what intents and entities you’re waiting for… so, we need to add some! There are some default intents available but I want to create my own, so I’ll create a “Ask for food” intent. If we want, this intent can have some entities: imagine we want to be able to catch the food we want (food entity) and we are REALLY hungry or if we want something spicier (modifier intent). In that case, we can click on entities and create them. In my case, I’ll create the action entity (which covers the entire request) and attach sub-entities to it. By the end, it looks as follows:
After doing this, we should go to our “Ask for food” intent and add some examples for it to train later. In order to train and get our entities more accurately, we can click on our examples and map it (or parts of it) to our entities. Here’s an example:
When you’re done adding the examples and mapping them to our entities, we can finally click “Train” on the top right corner. After the training is finished, we can click on “Test” and send some phrases just to see what we can get out of them.
But now, after coffee, mysteriously I’m feeling REALLY hungry, so I would like something more…fulfilling:
I hope this is fulfilling enough… 🍔🍔🍔
Are you feeling satisfied? Then, click on “Publish” on the top right corner and publish the AI to production! We need to publish it to production to get access to our endpoints and access keys.
Once that’s done, click on the popup where it says “Access your endpoint URLs”. It should take you to a page like this:
But wait, there’s nothing there! 😮 Don’t worry, click on “Authoring Resource” and the keys and endpoint URL should show up:
Save the endpoint and the keys (at least the primary one) somewhere, we will need those later.
2 - The Discord server:
Now for the discord part… If you have access to a server and can add bots, you can test on it. If not, you can easily create your own server by clicking on the “Add a server” button! After deciding where your bot will reside, go to Discord’s developer portal (Discord Developer Portal — My Applications) and click on the “New Application” button on the top right corner. After creating the application, you’ll be redirected to your newly created application’s information page. On the left side of the page, click on “Bot” and then “Add Bot”.
Congrats! You have a Discord bot! 😎😎
Now, all we need to do is to add it to our server: click on “OAuth2”, scroll down to the “scopes” section and check the “bot” scope. After checking, the “Bot Permissions” block will appear. This bot only checks and sends messages, so we only need a few permissions:
After setting everything, you probably noticed how there’s some URL on the “Scopes” block. Copy that URL and paste it on your browser to add the bot to your server! After this, you should see your bot on your server (it is offline though).
3 - The server itself:
Now that we have an AI and a discord server, we need the server itself to handle our messages and send requests to the LUIS REST API. For this server, I will use Node.js, so make sure you have node installed on your machine. If you don’t want to install node, you can use Docker with a node image! I won’t be covering Docker in this post so if you don’t know how to use Docker (which is really cool by the way), feel free to go learn the basics and come back here later! Or, just install Node.js.
Assuming you have everything, create a folder for the server code, and open a terminal inside the newly created folder. In the terminal, run “npm init”. You can leave everything as it is (pressing the enter key like there is no tomorrow) since this is only a test bot.
After this, open the folder in your favorite text editor and create two more files: index.js (the server’s entry point) and config.json (where we will keep the server configuration, like the bot token).
Now… first things first. We need the bot token so our server can authenticate itself on discord and have a rich presence (appears as online, for instance) on our discord server. For now, grab this piece of code, paste it on your config.json file and replace “YOUR BOT TOKEN” by… you guessed it… your bot token. 😉
Now that we have the bot’s token, let’s code the server itself. First of all, we need a package to easily communicate with Discord. To install that package, check on your terminal inside the project's directory type:
Now that we have the package installed, just to test if we can connect to our discord bot, we can just try to login our server to it. It should be something like this (index.js):
After pasting this, we can run our server and see if the bot’s status changes to “online”. To do this, if you’re using Visual Studio Code like me, you can go to “Run” and press “Start Debugging”. This will start a node process and attach the editor to that process so you can add breakpoints and debug your app! If you don’t want to do that, you can just type on the terminal: node index.js
It did! Great! 💪
If you look at the terminal, there isn’t any kind of output telling us when and if the bot successfully logs in, so, let’s create some listeners! When something happens on our Discord server, a few events are fired and we can listen to some of them. That said, let’s listen to the “ready” event, to output on the terminal when the bot logs-in. To do this, add the following code before the “client.login” line:
If you have never used node, when you make changes in your code it doesn’t reload the server with your changes by default. There are some packages that allow you to do this but I won’t use any in this tutorial, since I think it’s a bit overkill in something this small. You are free to use them though!
Let’s test our new code then! Stop and launch your node process (if you don’t have live reload) or, if you’re debugging with VSCode, click the restart button and check your terminal!
Success! 🎉🎉 Now that we know that our server logs in and can listen to the bot’s events, let’s get to the fun stuff! We need to listen to a message event, grab that message, send it to LUIS, get LUIS’s response and finally, do whatever we want with it! So, let’s get started!
But first, to send our requests to LUIS, we need a few things. Remember those things I told you to save? Yep, we need them. Grab them and put them in your config.json file.
Something like this:
Now that we have everything for the request, let’s install axios. Axios is a cool package to handle http requests. To do this, just type on the terminal:
npm install axios
After installing axios, we need to build the request endpoint with our LUIS endpoint URL and our keys and create our axios instance with that base URL that we’ve just built. Something more or less like this:
Next, let’s create a function to handle LUIS’s response, so we can keep the message listener (which we’ll create later) clean and simple. You can paste this code after the login code:
Ok, now that we have something to handle our LUIS’s response, all that’s missing is the message listener. Paste this before the login code:
You know what to do now! Restart the node process, go to your discord server and say something!
Congrats! You’ve just built a simple bot with a simple AI! This was a simple tutorial so neither our bot or AI have tons of features. Still, here are some stuff you can do to make things a bit more interesting:
You don’t want your bot to send every single message to LUIS right? Why not adding a command like “=LUIS”?
LUIS just returning some text can be a bit…unfulfilling… You can get the food from the LUIS’s response and send it to a GIF API (like GIPHY) and return the first GIF it finds for your food! Careful… it might make you hungry though…
Sometimes when you ask for certain types of food, probably you’ve noticed that LUIS doesn’t recognize your request. Why not take care of it? You can add more examples and/or add a prebuilt entity (if it fits your needs) or a machine learning to train your AI more accurately.
Since the “Ask for Food” intent is the only intent we’ve got, it’s only normal our requests will always go to it. It feels a little like cheating, no? That said, why not create a new intent for desserts? Or to ask for a cab to go to a specific place where there is a fancy restaurant? Desserts are always nice, and probably we need some means to get to the restaurant to eat anyway. You can also add a validation to only choose the top intent only if it has a certainty above 75% (for example).
Looks like we’ve reached the end! I hope you had as much fun as I did building this chatbot from scratch! Now, let’s go brag about our bot to our friends! (just make sure they don’t understand much about this…).
Feel free to get in touch with me if you have questions! For that, use the comment section below. 👇
See the full code: