UNPKG

4.37 kBtext/coffeescriptView Raw
1# Description:
2# Have Hubot perform actions when it hears user-specified keywords.
3#
4# Dependencies:
5# quick-gist: 1.2.0
6#
7# Configuration:
8# HUBOT_EAVESDROP_DELAY: Seconds to wait before an event can be triggered a second time. Default is 30.
9#
10# Commands:
11# hubot when you hear <pattern> do <something hubot does> - Setup a eavesdropping event
12# hubot stop listening - Stop all eavesdropping (requires user to be an 'admin')
13# hubot stop listening for <pattern> - Remove a particular eavesdropping event
14# hubot show listening - Show what hubot is eavesdropping on
15#
16# Author:
17# garylin
18# contolini
19# inhumantsar
20
21gist = require 'quick-gist'
22TextMessage = require('hubot').TextMessage
23
24class EavesDropping
25 constructor: (@robot) ->
26 @delay = process.env.HUBOT_EAVESDROP_DELAY || 30
27 @recentEvents = {}
28 initialized = false
29 robot.brain.on 'loaded', =>
30 return if initialized
31 initialized = true
32 eavesdroppings = @robot.brain.get 'eavesdroppings'
33 @eavesdroppings = eavesdroppings or []
34 @robot.brain.set 'eavesdroppings', @eavesdroppings
35
36 add: (pattern, user, action, order) ->
37 task = {key: pattern, task: action, order: order, creator: user}
38 @eavesdroppings.push task
39 all: -> @eavesdroppings
40 deleteByPattern: (pattern, msg) ->
41 filtered = @eavesdroppings.filter (n) -> n.key != pattern
42 if @eavesdroppings.length == filtered.length
43 return msg.send "I'm not listening for #{pattern}."
44 @eavesdroppings = filtered
45 @robot.brain.set 'eavesdroppings', @eavesdroppings
46 msg.send "Okay, I will ignore #{pattern}."
47 deleteAll: () ->
48 @eavesdroppings = []
49 @robot.brain.set 'eavesdroppings', @eavesdroppings
50
51module.exports = (robot) ->
52 eavesDropper = new EavesDropping robot
53
54 robot.respond /when you hear (.+?) do echo (.+?)$/i, (msg) ->
55 msg.reply "Please use the new format: \"#{robot.name} when you hear [phrase] respond with [reponse]\""
56
57 robot.respond /when you hear (.+?) respond with (.+?)$/i, (msg) ->
58 key = msg.match[1]
59 for task_raw in msg.match[2].split ";"
60 task_split = task_raw.split "|"
61 # If it's a single task, don't add an "order" property
62 if not task_split[1]
63 eavesDropper.add(key, msg.envelope.user.name, task_split[0])
64 else
65 eavesDropper.add(key, msg.envelope.user.name, task_split[0], task_split[1])
66 msg.send "I am now listening for #{key}."
67
68 robot.respond /stop (listening|eavesdropping)$/i, (msg) ->
69 if robot.auth.hasRole msg.envelope.user, 'admin'
70 eavesDropper.deleteAll()
71 msg.send 'Okay, I will no longer listen for anything.'
72 else
73 msg.send 'Sorry, only admins can delete all eavesdroppings.'
74
75 robot.respond /stop (listening|eavesdropping) (for|on) (.+?)$/i, (msg) ->
76 pattern = msg.match[3]
77 eavesDropper.deleteByPattern(pattern, msg)
78
79 robot.respond /show (listening|eavesdropping)s?/i, (msg) ->
80 response = "\n"
81 if eavesDropper.all().length < 1
82 return msg.send "I'm not listening for anything."
83 for task in eavesDropper.all()
84 response += "#{task.key} -> #{task.task} (#{task.creator})\n"
85 if response.length < 1000
86 msg.send response
87 else
88 gist {content: response}, (err, resp, data) ->
89 url = data.html_url
90 msg.send "I'm listening for the following items: " + url
91
92 robot.hear /(.+)/i, (msg) ->
93 robotHeard = msg.match[1]
94
95 # To play nicely with adapters that spoof the bot's name in DMs, don't respond
96 # if the message starts with "hubot:" or "hubot when you hear"
97 if new RegExp("^#{robot.name}\:", "i").test(robotHeard) or new RegExp("^(#{robot.name} )?when you hear", "i").test(robotHeard)
98 return
99
100 tasks = eavesDropper.all()
101 tasks.sort (a,b) ->
102 return if a.order >= b.order then 1 else -1
103
104 tasksToRun = []
105 for task in tasks
106 if new RegExp(task.key, "i").test(robotHeard)
107 tasksToRun.push task
108
109 tasksToRun.sort (a,b) ->
110 return if a.order >= b.order then 1 else -1
111
112 for task in tasksToRun
113 if robot.name != msg.message.user.name
114 now = Date.now()
115 lastTime = eavesDropper.recentEvents[task.key]
116 if msg.message.user.name == task.creator or !lastTime or (now - lastTime) / 1000 > eavesDropper.delay
117 robot.messageRoom msg.room, task.task
118 eavesDropper.recentEvents[task.key] = now