1 |
|
2 |
|
3 |
|
4 |
|
5 |
|
6 |
|
7 |
|
8 |
|
9 |
|
10 |
|
11 |
|
12 |
|
13 |
|
14 |
|
15 | S = require 'string'
|
16 | RemoteSlack = require './remote-slack'
|
17 | Relay = require './relay'
|
18 |
|
19 | module.exports = (robot) ->
|
20 |
|
21 | BRAIN_KEY = 'hubot-slack-relay.storage'
|
22 | IGNORE_BOTS = process.env.IGNORE_BOTS or true
|
23 | relays = []
|
24 | client = robot.adapter.client
|
25 |
|
26 | brainLoaded = () =>
|
27 |
|
28 | data = (robot.brain.get BRAIN_KEY) || {}
|
29 |
|
30 | relays = for d in data
|
31 | relay = Relay.fromJSON d
|
32 | relay.on 'invalidChannel', invalidChannelError
|
33 | relay
|
34 |
|
35 | invalidChannelError = (relay) =>
|
36 | robot.logger.info 'invalidChannelError'
|
37 | remoteBot = relay.remote.client.self.name ? 'the remote bot'
|
38 |
|
39 | user = { room: relay.localRoom }
|
40 | robot.adapter.send user, 'Could not deliver message to \'' + relay.remoteRoom + '\' because ' + remoteBot + ' is not in the channel.'
|
41 |
|
42 | brainLoaded()
|
43 | robot.brain.on 'loaded', brainLoaded
|
44 |
|
45 | saveBrain = () =>
|
46 | robot.logger.info 'Save Brain'
|
47 |
|
48 |
|
49 | temp = relays
|
50 |
|
51 | robot.brain.set BRAIN_KEY, relays
|
52 | robot.brain.save()
|
53 |
|
54 |
|
55 | relays = temp
|
56 |
|
57 |
|
58 | robot.respond /relay add\s+(\S+)\s+(\S+)\s+(\S+)/i, (res) =>
|
59 | robot.logger.info 'relay add ' + res.match[1] + ' ' + res.match[2] + ' ' + res.match[3]
|
60 |
|
61 | localRoom = S(res.match[1]).chompLeft('#').s
|
62 | remoteRoom = S(res.match[2]).chompLeft('#').s
|
63 | remoteToken = S(res.match[3]).chompLeft('#').s
|
64 |
|
65 |
|
66 | if process.env.HUBOT_SLACK_TOKEN is remoteToken
|
67 | res.send 'This is the local hubot token. Please use the hubot token from the remote server.'
|
68 | return
|
69 |
|
70 | for relay in relays
|
71 | if relay.localRoom is localRoom and relay.remoteRoom is remoteRoom and relay.remote.token is remoteToken
|
72 | res.send 'This remote relay already exists.'
|
73 | return
|
74 |
|
75 |
|
76 | @newResponse = res
|
77 |
|
78 |
|
79 |
|
80 | remote = new RemoteSlack(remoteToken)
|
81 | @newRelay = new Relay localRoom, remote, remoteRoom
|
82 |
|
83 | remote.on 'remote.connected', newRemoteConnected
|
84 | remote.on 'remote.error', newRemoteError
|
85 |
|
86 | remote.login()
|
87 |
|
88 | newRemoteConnected = (remote) =>
|
89 | @newRelay.remote.removeListener('remote.connected',newRemoteConnected)
|
90 | @newRelay.remote.removeListener('remote.error',newRemoteError)
|
91 | @newRelay.on 'invalidChannel', invalidChannelError
|
92 |
|
93 | channel = @newRelay.remote.client.getChannelGroupOrDMByName @newRelay.remoteRoom
|
94 | remoteBot = @newRelay.remote.client.self.name ? 'the remote bot'
|
95 |
|
96 | if channel
|
97 |
|
98 | relays.push @newRelay
|
99 | saveBrain()
|
100 |
|
101 | if channel.is_member
|
102 | @newResponse.send 'Successfully connected to the remote relay and channel \'' + @newRelay.remoteRoom + '\'.'
|
103 | else
|
104 | @newResponse.send 'Successfully connected to the remote relay but ' + remoteBot + ' needs to be invited to \'' + @newRelay.remoteRoom + '\'.'
|
105 |
|
106 | else
|
107 | @newResponse.send 'Could not find the channel \'' + @newRelay.remoteRoom + '\' on the remote relay.'
|
108 |
|
109 |
|
110 | newRemoteError = (error) =>
|
111 | @newRelay.remote.removeListener('remote.connected',newRemoteConnected)
|
112 | @newRelay.remote.removeListener('remote.error',newRemoteError)
|
113 |
|
114 | t = S(@newRelay.remote.token).padLeft(5)
|
115 | @newResponse.send 'Could not connect to remote relay with token \'' + S('*').repeat(t.length - 5) + S(t.substr(t.length - 5)).trim() + '\'.'
|
116 |
|
117 | robot.respond /relay remove\s+(\S+)\s*(\S*)\s*(\S*)/i, (res) =>
|
118 | robot.logger.info 'relay remove ' + res.match[1] + ' ' + res.match[2] + ' ' + res.match[3]
|
119 |
|
120 | localRoom = S(res.match[1]).chompLeft('#').s
|
121 | remoteRoom = if res.match[2] then S(res.match[2]).chompLeft('#').s
|
122 | remoteToken = if res.match[3] then S(res.match[3]).chompLeft('#').s
|
123 |
|
124 | found = false
|
125 | if not remoteRoom
|
126 | relays = for relay in relays
|
127 |
|
128 | if relay.localRoom is localRoom
|
129 | found = true
|
130 | continue
|
131 | relay
|
132 | if found
|
133 | saveBrain()
|
134 | res.send 'Removed all remote relays associated with local channel \'' + localRoom + '\''
|
135 |
|
136 | else
|
137 | if remoteToken
|
138 | relays = for relay in relays
|
139 |
|
140 | t = relay.remote.token
|
141 | token = t.substr(t.length - 5)
|
142 | if relay.localRoom is localRoom and relay.remoteRoom is remoteRoom and token is remoteToken
|
143 | found = true
|
144 | continue
|
145 | relay
|
146 | if found
|
147 | saveBrain()
|
148 | res.send 'Removed remote relay - local-channel: ' + localRoom + ' remote-channel: ' + remoteRoom + ' remote-token: ' + remoteToken
|
149 | else
|
150 | matches = []
|
151 | potentialRelays = for relay in relays
|
152 | if relay.localRoom is localRoom and relay.remoteRoom is remoteRoom
|
153 | matches.push relay
|
154 | continue
|
155 | relay
|
156 |
|
157 | if matches.length is 1
|
158 | found = true
|
159 | relays = potentialRelays
|
160 | saveBrain()
|
161 | res.send 'Removed remote relay - local-channel: ' + localRoom + ' remote-channel: ' + remoteRoom
|
162 |
|
163 | else if matches.length > 1
|
164 | found = true
|
165 | res.send '*There are multiple options for this <local-channel> <remote-channel> combination.*\nPlease include the last 5 digits of the remote token and try again.\n`relay remove <local-channel> <remote-channel> <last 5 of remote-token>`'
|
166 | res.send blockList(matches)
|
167 |
|
168 | if not found
|
169 | res.send 'Could not find any records matching the criteria.'
|
170 |
|
171 | robot.respond /relay list/i, (res) =>
|
172 | robot.logger.info 'relay list'
|
173 | res.send blockList(relays)
|
174 |
|
175 |
|
176 | blockList = (collection, filter) =>
|
177 | if not collection or collection.length is 0 then return ''
|
178 | filter ?= () -> true
|
179 | list = '```'
|
180 | for item in collection when filter(item)
|
181 | list = list + item.toString() + '\n'
|
182 | list + '```'
|
183 |
|
184 | robot.hear /(.+)/i, (res) =>
|
185 |
|
186 | if IGNORE_BOTS and client.getUserByID(res.message.user.id).is_bot then return
|
187 |
|
188 | for relay in relays
|
189 | if res.message.room isnt relay.localRoom then continue
|
190 | user = { room: relay.remoteRoom }
|
191 | if not relay.remote.send user, '_' + res.message.user.name + ' said:_ ' + res.match[1]
|
192 | invalidChannelError relay
|
193 |
|
194 | robot.enter (res) ->
|
195 |
|
196 | if IGNORE_BOTS and client.getUserByID(res.message.user.id).is_bot then return
|
197 |
|
198 | for relay in relays
|
199 | if res.message.room isnt relay.localRoom then continue
|
200 | user = { room: relay.remoteRoom }
|
201 | if not relay.remote.send user, '_' + res.message.user.name + ' has entered #' + res.message.room + '_'
|
202 | invalidChannelError relay
|
203 |
|
204 | robot.leave (res) ->
|
205 |
|
206 | if IGNORE_BOTS and client.getUserByID(res.message.user.id).is_bot then return
|
207 |
|
208 | for relay in relays
|
209 | if res.message.room isnt relay.localRoom then continue
|
210 | user = { room: relay.remoteRoom }
|
211 | if not relay.remote.send user, '_' + res.message.user.name + ' has left #' + res.message.room + '_'
|
212 | invalidChannelError relay
|
213 |
|
214 |
|
215 |
|
216 |
|
217 |
|
218 |
|
219 |
|
220 |
|
221 |
|
222 |
|
223 |
|
224 |
|
225 |
|