-
Notifications
You must be signed in to change notification settings - Fork 2
/
eavesdrop.coffee
113 lines (99 loc) · 4.25 KB
/
eavesdrop.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
104
105
106
107
108
109
110
111
112
113
# Description:
# Have Hubot perform actions when it hears user-specified keywords.
#
# Dependencies:
# quick-gist: 1.2.0
#
# Configuration:
# HUBOT_EAVESDROP_DELAY: Seconds to wait before an event can be triggered a second time. Default is 30.
#
# Commands:
# hubot when you hear <pattern> respond with <response> - Setup a eavesdropping event
# hubot stop listening - Stop all eavesdropping (requires user to be an 'admin')
# hubot stop listening for <pattern> - Remove a particular eavesdropping event
# hubot show listening - Show what hubot is eavesdropping on
#
# Author:
# garylin
# contolini
# inhumantsar
gist = require 'quick-gist'
class EavesDropping
constructor: (@robot) ->
@delay = process.env.HUBOT_EAVESDROP_DELAY || 30
@recentEvents = {}
add: (pattern, user, action, order) ->
task = {key: pattern, task: action, order: order, creator: user}
@eavesdroppings = @eavesdroppings or @robot.brain.get('eavesdroppings') or []
@eavesdroppings.push task
@robot.brain.set 'eavesdroppings', @eavesdroppings
all: ->
@eavesdroppings or @robot.brain.get('eavesdroppings') or []
deleteByPattern: (pattern, msg) ->
@eavesdroppings = @eavesdroppings or @robot.brain.get 'eavesdroppings'
filtered = @eavesdroppings.filter (n) -> n.key != pattern
if @eavesdroppings.length == filtered.length
return msg.send "I'm not listening for #{pattern}."
@eavesdroppings = filtered
@robot.brain.set 'eavesdroppings', @eavesdroppings
msg.send "Okay, I will ignore #{pattern}."
deleteAll: () ->
@eavesdroppings = []
@robot.brain.set 'eavesdroppings', @eavesdroppings
module.exports = (robot) ->
eavesDropper = new EavesDropping robot
robot.respond /when you hear (.+?) do echo (.+?)$/i, (msg) ->
msg.reply "Please use the new format: \"#{robot.name} when you hear [phrase] respond with [reponse]\""
robot.respond /when you hear (.+?) (respond|reply) with (.+?)$/i, (msg) ->
key = msg.match[1]
for task_raw in msg.match[3].split ";"
task_split = task_raw.split "|"
# If it's a single task, don't add an "order" property
if not task_split[1]
eavesDropper.add(key, msg.envelope.user.name, task_split[0])
else
eavesDropper.add(key, msg.envelope.user.name, task_split[0], task_split[1])
msg.send "I am now listening for #{key}."
robot.respond /stop (listening|eavesdropping)$/i, (msg) ->
if robot.auth.hasRole msg.envelope.user, 'admin'
eavesDropper.deleteAll()
msg.send 'Okay, I will no longer listen for anything.'
else
msg.send 'Sorry, only admins can delete all eavesdroppings.'
robot.respond /stop (listening|eavesdropping) (for|on) (.+?)$/i, (msg) ->
pattern = msg.match[3]
eavesDropper.deleteByPattern(pattern, msg)
robot.respond /show (listening|listener|listeners|eavesdropping)s?/i, (msg) ->
response = "\n"
if eavesDropper.all().length < 1
return msg.send "I'm not listening for anything."
for task in eavesDropper.all()
response += "#{task.key} -> #{task.task} (#{task.creator})\n"
if response.length < 1000
msg.send response
else
gist {content: response}, (err, resp, data) ->
url = data.html_url
msg.send "I'm listening for the following items: " + url
robot.hear /(.+)/i, (msg) ->
robotHeard = msg.match[1]
# To play nicely with adapters that spoof the bot's name in DMs, don't respond
# if the message starts with "hubot:" or "hubot when you hear"
if new RegExp("^#{robot.name}\:", "i").test(robotHeard) or new RegExp("^(#{robot.name} )?when you hear", "i").test(robotHeard)
return
tasks = eavesDropper.all()
tasks.sort (a,b) ->
return if a.order >= b.order then 1 else -1
tasksToRun = []
for task in tasks
if new RegExp(task.key, "i").test(robotHeard)
tasksToRun.push task
tasksToRun.sort (a,b) ->
return if a.order >= b.order then 1 else -1
for task in tasksToRun
if robot.name != msg.message.user.name
now = Date.now()
lastTime = eavesDropper.recentEvents[task.key]
if msg.message.user.name == task.creator or !lastTime or (now - lastTime) / 1000 > eavesDropper.delay
robot.messageRoom msg.envelope.room, task.task
eavesDropper.recentEvents[task.key] = now