Skip to content

Commit

Permalink
Merge pull request #6 from WickrInc/default-handler
Browse files Browse the repository at this point in the history
Add default handler for 1:1 messages
  • Loading branch information
dwickr committed Oct 11, 2023
2 parents f68c69c + 2fb90f5 commit 5f57cfc
Show file tree
Hide file tree
Showing 4 changed files with 53 additions and 19 deletions.
36 changes: 29 additions & 7 deletions lib/bot.js
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@ class WickrBot extends EventEmitter {
this.handlers = {
'help': {fn: this.sendHelp.bind(this) },
}
this.defaultHandler = undefined

this.username = username || this._getUsername()
this.on('start', () => this.wickr.cmdStartAsyncRecvMessages(this.handleMessage()))
Expand All @@ -34,18 +35,29 @@ class WickrBot extends EventEmitter {
this.emit('start')
}

/**
* _parseMessage reads an incoming message and parses out the command and arguments.
* The command is whatever word immediately follows a forward-slash at the beginning of
* the message, and the arguments are all of the words that follow.
*
* If the message is not in slash-command format, the args are returned with no command.
* @param {string} message
* @returns {command, args}
*/
_parseMessage(message) {
let regex = /^\/([\w\d]+)(?:@[^\s]+)?\s*(.*)?/
let match = message.match(regex)
if (match == null) {
return null
let splitArgs = (s) => s.trim().split(/\s+/)

if (match === null) {
return { command: undefined, args: splitArgs(message)}
}

let command = match[1]
let args = []
// set the args to everything after the /command in the message (if available)
if (match[2] != null) {
args = match[2].trim().split(/\s+/)
args = splitArgs(match[2])
}

return {command: command, args: args}
Expand Down Expand Up @@ -93,12 +105,14 @@ class WickrBot extends EventEmitter {

let msg = this._parseMessage(data.message)

if (msg && msg.command in this.handlers) {
if (msg.command in this.handlers) {
try {
this.handlers[msg.command].fn(data, msg.args)
} catch (error) {
console.error(`Error executing '${msg.command}' handler:`, error)
}
} else if (typeof msg.command === 'undefined' && this.defaultHandler) {
this.defaultHandler(data, msg.args)
}
}
}
Expand Down Expand Up @@ -242,7 +256,12 @@ class WickrBot extends EventEmitter {
if (typeof user === 'string') {
user = [user]
}
return this.wickr.cmdSend1to1Message(user, content, '', '', '', [], JSON.stringify(properties?.meta)|| '')

try {
return this.wickr.cmdSend1to1Message(user, content, '', '', '', [], JSON.stringify(properties?.meta) || '')
} catch (error) {
console.error('Error sending 1:1 message:', error)
}
}

/**
Expand All @@ -255,10 +274,9 @@ class WickrBot extends EventEmitter {
*/
sendMessage(room, content, properties) {
try {
// TODO: I might need to stringify propeties.meta here
return this.wickr.cmdSendRoomMessage(room, content, '', '', '', [], JSON.stringify(properties?.meta) || '')
} catch (error) {
console.error('Error sending message:', error)
console.error('Error sending group message:', error)
}
}

Expand All @@ -277,6 +295,10 @@ class WickrBot extends EventEmitter {
}
}

setDefaultHandler(fn) {
this.defaultHandler = fn
}

async waitForState(state, retries=10, interval=1000, exponential=true) {
const curState = this.wickr.getClientState()

Expand Down
4 changes: 2 additions & 2 deletions package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "wickrbot",
"version": "0.1.6",
"version": "0.2.0",
"description": "Framework for WickrIO bots",
"main": "lib/bot.js",
"directories": {
Expand Down
30 changes: 21 additions & 9 deletions test/test-wickr-bot.js
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,17 @@ describe('wickr-bot', function() {
expect(spyFn.calledWith(JSON.parse(fakeMsg), ['bar', 'baz'])).to.be.true
})

it('creates a default listener', function() {
let fakeMsg = '{"msgtype": 1000, "message": "hey what\'s up?"}'
let spyFn = sinon.spy()
let bot = new WickrBot(this.wickr, 'foo')

bot.setDefaultHandler(spyFn)
bot.handleMessage()(fakeMsg)

expect(spyFn.calledWith(JSON.parse(fakeMsg), ['hey', 'what\'s', 'up?'])).to.be.true
})

describe('#handleMessage', function() {
it('catches errors thrown in handlers', function() {
let fakeMsg = '{"msgtype": 1000, "message": "/foo@fake-bot"}'
Expand Down Expand Up @@ -143,20 +154,21 @@ describe('wickr-bot', function() {
expect(msg).to.eql({command: 'subscribe', args: ['foo', 'bar', 'baz']})
})

it('returns null for unrecognized messages', function() {
it('returns just the arguments for unrecognized messages', function() {
let bot = new WickrBot(this.wickr, 'foo')
let messages = [
'omg hi becky',
'¯\\_(ツ)_/¯',
'//ohai',
'```\n/foo bar',
'eicaighooduuh5uwuy7Die0quies4ahsh6Goiyung8cae9Poopheemoyae9Ni2',
'[email protected]',
{ input: 'omg hi becky', expected: ['omg', 'hi', 'becky'] },
{ input: '¯\\_(ツ)_/¯', expected: ['¯\\_(ツ)_/¯'] },
{ input: '//ohai', expected: ['//ohai'] },
{ input: '```\n/foo bar', expected: ['```', '/foo', 'bar'] },
{ input: 'eicaighooduuh5uwuy7Die0quies4ahsh6Goiyung8cae9Poopheemoyae9Ni2', expected: ['eicaighooduuh5uwuy7Die0quies4ahsh6Goiyung8cae9Poopheemoyae9Ni2']},
{ input: '[email protected]', expected: ['[email protected]'] },
]

messages.forEach(m => {
let msg = bot._parseMessage(m)
expect(msg).to.be.null
let msg = bot._parseMessage(m.input)
expect(msg.command).to.be.undefined
expect(msg.args).to.eql(m.expected)
})
})
})
Expand Down

0 comments on commit 5f57cfc

Please sign in to comment.