|
|
@ -4,30 +4,132 @@ |
|
|
|
|
|
|
|
let { logger } = require('../logging'); |
|
|
|
let message = require('../message'); |
|
|
|
let { isFunction, getObjectKeysToPrototype } = require('../utility'); |
|
|
|
|
|
|
|
class AbstractModule { |
|
|
|
name = "AbstractModule" |
|
|
|
description = "Base Module That All Other Modules Extend" |
|
|
|
command = "abstract_module" |
|
|
|
/* |
|
|
|
Name of the module used in help documentation and logging. |
|
|
|
*/ |
|
|
|
name = "AbstractModule"; |
|
|
|
|
|
|
|
/* |
|
|
|
Short description of the module functionality. |
|
|
|
*/ |
|
|
|
description = "Base Module That All Other Modules Extend"; |
|
|
|
|
|
|
|
/* |
|
|
|
The exported command used to invoke the module directly. |
|
|
|
*/ |
|
|
|
command = "abstract_module"; |
|
|
|
|
|
|
|
/* |
|
|
|
The default method to call when a command word is not recognized. |
|
|
|
*/ |
|
|
|
defaultCommand = null; |
|
|
|
/* |
|
|
|
The module should be hidden from help and command dialogs. |
|
|
|
*/ |
|
|
|
hidden = false; |
|
|
|
/* |
|
|
|
This module should receive all messages, regardless of whether |
|
|
|
the module was directly referenced with a command. |
|
|
|
*/ |
|
|
|
canHandleIndirectMessages = false; |
|
|
|
|
|
|
|
constructor(name, description, command) { |
|
|
|
this.name = name; |
|
|
|
this.description = description; |
|
|
|
this.command = command; |
|
|
|
this._recognizedCommands = new Map(); |
|
|
|
} |
|
|
|
|
|
|
|
addRecognizedCommand(command, methodName) { |
|
|
|
this._recognizedCommands.set(command, methodName) |
|
|
|
} |
|
|
|
|
|
|
|
getRecognizedCommands() { |
|
|
|
return this._recognizedCommands.keys(); |
|
|
|
} |
|
|
|
|
|
|
|
/** |
|
|
|
* Default functionality for receiving and processing a message. |
|
|
|
* |
|
|
|
* Override this if the module needs to do more complicated message processing. |
|
|
|
*/ |
|
|
|
handleMessage(event, room, callback) { |
|
|
|
logger.debug("[%s] [%s] [%s]", this.name, room.name, event.event.content.body); |
|
|
|
|
|
|
|
let messageBody = event.event.content.body; |
|
|
|
let bodyParts = messageBody.split(' '); |
|
|
|
let trigger = bodyParts[0]; |
|
|
|
let command = bodyParts[1]; |
|
|
|
var args = []; |
|
|
|
if (bodyParts.length > 2) { |
|
|
|
args = bodyParts.slice(2); |
|
|
|
} |
|
|
|
|
|
|
|
logger.debug("Attempting to call %s with %s", command, args); |
|
|
|
let responseMessage = this.processMessage(command, args); |
|
|
|
|
|
|
|
callback( |
|
|
|
room, |
|
|
|
message.createBasic(this.name + " processed the message") |
|
|
|
responseMessage |
|
|
|
); |
|
|
|
} |
|
|
|
|
|
|
|
help(event, room) { |
|
|
|
/* |
|
|
|
Call the command method with the args |
|
|
|
*/ |
|
|
|
processMessage(command, ...args) { |
|
|
|
if (command in this._recognizedCommands) { |
|
|
|
logger.debug("Calling %s with %s", this._recognizedCommands.get(command), args); |
|
|
|
return this[this._recognizedCommands.get(command)](...args); |
|
|
|
} else { |
|
|
|
if (this.defaultCommand != null) { |
|
|
|
logger.debug("Attempting to use default command %s", this.defaultCommand); |
|
|
|
try { |
|
|
|
let newArgs = [command].concat(...args); |
|
|
|
logger.debug("Calling %s with %s", this._recognizedCommands.get(this.defaultCommand), newArgs); |
|
|
|
return this[this._recognizedCommands.get(this.defaultCommand)](...newArgs); |
|
|
|
} catch (e) { |
|
|
|
logger.error("Error while calling default command %s %s", this.defaultCommand, e); |
|
|
|
return this.cmd_help(); |
|
|
|
} |
|
|
|
} else { |
|
|
|
logger.debug("Unrecognized command %s", command); |
|
|
|
return this.cmd_help(); |
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
/* Basic cmd methods */ |
|
|
|
|
|
|
|
/* |
|
|
|
return basic help information,. |
|
|
|
*/ |
|
|
|
cmd_help(...args) { |
|
|
|
return message.createBasic(this.name + " HELP!"); |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
let abstractModulePrototype = Object.getPrototypeOf(new AbstractModule('', '', '')); |
|
|
|
|
|
|
|
/* |
|
|
|
Initialization of a module. |
|
|
|
*/ |
|
|
|
function init(mod) { |
|
|
|
logger.debug("Initializing module %s", mod.name) |
|
|
|
let commandMethods = getObjectKeysToPrototype(mod, abstractModulePrototype, (key) => { |
|
|
|
return key.startsWith('cmd_') && isFunction(mod[key]); |
|
|
|
}) |
|
|
|
// let commandMethods = objectKeys.filter();
|
|
|
|
logger.debug("Identified command methods: %s", commandMethods); |
|
|
|
commandMethods.forEach((commandMethodName) => { |
|
|
|
let command = commandMethodName.substring(4); |
|
|
|
mod.addRecognizedCommand(command, commandMethodName); |
|
|
|
}) |
|
|
|
logger.debug("Bound command methods for %s as %s", mod.name, mod.getRecognizedCommands()); |
|
|
|
} |
|
|
|
|
|
|
|
exports.AbstractModule = AbstractModule |
|
|
|
exports.AbstractModule = AbstractModule |
|
|
|
exports.initModule = init; |