From c9e3efac6e953a9cab35765a16a5930254414b96 Mon Sep 17 00:00:00 2001 From: Eric Martindale Date: Wed, 18 Apr 2018 19:37:21 +0200 Subject: [PATCH 1/5] Canonicalize on Matrix event.sender --- services/matrix.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/services/matrix.js b/services/matrix.js index 21e6538..c6f5c8c 100644 --- a/services/matrix.js +++ b/services/matrix.js @@ -183,7 +183,7 @@ Matrix.prototype._presence_change = function handlePresence (message) { Matrix.prototype._member_joined_channel = function handleJoin (message) { if (message.event.content.membership !== 'join') return; this.emit('join', { - user: message.sender.userId, + user: message.event.sender, channel: message.target.roomId }); }; From 73906668de47bbd4b396addd4e43415f51307f7c Mon Sep 17 00:00:00 2001 From: Eric Martindale Date: Fri, 20 Apr 2018 14:42:53 +0200 Subject: [PATCH 2/5] Add getUser() to services/matrix, generalize messaging API --- README.md | 2 +- lib/doorman.js | 22 ++++++++++++---------- lib/router.js | 7 ++++--- services/matrix.js | 18 +++++++++++++----- 4 files changed, 30 insertions(+), 19 deletions(-) diff --git a/README.md b/README.md index 6d8495a..4f36e93 100644 --- a/README.md +++ b/README.md @@ -61,7 +61,7 @@ List of external plugins for you to include with your installation (if you wish) - [mathfact](https://github.com/FabricLabs/doorman-mathfact) => spits out a random math fact - [yearfact](https://github.com/FabricLabs/doorman-yearfact) => spits out a random year fact - [datefact](https://github.com/FabricLabs/doorman-datefact) => spits out a random date fact -- [remaeusfact](https://github.com/FabricLabs/doorman-remaeusfact) => spits out a random fact about [Remaeus](https://github.com/martindale) +- [remaeusfact](https://github.com/FabricLabs/doorman-remaeusfact) => spits out a random fact about [Remaeus](https://www.roleplaygateway.com/member/Rem%C3%A6us/) ### Simple Plugins #### Ping-Pong Example Plugin, `./plugins/ping.json` diff --git a/lib/doorman.js b/lib/doorman.js index 576274e..65c3782 100644 --- a/lib/doorman.js +++ b/lib/doorman.js @@ -117,26 +117,26 @@ Doorman.prototype.enable = function enable (name) { let now = Date.now(); let id = [now, msg.actor, msg.target, msg.object].join('/'); let hash = crypto.createHash('sha256').update(id).digest('hex'); - let full = [name, 'messages', (msg.id || hash)].join('/'); - - self.emit('message', { - id: full, - created: now, + let message = { + id: [name, 'messages', (msg.id || hash)].join('/'), actor: [name, 'users', msg.actor].join('/'), target: [name, 'channels', msg.target].join('/'), object: msg.object, + created: now, '@data': msg - }); + }; + + self.emit('message', message); - let response = await self.parse(msg.object); + let response = await self.parse(message); if (response) { self.emit('response', { - parent: full, + parent: message, response: response }); service.send(msg.target, response, { - parent: full + parent: message }); } }); @@ -185,7 +185,9 @@ Doorman.prototype.use = function assemble (plugin) { if (self.plugins[name].triggers) { Object.keys(self.plugins[name].triggers).forEach(trigger => { - self.register(self.plugins[name].triggers[trigger]); + self.register(Object.assign({ + plugin: name + }, self.plugins[name].triggers[trigger])); }); } } else { diff --git a/lib/router.js b/lib/router.js index ee9ebd2..2ebe97b 100644 --- a/lib/router.js +++ b/lib/router.js @@ -16,9 +16,10 @@ function Router (config) { * @return {Array} List of outputs generated from the input string. */ Router.prototype.route = async function handle (msg) { - if (typeof msg !== 'string') return; + if (!msg.actor || !msg.object || !msg.target) return null; + if (typeof msg.object !== 'string') return null; let output = []; - let parts = msg + let parts = msg.object .split(/\s+/g) .filter(x => x.charAt(0) === this.config.trigger) .map(x => x.substr(1)); @@ -35,7 +36,7 @@ Router.prototype.route = async function handle (msg) { result = handler.value; break; default: - result = await handler.value.apply(this.fabric.plugins[command], [msg]); + result = await handler.value.apply(this.fabric.plugins[handler.plugin], [msg]); break; } diff --git a/services/matrix.js b/services/matrix.js index c6f5c8c..a16e21c 100644 --- a/services/matrix.js +++ b/services/matrix.js @@ -131,6 +131,14 @@ Matrix.prototype._getUsers = async function getUsers () { return result; }; +Matrix.prototype._getUser = async function getUser (id) { + let result = await this.connection.getUser(id); + let user = Object.assign({ + id: result.userId + }, result); + return user; +}; + Matrix.prototype._getPresences = async function getPresences () { let result = await this.connection.getPresenceList(); console.log('getPresences() got:', result); @@ -140,7 +148,10 @@ Matrix.prototype._getPresences = async function getPresences () { Matrix.prototype._getMembers = async function getMembers(id) { let room = await this.connection.getRoom(id); for (let i in room.currentState.members) { - await this._registerUser(room.currentState.members[i]); + let member = Object.assign({ + id: i + }, room.currentState.members[i]); + await this._registerUser(member); } return Object.keys(room.currentState.members); }; @@ -163,10 +174,7 @@ Matrix.prototype._registerUser = function registerUser (user) { }; Matrix.prototype._presence_change = function handlePresence (message) { - console.log('presence change:', message); - let id = `/users/${message.event.sender}`; - if (!this.map[id]) this._registerUser({ id: message.event.sender }); this.map[id].online = (message.event.content.presence === 'online'); @@ -184,7 +192,7 @@ Matrix.prototype._member_joined_channel = function handleJoin (message) { if (message.event.content.membership !== 'join') return; this.emit('join', { user: message.event.sender, - channel: message.target.roomId + channel: message.event.room_id }); }; From 18dab9f7cbb5d573d744eca1a9c619df14880988 Mon Sep 17 00:00:00 2001 From: Eric Martindale Date: Fri, 20 Apr 2018 15:58:33 +0200 Subject: [PATCH 3/5] Update message/response test to use new API --- test/doorman.unit.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/test/doorman.unit.js b/test/doorman.unit.js index aff5d32..e0988fd 100644 --- a/test/doorman.unit.js +++ b/test/doorman.unit.js @@ -19,7 +19,7 @@ describe('Doorman', function () { doorman.use(sample); doorman.on('response', function (message) { - assert.equal(message.parent, 'local/messages/test'); + assert.equal(message.parent.id, 'local/messages/test'); assert.equal(message.response, sample.test); done(); }); From 8ad99cd0aabf98f89a088c00f32dd5c2f9864e55 Mon Sep 17 00:00:00 2001 From: Eric Martindale Date: Mon, 23 Apr 2018 16:38:52 +0200 Subject: [PATCH 4/5] Send markdown instead of HTML to Matrix --- services/matrix.js | 12 ++---------- 1 file changed, 2 insertions(+), 10 deletions(-) diff --git a/services/matrix.js b/services/matrix.js index a16e21c..a3f41b9 100644 --- a/services/matrix.js +++ b/services/matrix.js @@ -102,7 +102,7 @@ Matrix.prototype.handler = function route (message) { Matrix.prototype.send = function send (channel, message) { let html = markdown(message); // TODO: complain to `matrix-js-sdk` about duplicate params - this.connection.sendHtmlMessage(channel, html, html); + this.connection.sendHtmlMessage(channel, message, html); }; Matrix.prototype._getChannels = async function getChannels () { @@ -145,7 +145,7 @@ Matrix.prototype._getPresences = async function getPresences () { return result; }; -Matrix.prototype._getMembers = async function getMembers(id) { +Matrix.prototype._getMembers = async function getMembers (id) { let room = await this.connection.getRoom(id); for (let i in room.currentState.members) { let member = Object.assign({ @@ -176,16 +176,8 @@ Matrix.prototype._registerUser = function registerUser (user) { Matrix.prototype._presence_change = function handlePresence (message) { let id = `/users/${message.event.sender}`; if (!this.map[id]) this._registerUser({ id: message.event.sender }); - this.map[id].online = (message.event.content.presence === 'online'); this.map[id].presence = message.event.content.presence; - - // TODO: generate this from Fabric - this.emit('patch', { - op: 'replace', - path: [id, 'online'].join('/'), - value: this.map[id].online - }); }; Matrix.prototype._member_joined_channel = function handleJoin (message) { From 71b2ff9ca18de2c8c32681ee4241000695339470 Mon Sep 17 00:00:00 2001 From: Eric Martindale Date: Mon, 23 Apr 2018 23:54:40 +0200 Subject: [PATCH 5/5] Add name to Matrix, ready event for services --- lib/doorman.js | 24 ++++++++++++++---------- lib/service.js | 2 ++ services/matrix.js | 27 +++++++++++---------------- 3 files changed, 27 insertions(+), 26 deletions(-) diff --git a/lib/doorman.js b/lib/doorman.js index 65c3782..18097dd 100644 --- a/lib/doorman.js +++ b/lib/doorman.js @@ -36,6 +36,16 @@ util.inherits(Doorman, require('events').EventEmitter); Doorman.prototype.start = function configure () { let self = this; + self.enable('local'); + + if (self.config.services && Array.isArray(self.config.services)) { + self.config.services.forEach(service => self.enable(service)); + } + + if (self.config.plugins && Array.isArray(self.config.plugins)) { + self.config.plugins.forEach(module => self.use(module)); + } + if (self.config.triggers) { Object.keys(self.config.triggers).forEach(name => { let route = { @@ -47,16 +57,6 @@ Doorman.prototype.start = function configure () { }); } - if (self.config.plugins && Array.isArray(self.config.plugins)) { - self.config.plugins.forEach(module => self.use(module)); - } - - self.enable('local'); - - if (self.config.services && Array.isArray(self.config.services)) { - self.config.services.forEach(service => self.enable(service)); - } - self.register({ name: 'help', value: `Available triggers: ${Object.keys(self.triggers).map(x => '`' + self.config.trigger + x + '`').join(', ')}` @@ -141,6 +141,10 @@ Doorman.prototype.enable = function enable (name) { } }); + service.on('ready', function () { + self.emit('service', { name }); + }); + this.services[name] = service; this.services[name].connect(); diff --git a/lib/service.js b/lib/service.js index 5df92d9..b9084ca 100644 --- a/lib/service.js +++ b/lib/service.js @@ -38,6 +38,8 @@ Service.prototype.connect = function initialize () { callback(null, chunk); } }); + + this.ready(); }; Service.prototype.ready = function ready () { diff --git a/services/matrix.js b/services/matrix.js index a3f41b9..5b2f7e2 100644 --- a/services/matrix.js +++ b/services/matrix.js @@ -34,19 +34,6 @@ Matrix.prototype.connect = function initialize () { Matrix.prototype.ready = async function () { let self = this; - - console.log('[MATRIX]', 'ready!'); - - this.connection.on('event', this.handler.bind(this)); - this.connection.on('Room.timeline', function (event, room) { - //- console.log('shenanigans!', event, room); - }); - this.connection.on('RoomMember.membership', function (event, member) { - if (member.membership === 'invite' && member.userId === self.config.user) { - self.connection.joinRoom(member.roomId); - } - }); - let users = await self._getUsers(); let channels = await self._getChannels(); let presences = await self._getPresences(); @@ -59,12 +46,19 @@ Matrix.prototype.ready = async function () { self._registerChannel(channels[id]); } + console.log('[MATRIX]', 'ready!'); + + this.connection.on('event', this.handler.bind(this)); + this.connection.on('RoomMember.membership', function (event, member, old) { + if (member.membership === 'invite' && member.userId === self.config.user) { + self.connection.joinRoom(member.roomId); + } + }); + self.emit('ready'); }; Matrix.prototype.sync = function handleSync (state, previous, data) { - console.log('[MATRIX]', 'sync received:', state, previous, data); - switch (state) { case 'PREPARED': this.ready(); @@ -134,7 +128,8 @@ Matrix.prototype._getUsers = async function getUsers () { Matrix.prototype._getUser = async function getUser (id) { let result = await this.connection.getUser(id); let user = Object.assign({ - id: result.userId + id: result.userId, + name: result.displayName }, result); return user; };