diff --git a/lib/bot.js b/lib/bot.js index 8e7e8aa..de345c3 100644 --- a/lib/bot.js +++ b/lib/bot.js @@ -25,6 +25,7 @@ class WickrBot extends EventEmitter { 'help': {fn: this.sendHelp.bind(this) }, } this.defaultHandler = undefined + this.fileHandler = undefined this.username = username || this._getUsername() this.on('start', () => this.wickr.cmdStartAsyncRecvMessages(this.handleMessage())) @@ -98,22 +99,26 @@ class WickrBot extends EventEmitter { handleMessage() { // return as an arrow function to maintain `this` binding return (message) => { - //console.log("Message received:", message); let data = JSON.parse(message) - if (data.msgtype !== MESSAGE_TYPE.TEXT) { - return - } + let handler, handlerName, args + + if (data.msgtype === MESSAGE_TYPE.FILE) { + handler = this.fileHandler + handlerName = 'file' + } else if (data.msgtype === MESSAGE_TYPE.TEXT) { + const msg = this._parseMessage(data.message) - let msg = this._parseMessage(data.message) + args = msg.args + handler = this.handlers[msg.command]?.fn || this.defaultHandler + handlerName = msg.command || 'default' + } - if (msg.command in this.handlers) { + if (handler) { try { - this.handlers[msg.command].fn(data, msg.args) + handler(data, args) } catch (error) { - console.error(`Error executing '${msg.command}' handler:`, error) + console.warn(`Error executing ${handlerName} handler:`, error) } - } else if (typeof msg.command === 'undefined' && this.defaultHandler) { - this.defaultHandler(data, msg.args) } } } @@ -296,10 +301,34 @@ class WickrBot extends EventEmitter { } } + /** + * setDefaultHandler defines the function which will be called when a text message is received + * which does not match any slash command + * + * @param {function (msg, args)} fn The function to call + */ setDefaultHandler(fn) { this.defaultHandler = fn } + /** + * setFileHandler defines the function which will be called when a file is received + * + * See https://wickrinc.github.io/wickrio-docs/#definitions-wickr-message-formats-file-transfer-messages + * for the complete format of a file transfer message + * + * @param {function (msg)} fn The function to call when a file is received + */ + setFileHandler(fn) { + this.fileHandler = fn + } + + /** + * setAvatar sets the user icon for the bot in Wickr + * + * @param {string} imgPath path to an image file containing the avatar + * @returns {boolean} `true` when the operation succeeded, `false` otherwise + */ setAvatar(imgPath) { if (!fs.existsSync(imgPath)) throw new Error(`Unable to set avatar. File ${imgPath} not found.`) diff --git a/test/test-wickr-bot.js b/test/test-wickr-bot.js index f3181bf..524a879 100644 --- a/test/test-wickr-bot.js +++ b/test/test-wickr-bot.js @@ -4,7 +4,7 @@ const sinon = require('sinon') const FakeWickr = require('./fakes/wickr') const WickrBot = require('../lib/bot') -describe('wickr-bot', function() { +describe('WickrBot', function() { beforeEach(function() { this.wickr = new FakeWickr() }) @@ -33,7 +33,7 @@ describe('wickr-bot', function() { expect(spyFn.calledWith(JSON.parse(fakeMsg), ['bar', 'baz'])).to.be.true }) - it('creates a default listener', function() { + it('sets a default listener', function() { let fakeMsg = '{"msgtype": 1000, "message": "hey what\'s up?"}' let spyFn = sinon.spy() let bot = new WickrBot(this.wickr, 'foo') @@ -44,6 +44,17 @@ describe('wickr-bot', function() { expect(spyFn.calledWith(JSON.parse(fakeMsg), ['hey', 'what\'s', 'up?'])).to.be.true }) + it('sets a file listener', function() { + let fakeMsg = '{"msgtype": 6000}' + let spyFn = sinon.spy() + let bot = new WickrBot(this.wickr, 'foo') + + bot.setFileHandler(spyFn) + bot.handleMessage()(fakeMsg) + + expect(spyFn.calledWith(JSON.parse(fakeMsg))).to.be.true + }) + describe('#handleMessage', function() { it('catches errors thrown in handlers', function() { let fakeMsg = '{"msgtype": 1000, "message": "/foo@fake-bot"}'