From 7b48f9bc213340103afc07d23172be59d7ec9723 Mon Sep 17 00:00:00 2001 From: Lewis Dale Date: Fri, 3 Feb 2017 23:00:23 +0000 Subject: [PATCH] Modifications to module system: * Renamed Module to JanetModule to reduce chance of clashes with NodeJS module * Changes to event dispatcher - different PubSub instances for each type of event * Fixed issues with arguments and scoping when modules triggered --- config.json | 6 ++-- janet.js | 45 +++++++++++++++++++++------ modules/greet.js | 26 ++++++++++------ modules/{module.js => janetmodule.js} | 13 +++++--- modules/time.js | 25 +++++++++++++++ package.json | 4 ++- 6 files changed, 92 insertions(+), 27 deletions(-) rename modules/{module.js => janetmodule.js} (77%) create mode 100644 modules/time.js diff --git a/config.json b/config.json index 6193005..742484d 100644 --- a/config.json +++ b/config.json @@ -1,10 +1,10 @@ { "irc": { - "server": "jfc.im", - "port": 6697, + "server": "localhost", + "port": 6667, "user": "Janet", "channels": [ - "#team2" + "#botchannel" ] } } diff --git a/janet.js b/janet.js index 352971a..19def89 100644 --- a/janet.js +++ b/janet.js @@ -1,15 +1,18 @@ const fs = require('fs') const irc = require('irc') +const PubSub = require('pubsub-js') + +const MessagePubSub = require('pubsub-js') class Janet { constructor() { this.config = this.loadConfig() - this.modules = { - 'pm': [], - 'join': [], - 'message': [] + + this.events = { + 'join': require('pubsub-js'), + 'message': require('pubsub-js') } this.loadModules() @@ -21,6 +24,20 @@ class Janet { } ) + this.client.addListener('message', (from, to, message) => { + if(message.substr(0,6) === "Janet,") { + let command = message.replace('Janet, ','').trim() + this.events.message.publish(command, { + from: from, + to: to, + message: message + }) + } + }) + + this.client.addListener('join', (channel, who) => { + PubSub.publish('join', who) + }) } /** @@ -37,20 +54,30 @@ class Janet { loadModules() { let files = fs.readdirSync('modules') for (let file of files) { + if (file.substr(-3) === '.js') { let title = file.substr(0, file.length - 3) - if (title !== 'module') { - let module = require('./modules/' + title) + if (title !== 'janetmodule') { + let module = require('./modules/' + title)(this) + for(let method of module.methods) { - if (method in this.modules) { - this.modules[method].push(module) - } + this.events[method].subscribe(module.command, (...args) => { + module.respond(...args) }) } } } } } + + /** + * Says a phrase across all of the joined channels + */ + say(phrase) { + for (let channel of this.config.irc.channels) { + this.client.say(channel, phrase) + } + } } const janet = new Janet(); diff --git a/modules/greet.js b/modules/greet.js index 6268088..e21d7f4 100644 --- a/modules/greet.js +++ b/modules/greet.js @@ -1,21 +1,27 @@ -const Module = require('./module') +const JanetModule = require('./janetmodule') -class Greet extends Module { +/** + * A simple greet module that says a friendly hello when somebody joins + * @author Lewis Dale + */ +class Greet extends JanetModule { - constructor() { + constructor(client) { super({ name: 'Greet', showInHelp: false, - command: 'Hello', + command: 'join', methods: ['join'] - }) - - this.test = {} + }, client) } - respond(input) { - return "Hello, " + input + respond(event, who) { + if (who !== "Janet") { + this.client.say("Hello, " + who) + } } } -module.exports = new Greet() +module.exports = (client) => { + return new Greet(client) +} diff --git a/modules/module.js b/modules/janetmodule.js similarity index 77% rename from modules/module.js rename to modules/janetmodule.js index 60663b5..51c3876 100644 --- a/modules/module.js +++ b/modules/janetmodule.js @@ -1,4 +1,4 @@ -class Module { +class JanetModule { /** * Construct a new Modules instance @@ -8,7 +8,7 @@ class Module { * @param opts.command: The command that triggers the action * @param opts.methods: A list of contact methods where the command is available */ - constructor(opts = {}) { + constructor(opts = {}, client) { let keys = [ 'name', 'showInHelp', @@ -22,6 +22,11 @@ class Module { } this[key] = opts[key] + + if (client === undefined || client === null) { + throw new TypeError("Client object was not passed to the module") + } + this.client = client } } @@ -30,9 +35,9 @@ class Module { * Response to the input, triggered by the command * @return A string response */ - respond(input) { + respond() { throw new TypeError("Function respond has not been implemented. Please override Module.respond()") } } -module.exports = Module +module.exports = JanetModule diff --git a/modules/time.js b/modules/time.js new file mode 100644 index 0000000..cc5727f --- /dev/null +++ b/modules/time.js @@ -0,0 +1,25 @@ +const JanetModule = require('./janetmodule') + +/** + * A simple command to ask Janet the current time + * @author Lewis Dale + */ +class Time extends JanetModule { + constructor(client) { + super({ + name: 'Time', + showInHelp: true, + command: 'what time is it?', + methods: ['message'] + }, client) + } + + respond(event, data) { + let date = new Date() + this.client.say(data.from + ", it is currently " + date.toTimeString()) + } +} + +module.exports = (client) => { + return new Time(client) +} diff --git a/package.json b/package.json index 18377e5..58d8cbc 100644 --- a/package.json +++ b/package.json @@ -4,6 +4,7 @@ "description": "A NodeJS-based IRC bot", "main": "janet.js", "scripts": { + "start": "node janet.js", "test": "echo \"Error: no test specified\" && exit 1" }, "repository": { @@ -17,6 +18,7 @@ "author": "Lewis Dale ", "license": "MIT", "dependencies": { - "irc": "^0.5.2" + "irc": "^0.5.2", + "pubsub-js": "^1.5.4" } }