Created
July 25, 2021 00:41
-
-
Save SpiffGreen/9d6cbb39ffcd8e18510dbf0f96fa2c6c to your computer and use it in GitHub Desktop.
A simple rule-based chatbot developed with javascript
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
const bot = require("./training"); | |
console.log("Hello I'm Bujo. Let's Talk :)"); | |
bot.converse(); |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
"use strict"; | |
const readline = require("readline"); | |
const chalk = require("chalk"); | |
const prompt = readline.createInterface({ | |
input: process.stdin, | |
output: process.stdout | |
}); | |
// Utilities | |
function input(self, str = "> ") { | |
prompt.question(str, (value) => { | |
const result = self.process(value); | |
if(result.answer) { | |
process.stdout.write(chalk.yellow(result.answer) + "\n"); | |
if(value.includes("bye")) { | |
prompt.close(); | |
process.exit(); | |
} | |
input(self, str); | |
} else { | |
process.stdout.write("Sorry please could you rephrase that?" + "\n"); | |
input(self, str); | |
} | |
}); | |
// prompt.close(); | |
} | |
function randomBetween(min, max) { | |
return Math.floor(Math.random() * (max - min + 1) + min); | |
} | |
function flattenArray(arr) { | |
let result = []; | |
arr.forEach(i => { | |
if(!Array.isArray(i)) { | |
result.push(i); | |
} else { | |
result.push(...flattenArray(i)); | |
} | |
}); | |
return result; | |
}; | |
/** Test | |
const testArr = [ | |
[1, 2, 3, 4], | |
5, 6, 7, | |
[8, 9, 10, [11, 12, [13, 14, 15], 16]], | |
]; | |
*/ | |
// function processData(reg, str, template) { | |
// // const m = /hello|hi\s+([^\s]+)/g.exec(str); | |
// const m = reg.exec(str); | |
// for(let i = 1; i < m.length; i++) { | |
// console.log(i); | |
// template = template.replace(`%${i}`, m[i]); | |
// } | |
// return template; | |
// } | |
function processData(match, templates) { | |
const newTemp = templates.map(template => { | |
for(let i = 1; i < match.length; i++) { | |
template = template.replace(`%${i}`, match[i]); | |
} | |
return template; | |
}); | |
return newTemp; | |
} | |
/** | |
* @description A simple example of nlp functions for building chatbots | |
* | |
*/ | |
class Simple_Nlp { | |
constructor() { | |
this.__Markers = Object.create(null); | |
this.__Rules = Object.create(null); | |
this.__Answers = Object.create(null); | |
// Bind methods | |
this.addRule = this.addRule.bind(this); | |
this.addAnswer = this.addAnswer.bind(this); | |
this.train = this.train.bind(this); | |
this.process = this.process.bind(this); | |
this.converse = this.converse.bind(this); | |
} | |
// Use String.raw to create string using | |
addRule(rule, marker) { | |
this.__Markers[marker] ? this.__Markers[marker] += `|${rule}` : this.__Markers[marker] = rule; | |
if(!this.__Answers[marker]) this.__Answers[marker] = Array(); | |
} | |
addAnswer(marker, answer) { | |
if(!this.__Answers[marker]) throw new Error(`Sorry '${marker} does not exist`); | |
this.__Answers[marker].push(answer); | |
} | |
train() { | |
for(let marker in this.__Markers) { | |
this.__Rules[marker] = new RegExp(this.__Markers[marker], "gim"); | |
} | |
} | |
/** | |
* @todo Add formatted output | |
*/ | |
process(str) { | |
const result = Object.create(null); | |
result.utterance = str; | |
result.possibleAnswers = Array(); | |
result.classifications = Object.create(null); | |
for(let marker in this.__Rules) { | |
// let match = str.match(this.__Rules[marker]); | |
let match = this.__Rules[marker].exec(str); | |
if(match) { | |
result.classifications[marker] = match; | |
result.possibleAnswers.push(processData(match, this.__Answers[marker])) | |
} | |
} | |
result.possibleAnswers = flattenArray(result.possibleAnswers); | |
result.answer = result.possibleAnswers[randomBetween(0, result.possibleAnswers.length - 1)]; | |
return result; | |
} | |
converse() { | |
input(this); | |
} | |
} | |
const nlp = new Simple_Nlp(); | |
module.exports = { | |
bot: nlp, | |
r: String.raw | |
}; |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
const {bot, r} = require("./simple-nlp"); | |
// console.log(r); | |
// Possible questions | |
// bot.addRule('hi', "greeting.hi"); | |
bot.addRule("hey", "greeting.hi"); | |
bot.addRule("hello", "greeting.hi"); | |
bot.addRule("how are you", "ask.about"); | |
bot.addRule("whatsup", "ask.about"); | |
bot.addRule("howfar", "ask.about"); | |
bot.addRule("your name", "ask.self"); | |
bot.addRule("sex", "ask.sex"); | |
bot.addRule("bye", "greeting.bye"); | |
bot.addRule("fine", "answer.greeting"); | |
bot.addRule("great", "answer.greeting"); | |
bot.addRule("good", "answer.greeting"); | |
bot.addRule("sorry", "answer.plead"); | |
bot.addRule("order", "business.order"); | |
bot.addRule("purchase", "business.order"); | |
bot.addRule(r`i want ([^\s]+)`, "business.order"); | |
bot.addRule(r`i need ([^\s]+)`, "business.order"); | |
bot.addRule("Menu", "business.menu"); | |
bot.addRule("List", "business.menu"); | |
bot.addRule("Products", "business.menu"); | |
// Answers | |
bot.addAnswer("greeting.hi", "Hello dear how are you?"); | |
bot.addAnswer("greeting.hi", "How are you?"); | |
bot.addAnswer("greeting.hi", "Hi, how can i help you?"); | |
bot.addAnswer("greeting.bye", "Ok see you around"); | |
bot.addAnswer("greeting.bye", "It was nice talking with you"); | |
bot.addAnswer("ask.about", "I'm doing great, how can I help you?"); | |
bot.addAnswer("ask.self", "I am a bot Created by Spiff"); | |
bot.addAnswer("ask.sex", "๐ Hey I am a bot"); | |
bot.addAnswer("ask.sex", "๐ Ha thats funny, you know i'm not human right?"); | |
bot.addAnswer("answer.greeting", "That's good to know"); | |
bot.addAnswer("answer.greeting", "That's great"); | |
bot.addAnswer("answer.plead", "It's all good."); | |
bot.addAnswer("business.order", "You want to place an order, Contact +234 701 0990 0405"); | |
bot.addAnswer("business.order", "You want to make a purchase, Contact +234 701 0990 0405"); | |
bot.addAnswer("business.order", "Your order for %1 has been placed. :)") | |
bot.addAnswer("business.menu", "We sell eggs, milk, chickens, chicken feed, fish, etc"); | |
// Test | |
bot.addRule(r`my name is ([^\s]+)`, "intro.name"); | |
bot.addAnswer("intro.name", "Hello %1"); | |
// Train bot | |
bot.train(); | |
module.exports = bot; |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment