DEV Community

loading...
Cover image for Build a Chatbot with Vanilla JavaScript

Build a Chatbot with Vanilla JavaScript

Emmanuel Ugwu
Software Engineering | Technical Writing | Web Development
Updated on ・6 min read

Recently, I visited a website and while surfing through it, the website’s chatbot caught my attention. I had been looking for a new project to work on, so I got to researching how I could build a chatbot using vanilla JavaScript. While building this project from scratch I stumbled across a lot of difficulties based on the knowledge I had and when I say 'from scratch', I just mean I did not use any additional libraries or APIs while building. Part of this code is based on existing blog posts, articles, and YouTube videos. Also note that this project is more of an insight into JavaScript fundamentals, not any form of artificial intelligence (AI) or machine learning. The main prerequisite for understanding this article is the knowledge of HTML, CSS, and vanilla JavaScript.

Getting Started

Let’s create a folder to house our project files, broadly divided into three parts —HTML, CSS and JavaScript. Then we build a barebone HTML file which contains all our HTML components:

// index.html
<!DOCTYPE html>
<html lang="en">
<head>
  <title>Chatbot</title>
  <link rel="stylesheet" href="style.css" />
  <script type="text/javascript" src="index.js" ></script>
</head>
<body>
  <h1>Chatbot</h1>
  <div id="container" class="container">
     <input id="input" type="text" placeholder="Say something..." autocomplete="off" />
  </div>
</body>
</html>
Enter fullscreen mode Exit fullscreen mode

We’ll do the same for our style.css file to add styling to our application:

  * {
          box-sizing: border-box;
    }

  html {
          height: 100%;
       }

  body {
          font-family: 'Poppins', sans-serif;
          background-color: #fff;
          height: 100%;
          margin: 0;
       }

 .container {
          width: 100%;
          height: 100%;
      }
Enter fullscreen mode Exit fullscreen mode

Listening for events

First off, we’ll have to check if the content of our page has loaded before our script has a chance to run and we’ll also need a keycode to send a message to the chatbot using our enter key.
For this to work, an addEventListener method is needed. It calls up a function whenever a specified event is delivered to the target. The two events our addEventListener listens for are:

  • DOMContentLoaded - this event fires when the initial HTML document has been completely loaded and parsed, without waiting for stylesheets, images, and subframes to finish loading.
  • keydown - this event is fired for all keys, regardless of whether they produce a character value.

KeyboardEvent code

The keydown event is a KeyboardEvent.code property which provides a code indicating which of the user’s keyboard keys is pressed. For example, a lowercase "a" will be reported as 65 by keydown and keyup. An uppercase "A" is reported as 65 by both events.
With the help of our keydown event, we can create an effective way of sending a message to the chatbot by pressing the enter key. Our addEventListener would listen and respond anytime the enter key is pressed.

document.addEventListener("DOMContentLoaded", () => {
inputValue.addEventListener("keydown", (e) => {
      if (e.code === "Enter") {
        let input = inputValue.value;
        inputValue.value = "";
        output(input);
      }
    });
  });
Enter fullscreen mode Exit fullscreen mode

In the code snippet above, e.code === "Enter" indicates the Keycode 13 directly assigned to the Enter button. To know more about Keycodes, read up on the KeyboardEvent object.
The input value from the user is assigned to a variable which we’ll make use of later on. One last thing to have in mind is to clear or reset our input once our message is sent, .value = "" makes this possible. We can use .reset() if our input field was a form tag but sadly, it isn’t.

Creating User and Chatbot responses

Editing user text input

Next, we’ll create a function for our chatbot behaviour.

function output(input) {
    //remove all characters except word characters, space, and digits 
    let text = input.toLowerCase().replace(/[^\w\s]/gi, "").replace(/[\d]/gi, "").trim();
    text = text
      .replace(/ a /g, " ")   // replaces 'tell me a story' to 'tell me story'
      .replace(/i feel /g, "")
      .replace(/whats/g, "what is") // replaces "whats" to "what is"
      .replace(/please /g, "")
      .replace(/ please/g, "")
      .replace(/r u/g, "are you"); //replaces "r u" to "are you"
}
Enter fullscreen mode Exit fullscreen mode

Our user’s input value need to undergo some changes for our chatbot to understand the message sent by the user as shown above and by doing that we’ll have to apply some JavaScript methods which are:

  • toLowerCase() - Converting the input values to lowercase.
  • Regex and replace() - This removes a non word/space character and digit. For example it replaces certain things like whats up to what is up or r u to are you. If the user says what is going on, whats going on, or what's going on, they will all lead to the same valid bot response.
  • trim() - To trim trailing whitespaces.

Creating a set of arrays

Now that we’ve gotten a good idea of how the user’s text input would turn out, we’ll have to create a set of arrays which include possible user texts and another array of appropriate chatbot responses.

const userTexts = [
    //0 
    ["hi", "hey", "hello", "good morning", "good afternoon", "good day"],
    //1
    ["how are you", "how is life", "how are things", "how are you doing", 
    "are you doing good", "are you fine", "how is your day going", "how is your day", 
    "what's up", "whats up", "you good"],
    //2
    ["what are you doing", "what is going on", "what is up", "how is your day", 
    "what's up", "whats up", "you good"],
    //3
    ["how old are you", "are you old"],
    //4
    ["who are you", "are you human", "are you bot", "are you human or bot"],
    //5
    ["who created you", "who made you", "were you created"]
  ]

  const botReplies = [
    //0
    ["Hello!", "Hi!", "Hey!", "Hi there!","Howdy"],
    //1
    [
      "Fine... and you?",
      "Pretty well, and you?",
      "Fantastic, and you?"
    ],
    //2
    [
      "Nothing much",
      "About to go to sleep",
      "Can you guess?",
      "I don't know actually"
    ],
    //3
    ["I am infinite"],
    //4
    ["I am just a bot", "I am a bot. What are you?"],
    //5
    ["The one true God, JavaScript"]
  ]
Enter fullscreen mode Exit fullscreen mode

We’ll need to create an alternate set of arrays for a situation where the chatbot can not understand the message being sent by the user.

 const alternative = [
   "Same",
   "Go on...",
   "Bro...",
   "Try again",
   "I'm listening...",
   "I don't understand :/"
   ]
Enter fullscreen mode Exit fullscreen mode

NOTE: You can add extra user texts and reponses if needed.

Compare and match User and Chatbot responses

Our chatbot function still needs an IF/ELSE statement to compare and match our arrays for a suitable reply or produce an alternate reply if we get a user input that does not match our userTexts array.

function output(input) {
    if (compare(userTexts, botReplies, text)) { 
      // search for exact match in `userTexts`
      finalResult = compare(userTexts, botReplies, text);
    } else {
      // if everything else fails, bot produces a random alternative reply
      finalResult = alternative[Math.floor(Math.random() * alternative.length)];
    }
    // to update our HTML DOM element 
    addToChat(input, finalResult);
  }
Enter fullscreen mode Exit fullscreen mode

We have to match the user and chatbot arrays to making it look like a conversation between a user and the chatbot. Notice in the code snippet above, if we get a user input that matches an option at userTexts[0] such as ‘hi’ or ‘hello’, the bot will answer with a corresponding reply from its own set of options from botReplies[0] and so on. Now we’ll add the function that matches these two set of arrays.

function compare(userTexts, botReplies, text) { 
  for (let x = 0; x < userTexts.length; x++) {
      for (let y = 0; y < botReplies.length; y++){
        if (userTexts[x][y] == text) {
          let replies = botReplies[x];
          let reply = replies[Math.floor(Math.random() * replies.length)];
        }
      }
    }
    return reply;
  }
Enter fullscreen mode Exit fullscreen mode

The function works like this, we’ll first have to loop through the index of the userTexts array, then we’ll apply another loop to check if our user’s input text matches any of the responses at that particular index. After checking to see if it matches, we’ll randomly pick a corresponding reply from the set of botReplies arrays available.

Updating our DOM element

Finally we’ll update our HTML DOM (Document Object Model) so our messages can actually display for whenever the user or the chatbot sends a message. Making use of the .appendChild method, we could create a thread of messages by updating the user and chatbot field every time a message is sent.

function addToChat(input, finalResult) {
    let userDiv = document.createElement("div");
    userDiv.id = "user";
    userDiv.className = "response";
    userDiv.innerHTML = `<span>${input}</span>
    messagesContainer.appendChild(userDiv)`;

    let botDiv = document.createElement("div");
    let botImg = document.createElement("img");
    let botText = document.createElement("span");
    botDiv.id = "bot";
    botImg.className = "avatar";
    botDiv.className = "bot response";
    botText.innerText = "Typing...";
    botDiv.appendChild(botImg);
    botDiv.appendChild(botText);
    messagesContainer.appendChild(botDiv);
}
Enter fullscreen mode Exit fullscreen mode

Video

Demo of our application in use

Conclusion

By following the steps in this article, you can build a chatbot with plain JavaScript.
For better understanding and overview of the code base of this article, you can check it out on Github.

Discussion (11)

Collapse
ninjaasmoke profile image
Nithin Sai K J

Not to be blunt, but that is NOT how one should implement a BOT. This is just a program that generates predefined responses. A bot, on the other hand needs to understand context (of previous messages) and formulate new answers.

Collapse
ugwutotheeshoes profile image
Emmanuel Ugwu Author

I understand, the plan here was to create something which exhibits some behaviours of a bot.

Collapse
johnjacobkenny profile image
Kenny John Jacob 📘

Nice first post, I agree with Nithin, this is too simple for calling it a "chatbot". But it's a good start, and you can look into RASA as a backend which is open source and helps you build a real bot. Or something like dialogflow 😊

Thread Thread
ugwutotheeshoes profile image
Emmanuel Ugwu Author

Thanks a lot. I'll try it out then.

Collapse
madza profile image
Madza

Hearing 'vanilla' in JS ecosystem in 2021 is as rare as hen's teeth 😃😃
Good job on this 😃😃

Collapse
ugwutotheeshoes profile image
Emmanuel Ugwu Author

Haha, thanks Madza.
I'm just a beginner, eventually I'll get better.

Collapse
weltam profile image
Welly Tambunan

hi, maybe you could try to combine the bot with this rasa.com/

it's a great framework. and it's fun to use.

Collapse
ugwutotheeshoes profile image
Emmanuel Ugwu Author

Thanks, I'll try it out.

Collapse
faaktap profile image
Fakie Tap

I think a fun way to hone your skills, would be to create the animals game in javascript.
See ulisp.com/show?1LKX

Collapse
uzair004 profile image
Muhammad Uzair

Nice but i guess bots are supposed to be AI based

Collapse
shikkaba profile image
shikkaba

This is a form of AI. Rudimentary, but still AI is just code. The more complex it is, the more intelligent it appears.