Skip to content
A semi-simple JS chat bot example with TTS implementation.
JavaScript HTML
Branch: master
Clone or download
Fetching latest commit…
Cannot retrieve the latest commit at this time.
Permalink
Type Name Latest commit message Commit time
Failed to load latest commit information.
bot
README.md

README.md

JSchatBOT

A semi-simple JS chat bot example with working TTS

example here:

http://mzero.space/hosted/JSchatBOT/

This software contains some unfinished objects intentionally, to allow for quick extension in the future.

THE LOGIC FLOW

The main driving force of this bot is in the BOT.listen() method. At a high level, it decides if the users input is going to the BOT.learning() (Which does not yet exist, but has some code implemented in this method none the less.) or to BOT.think() which will analyse input and form a response before speaking it back to the user.

This method takes only one argument, 'input' which is a value that should be taken from <input id="input">in index.html.

BOT.learning()

A flag that indicates if the bot is listening to user input with the purpose of remembering it. This has not been fully implemented yet.

BOT.hear()

Basically a wrapper for our REGEX. Takes two arguments, 'input' & 'src' and decides if 'input' contains the string 'src'. The value for 'input' can be any number of words that is more than zero. You can string words together like this:

BOT.hear(input,'is the time')

However the REGEX will always expect to find either a space, punctuation or new line at the beginning and end of the 'src' (when it looks but not in your actual 'src' value).

The search value is not case sensitive.

This method will return true if there is a match found and false if there is not.

So for example executing the code below will return true:

BOT.hear('Hello World!','hello')

But

BOT.hear('Greetings','Greetings!')

Will return false.

This is the basic method used by this bot to listen to what the user is saying and try to pick out key words.

BOT.tag()

This is where the real work is happening right now. This method basically serves to take the user input and filter it into categories.

Since there are many ways to say "hello" we could spend a million years writing a unique response to each version. Instead I have gone with a filtering system.

We take a list of possible ways to say "hello", for example we can use "Hi" & "Hey". using the BOT.hear() method, we can determine if the user input had any of these words and if it did we will "TAG" it with the "greetings" tag so that we know that the user input contained a greetings of some kind.

Since there are not only different ways to say "hello", but also a few different styles/tones it can be said in. We also have a "greetings_slang" TAG. This can contain some greetings like "Sup" and "Yo". Since the user is conveying a different tone or style with these kind of greetings, we can use that data to let our bot reply in a more casual way.

Category tags are at the core of the system that lets our bot make sense out of what the user is saying. These tags will later be used to generate a somewhat logical response to our user, but more on that later.

Adding to this

In order to add new functionality to this bot you will most likely have to add new TAGS unless you are content with working inside the bounds of our existing TAGS.

If you are content with working with the current TAGS then all you need to do in order accept new kinds of user input is add a new code block like the one below:

  if(BOT.hear(input,'hello')===true){
    console.log("heard 'hello' as greeting");
    TAG["greetings"] = true;
  }

Simply replace any instance of the string 'hello' with your new string that you want to search for. For instance you could change this code to accept the user saying "Good day sir" as a "greeting" by changing the code like this and adding it to this method:

  if(BOT.hear(input,'good day sir')===true){
    console.log("heard 'good day sir' as greeting");
    TAG["greetings"] = true;
  }

Adding a new TAG and accepting user input under that TAG is a little bit more complex. I will cover the BOT.think() method first since we will need to know how that before adding a new tag can yield any affect. If you want to add new TAGs as well as new responses keep reading.

BOT.think()

This method is actually pretty simple. It takes the TAGs that have been generated by the BOT.tag() method and uses them to form a response that will be sent back to the user.

This method takes two arguments, 'TAG' & 'input'. At the time of this writing. Currently, 'input' is only used to respond to an unknown word or phrase. TAG is a generated list of tags from the BOT.tag() method.

This method also contains a small function getRes() for choosing a random result from our list of response options. More on this later.

As you may have already noticed, it is 100% possible for the input to fall under multiple tags. This is intentional because it will let our bot respond to a multitude of questions or statements in a single logical response. For example it if asked a question like "Hi, do you know what the time is?" The bot could respond by saying "Hello, the time is 4:35am" (NOTE: at the time of this writing the bot can not yet tell time but adding this will be trivial). As you can see in this mini thought experiment, the bot is able to make some reasonably complex responses without being overwhelmed. Right now the bot is not doing much with this technology but it has potential to be expanded.

The bots response is currently generated as a string that gets appended when it falls through any of the TAG blocks that it matches.

This does however bring us to a current potential weak point in this bots logic. Right now it has no way of knowing what parts of the response should go in what order aside from the explicit order that we give it.

Due to this, it is very important to ensure that the blocks of code that are in this method that check for a tag and append the text are in the order you would want the response to come out. So for example, the "greetings" tag block should always come first since it is good practice in the English language to insert your greeting at the beginning of your response.

Choosing the TAGs response with getRes()

Not only does this bot generate a valid response to "speak" back to the user based on the users input but it also contains a function for semi-randomly selecting what that response should sound like using the getRes() function. Each block of code in this method (BOT.think()) that is used for deciding a response based on a tag will look something like this:

  if(TAG["greetings"]===true){
    console.log("Thinking about greetings");
    option_list = [
      "Hello! ",
      "Good Day! ",
      "Greetings! ",
      "Hi there! ",
    ];
    res += getRes(option_list);
  }

By editing the array 'option_list' you can add new responses to the list of possible responses that the bot can use for each tag. For instance you could add a new the "greetings" TAG like this:

  if(TAG["greetings"]===true){
    console.log("Thinking about greetings");
    option_list = [
      "Hello! ",
      "Good Day! ",
      "Greetings! ",
      "Hi there! ",
      "'Ello! "
    ];
    res += getRes(option_list);
  }

Sure, that might have been better suited for the "greetings_slang" TAG but I'm not here to argue semantics. To add a new TAG to this method you will simple create a new code block similar to the ones above. For example you could add a new TAG to this method like this:

  if(TAG["newTag"]===true){
    console.log("Thinking about new tags");
    option_list = [
      "response 1",
      "response 2"
    ];
    res += getRes(option_list);
  }

Adding a TAG here alone is not enough to get the bot to respond to it. More on that now.

OKAY I REALLY JUST WANT TO ADD TO THIS THING

At this point you should already know how to add new TAGS to the BOT.tag() method and assign new the BOT.hear() method. You might want to just make sure you have read the entire README and understand it before getting to this point, but I am not about to tell you how to live your life.

The basic process of adding new inputs and response, as well as new features, consists of adding TAGs. In the future I would like to design a new system that will make this process a lot easier and allow for greater extend-ability, but that will most likely manifest as a totally new project.

In order to implement a new feature you will have to follow a few steps and insert some code into a few methods.

You will start by modifying the variable TAG found in the top of the BOT.tag() method. This is a JSON object and you can add a new TAG to it like this:

  var TAG = {
    "greetings":false,
    "greetings_slang":false,
    "time":false,
    "date":false,
    "about_me":false,
    "unknown":false,
    "newTAG":false
  };

You will probably want to set your new TAG to false by default. If you are not sure, leave it set to false.

Next, you will want to add some logic into the BOT.tag() method that will sort some words or phrases into the tag using BOT.hear(). For example you can see the logic for the greeting tag here:

  //##TAG LOGIC##
  //greetings
  if(BOT.hear(input,'hello')===true){
    console.log("heard 'hello' as greeting");
    TAG["greetings"] = true;
  }
  if(BOT.hear(input,'hi')===true){
    console.log("heard 'hi' as greeting");
    TAG["greetings"] = true;
  }

Make sure you insert any new logic between the //##TAG LOGIC## comment and the //unknown comment

You will also need to add some new logic into the BOT.think() method in two places.

The first piece of logic that you will need to add is the logic for deciding what kind of responses this TAG can generate. An example of this type of logic is below:

  if(TAG["newTAG"]===true){
    console.log("Thinking about my new TAG");
    option_list = [
      "response 1",
      "response 2",
    ];
    res += getRes(option_list);
  }

The last but most important step is to add your new TAG to the very ugly "unknown checking" if statement at the bottom of BOT.think() method. At the time of writing it looks like this:

//unknown (gross function that must include everything)
if(TAG["greetings"]===false&&TAG["greetings_slang"]===false&&TAG["time"]===false&&TAG["date"]===false&&TAG["about_me"]===false){
  ...
}

To add your tag to this condition you just need to put it in like the others by adding an && operator to the end. You could add a new tag like this:

//unknown (gross function that must include everything)
if(TAG["greetings"]===false&&TAG["greetings_slang"]===false&&TAG["time"]===false&&TAG["date"]===false&&TAG["about_me"]===false&&TAG["newTAG"]===false){
  ...
}

If this condition is met, the bot did not understand anything that was said. If you do not add your TAG to this condition the bot will be very confused. Failing this condition will trigger the not fully implemented "learning" logic wherein the bot will ask for a an example response from the human user to an unknown question or phrase.

You can’t perform that action at this time.