I've been inspired by @SirPython's SirAlfred JavaScript chat bot, so I went and made my own. This one is slightly different though, in the fact that it can accept input in a more lenient way. For example, here's a "conversation" with the bot:
sudo make me a sandwich bot BOT: It will be done master. sudo make me a sandwich bot BOT: Yes sir. Hello there bot. BOT: Hello there. Goodbye bot. BOT: Goodbye.
Essentially, instead of directly checking the contents of the string, it removes all non-alphanumeric characters, excluding spaces, and then splits on a space. It then checks to see if this split array contains certain words, and then outputs a message based on those words.
/**
* This is a small utility function used to
* determine if an array contains a certain
* value.
* @param {array} array - The array to check for the element in.
* @param {generic} value - The value to check for.
* @returns {boolean}
*/
function arrayContains(array, value) {
return array.indexOf(value) > -1;
}
/**
* Select a random element from the array.
* @param {array} array - The array to select from.
*/
function randomArrayElement(array) {
return array[Math.floor(Math.random() * array.length)];
}
/**
* This error is thrown when sendMessage
* is called and the message length
* exceeds 400 characters.
* @constructor
* @param {string} message - The error's message.
*/
function InvalidMessageLength(message) {
this.message = message;
this.name = "InvalidMessageLength";
}
/**
* Post a message to the room.
* @param {string} messageString - The string to be posted.
*/
function sendMessage(messageString) {
if(messageString.length - 1 <= 400) {
document.getElementById("input").value = messageString;
document.getElementById("sayit-button").click();
}
else {
throw new InvalidMessageLength("Length of message exceeded 400 characters.");
}
}
/**
* Obtains the very last posted message.
* @returns {object}
*/
function getLastPostedMessage() {
try {
var messageElements = document.getElementById("chat");
return messageElements.lastElementChild.children[1].lastElementChild.children[1].innerHTML;
}
catch(error) {
// The reason I have this try-catch block set up
// is because for some reason, an error associated
// with innerHTML pops up, and I don't know why.
// Sometimes it works fine, other times, the error
// will pop up after n amount of messages. Maybe
// it's a browser compatability issue?
return "";
}
}
/**
* Gets user input and sends messages
* back to that user.
*/
function main() {
var BOT_TEXT = "**`BOT:`** ";
var RANDOM_REPLIES = {
helloGreeting: function() {
return randomArrayElement([
"Hello.",
"Hello there.",
"Hello user."
]);
},
goodbyeGreeting: function() {
return randomArrayElement([
"Goodbye.",
"Goodbye user."
]);
},
sudoCommand: function() {
return randomArrayElement([
"Yes master.",
"Yes sir.",
"It will be done master."
]);
}
}
var lastMessage = getLastPostedMessage().toLowerCase().replace(/[^a-zA-Z\d\s:]/g, "").split(" ");
if(arrayContains(lastMessage, "hello") && arrayContains(lastMessage, "bot")) {
sendMessage(BOT_TEXT + RANDOM_REPLIES.helloGreeting());
}
else if(arrayContains(lastMessage, "goodbye") && arrayContains(lastMessage, "bot")) {
sendMessage(BOT_TEXT + RANDOM_REPLIES.goodbyeGreeting());
}
else if(arrayContains(lastMessage, "sudo") && arrayContains(lastMessage, "bot")) {
sendMessage(BOT_TEXT + RANDOM_REPLIES.sudoCommand());
}
window.setTimeout(main, 4500);
}
main();
Finally, in order to run this, you need to open up inspect element on your browser. While in a Stack Exchange chat room, copy-paste the above source into the JavaScript console, and then hit enter.