This repository was archived by the owner on Jun 8, 2023. It is now read-only.
-
Notifications
You must be signed in to change notification settings - Fork 1.9k
/
Copy pathresponders.coffee
103 lines (91 loc) · 2.9 KB
/
responders.coffee
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
# Description:
# Define new responders on the fly.
#
# Dependencies:
# None
#
# Configuration:
# None
#
# Commands:
# hubot responders - List all responders
# hubot responder /pattern/ - Show a responder
# hubot forget /pattern/ - Remove a responder
# hubot respond /pattern/ msg.send(...) - Create a new responder
#
# Notes:
# It's possible to crash Hubot with this script. Comparing pathological
# strings against evil regular expressions will crash Hubot. Callbacks with
# infinite loops will crash Hubot. So, you know, don't do that. For example,
# this is bad: "Hubot: respond /(a+)+/ while(1);".
#
# Author:
# tfausak
class Responders
constructor: (@robot) ->
@robot.brain.data.responders = {}
@robot.brain.on 'loaded', (data) =>
for pattern, responder of data.responders
delete responder.index
@add(pattern, responder.callback)
responders: ->
@robot.brain.data.responders
responder: (pattern) ->
@responders()[pattern]
remove: (pattern) ->
responder = @responder(pattern)
if responder
if responder.index
@robot.listeners.splice(responder.index, 1, (->))
delete @responders()[pattern]
responder
add: (pattern, callback) ->
try
eval_pattern = eval("/#{pattern}/i")
catch error
eval_pattern = null
try
eval_callback = eval("_ = function (msg) { #{callback} }")
catch error
eval_callback = null
if eval_pattern instanceof RegExp and eval_callback instanceof Function
@remove(pattern)
@robot.respond(eval_pattern, eval_callback)
@responders()[pattern] = {
callback: callback,
index: @robot.listeners.length - 1,
}
@responder(pattern)
module.exports = (robot) ->
responders = new Responders(robot)
robot.respond /responders/i, (msg) ->
patterns = Object.keys(responders.responders()).sort()
if patterns.length
response = ''
for pattern in patterns
response += "/#{pattern}/ #{responders.responder(pattern).callback}\n"
msg.send(response.trim())
else
msg.send("I'm not responding to anything.")
robot.respond /responder \/(.+)\//i, (msg) ->
pattern = msg.match[1]
responder = responders.responder(pattern)
if responder
msg.send(responder.callback)
else
msg.send("I'm not responding to /#{pattern}/.")
robot.respond /forget \/(.+)\//i, (msg) ->
pattern = msg.match[1]
responder = responders.remove(pattern)
if responder
msg.send("I'll stop responding to /#{pattern}/.")
else
msg.send("I wasn't responding to /#{pattern}/ anyway.")
robot.respond /respond \/(.+)\/ ([^]+)/i, (msg) ->
pattern = msg.match[1]
callback = msg.match[2]
responder = responders.add(pattern, callback)
if responder
msg.send("I'll start responding to /#{pattern}/.")
else
msg.send("I'd like to respond to /#{pattern}/ but something went wrong.")