epic-chat-bot
Version:
A simple chat bot module.
343 lines • 14.3 kB
JavaScript
"use strict";
var __importDefault = (this && this.__importDefault) || function (mod) {
return (mod && mod.__esModule) ? mod : { "default": mod };
};
var __importStar = (this && this.__importStar) || function (mod) {
if (mod && mod.__esModule) return mod;
var result = {};
if (mod != null) for (var k in mod) if (Object.hasOwnProperty.call(mod, k)) result[k] = mod[k];
result["default"] = mod;
return result;
};
Object.defineProperty(exports, "__esModule", { value: true });
const string_similarity_1 = __importDefault(require("string-similarity"));
const socketIoClient = __importStar(require("socket.io-client"));
const events_1 = __importDefault(require("events"));
//Bot Status
var STATUS;
(function (STATUS) {
STATUS["ONLINE"] = "Online";
STATUS["OFFLINE"] = "Offline";
})(STATUS = exports.STATUS || (exports.STATUS = {}));
//Bot Gender
var GENDER;
(function (GENDER) {
GENDER["MALE"] = "Male";
GENDER["FEMALE"] = "Female";
})(GENDER = exports.GENDER || (exports.GENDER = {}));
class epicChatBot {
//Constructor
constructor(name = "Epic", gender = GENDER.MALE, status = STATUS.ONLINE, variables = {}) {
//Defaults
this.name = "Epic";
this.gender = GENDER.MALE;
this.status = STATUS.OFFLINE;
this.variables = {};
this.chatInitialized = true;
this.blackListWords = [];
this.requestHistory = [];
this.responseObject = undefined;
this.events = new events_1.default.EventEmitter();
this.chatHelper = null;
this.socketUri = null;
this.defaultTrainingObject = {
id: "default",
initRequired: false,
questions: [],
answerObject: {
answered: 0,
repeatAllowed: 3,
answers: [
"Sorry I didn't get that!",
"No idea!!",
"I'm a bot programmed to answer only some of the frequent questions.",
"Well, I think I didn't get that!",
],
optionsObject: {
text: "Please choose an option below.",
options: [],
},
actionsObject: {},
},
repeatObject: {
answered: 0,
repeatAllowed: 3,
answers: [
"Sir/Mam, Make sure your question is correct! Or please contact our team member.",
"If you think there is an issue with me, please let my creators know about it...",
],
optionsObject: {
text: "Please choose an option below.",
options: [],
},
actionsObject: {},
lastActionsObject: {},
},
};
this.trainingObjects = [];
this.me = null;
this.eventPrefix = "epicChatBot.";
this.toggleStatus = () => {
if (this.status == STATUS.ONLINE) {
this.status = STATUS.OFFLINE;
}
else {
this.status = STATUS.ONLINE;
}
this.event("statusChanged", this.status);
return this;
};
this.toggleInitialization = () => {
if (this.chatInitialized)
this.chatInitialized = false;
else
this.chatInitialized = true;
this.event("initChanged", this.chatInitialized);
return this;
};
this.getStatus = () => {
return this.status;
};
this.train = (data) => {
let questions = [];
data.forEach((v, i) => {
let already = false;
questions.forEach((a) => {
//@ts-ignore
if (v.questions.equals(a))
already = true;
});
if (!already) {
questions.push(v.questions);
this.trainingObjects.forEach((q, w) => {
if (v.id == q.id) {
data.splice(i, 1);
}
else if (v.id == "default") {
this.defaultTrainingObject = v;
data.splice(i, 1);
}
});
}
});
this.trainingObjects = this.trainingObjects.concat(data);
this.event("trained", this.trainingObjects);
return this;
};
this.unTrain = () => {
this.trainingObjects = [];
this.event("unTrained", this.trainingObjects);
return this;
};
this.getrequestHistory = () => {
return this.requestHistory;
};
this.evaluate = (request) => {
let white = true;
this.blackListWords.forEach((v, i) => {
if (request.match(v)) {
white = false;
}
});
return white;
};
this.listen = (request) => {
let matchingObjects = [];
this.trainingObjects.forEach((v, i) => {
if ((v.initRequired && this.chatInitialized) || !v.initRequired) {
let questions = [];
v.questions.forEach((v, i) => {
questions.push(v.toLowerCase());
});
let match = string_similarity_1.default.findBestMatch(request.toLowerCase(), questions);
matchingObjects.push({
index: i,
rating: match.bestMatch.rating,
});
}
});
let resultObject = null;
let topRating = 0;
matchingObjects.forEach((v, i) => {
if (v.rating > topRating) {
topRating = v.rating;
resultObject = v;
}
});
return resultObject;
};
this.request = (request) => {
let responseObject;
let resultObject;
if (this.status == STATUS.ONLINE) {
if (this.evaluate(request)) {
resultObject = this.listen(request);
if (resultObject !== null &&
typeof resultObject.index != "undefined") {
if (!this.chatInitialized) {
this.event("initialized", this);
this.chatInitialized = true;
}
responseObject = this.trainingObjects[resultObject.index];
}
else {
responseObject = this.defaultTrainingObject;
}
}
else {
responseObject = this.defaultTrainingObject;
}
this.responseObject = responseObject;
//Store History
this.requestHistory.push({
request: request,
responseObject: this.responseObject,
});
this.event("request", request);
return this;
}
else {
throw new Error(`${this.name.toUpperCase()} IS NOT ONLINE!`);
}
};
this.answerTemplate = (string, index, destination) => {
let self = this;
if (string.match(/\{\{\s*(.+?)\s*\}\}/g)) {
Object.entries(self.variables).forEach((v, i) => {
if (typeof self.responseObject != "undefined") {
string = self.responseObject[destination].answers[index] = string.replace((new RegExp('\\{\\{\\s*(' + v[0] + ')\\s*\\}\\}', "g")), v[1]);
}
});
}
return self;
};
this.response = () => {
let self = this;
if (typeof self.responseObject != "undefined") {
self.responseObject.answerObject.answers.forEach((v, i) => {
self.answerTemplate(v, i, "answerObject");
});
self.responseObject.repeatObject.answers.forEach((v, i) => {
self.answerTemplate(v, i, "repeatObject");
});
this.event("response", self.responseObject);
return self.responseObject;
}
else
return null;
};
this.chat = (helper, connectOptions) => {
var _a, _b, _c;
this.chatHelper = helper;
this.socketUri = this.chatHelper.host.replace(/^\/+|\/+$/g, "") + ":" + this.chatHelper.port;
let socket = socketIoClient.connect(this.socketUri, connectOptions);
console.log("Socket Attempting Connection To: ", this.socketUri);
socket.on('connect', () => {
var _a;
let authenticate = {
reference: "bot",
name: this.name,
contact: null,
trace: null,
meta: null,
};
socket.emit(((_a = this.chatHelper) === null || _a === void 0 ? void 0 : _a.eventPrefix) + "authenticate", authenticate);
//Log
console.log("EpicChatBot: Epic Chat Bot Connection Has Been Initiated.");
});
let socketIds = [];
let connections = {};
socket.on(((_a = this.chatHelper) === null || _a === void 0 ? void 0 : _a.eventPrefix) + "connected", (connection) => {
if (connection.connection.reference != "bot") {
socketIds.push(connection.connection.id);
connections[connection.connection.id] = connection.connection;
//Log
console.log("A New Socket Contact Has Been Added To Epic Chat Bot.");
}
else {
this.me = connection.connection;
//Log
console.log("Epic Chat Bot Has Been Connected To Socket.");
}
});
socket.on(((_b = this.chatHelper) === null || _b === void 0 ? void 0 : _b.eventPrefix) + "message", (messageObject) => {
var _a, _b;
if (socketIds.includes(messageObject.sender.id)) {
socket.emit(((_a = this.chatHelper) === null || _a === void 0 ? void 0 : _a.eventPrefix) + "send_event", {
type: 0,
sender: this.me,
receiver: connections[messageObject.sender.id],
payload: {
event: "typing",
data: {
text: "",
}
}
});
socket.emit(((_b = this.chatHelper) === null || _b === void 0 ? void 0 : _b.eventPrefix) + "message", {
receiver: connections[messageObject.sender.id],
message: this.request(messageObject.message).response(),
});
}
});
socket.on(((_c = this.chatHelper) === null || _c === void 0 ? void 0 : _c.eventPrefix) + "disconnected", (connection) => {
if (typeof connection.connection != "undefined" && typeof connection.connection.id != "undefined") {
socketIds = socketIds.filter(i => i != connection.connection.id);
delete connections[connection.connection.id];
}
});
socket.on('connect_error', (error) => {
console.log("EpicChatBot: ", error);
});
socket.on('connect_timeout', (timeout) => {
console.log("EpicChatBot: ", timeout);
});
return this;
};
this.event = (event, data) => {
this.events.emit(this.eventPrefix + event, data);
return this;
};
this.on = (event, handler) => {
let self = this;
this.events.on(this.eventPrefix + event, handler);
return self;
};
this.name = name;
this.gender = gender;
this.status = status;
this.variables = Object.assign({
name: this.name,
gender: this.gender,
status: this.status,
}, variables);
// Attach the .equals method to Array's prototype to call it on any array
// @ts-ignore
Array.prototype.equals = function (array) {
// If the other array is a falsy value, return
if (!array)
return false;
// Compare lengths - can save a lot of time
if (this.length != array.length)
return false;
for (var i = 0, l = this.length; i < l; i++) {
// Check if we have nested arrays
if (this[i] instanceof Array && array[i] instanceof Array) {
// Recurse into the nested arrays
if (!this[i].equals(array[i]))
return false;
}
else if (this[i] != array[i]) {
// Warning - two different object instances will never be equal: {x:20} != {x:20}
return false;
}
}
return true;
};
// Hide method from for-in loops
Object.defineProperty(Array.prototype, "equals", { enumerable: false });
return this;
}
}
exports.epicChatBot = epicChatBot;
//# sourceMappingURL=epicChatBot.js.map