slack-smart-bot 1.7.0 → 1.9.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/README.md +24 -12
- data/lib/slack-smart-bot.rb +53 -43
- data/lib/slack-smart-bot_general_rules.rb +7 -4
- data/lib/slack-smart-bot_rules.rb +8 -6
- data/lib/slack/smart-bot/comm.rb +6 -1
- data/lib/slack/smart-bot/comm/ask.rb +12 -5
- data/lib/slack/smart-bot/comm/dont_understand.rb +1 -1
- data/lib/slack/smart-bot/comm/event_hello.rb +30 -0
- data/lib/slack/smart-bot/comm/get_channel_members.rb +8 -0
- data/lib/slack/smart-bot/comm/get_channels.rb +20 -0
- data/lib/slack/smart-bot/comm/get_user_info.rb +16 -0
- data/lib/slack/smart-bot/comm/react.rb +21 -8
- data/lib/slack/smart-bot/comm/respond.rb +38 -12
- data/lib/slack/smart-bot/comm/send_file.rb +1 -1
- data/lib/slack/smart-bot/comm/send_msg_channel.rb +2 -2
- data/lib/slack/smart-bot/comm/send_msg_user.rb +4 -4
- data/lib/slack/smart-bot/comm/unreact.rb +29 -0
- data/lib/slack/smart-bot/commands.rb +3 -1
- data/lib/slack/smart-bot/commands/general/bot_help.rb +16 -3
- data/lib/slack/smart-bot/commands/general/bot_stats.rb +313 -0
- data/lib/slack/smart-bot/commands/general/bot_status.rb +1 -1
- data/lib/slack/smart-bot/commands/general/bye_bot.rb +1 -1
- data/lib/slack/smart-bot/commands/general/hi_bot.rb +1 -1
- data/lib/slack/smart-bot/commands/general/use_rules.rb +6 -9
- data/lib/slack/smart-bot/commands/general/whats_new.rb +19 -0
- data/lib/slack/smart-bot/commands/on_bot/add_shortcut.rb +65 -33
- data/lib/slack/smart-bot/commands/on_bot/admin/add_routine.rb +42 -9
- data/lib/slack/smart-bot/commands/on_bot/admin/extend_rules.rb +3 -7
- data/lib/slack/smart-bot/commands/on_bot/admin/pause_bot.rb +1 -0
- data/lib/slack/smart-bot/commands/on_bot/admin/see_routines.rb +9 -2
- data/lib/slack/smart-bot/commands/on_bot/admin/start_bot.rb +1 -0
- data/lib/slack/smart-bot/commands/on_bot/delete_repl.rb +1 -1
- data/lib/slack/smart-bot/commands/on_bot/delete_shortcut.rb +52 -21
- data/lib/slack/smart-bot/commands/on_bot/get_repl.rb +5 -5
- data/lib/slack/smart-bot/commands/on_bot/repl.rb +50 -18
- data/lib/slack/smart-bot/commands/on_bot/ruby_code.rb +34 -9
- data/lib/slack/smart-bot/commands/on_bot/run_repl.rb +2 -3
- data/lib/slack/smart-bot/commands/on_bot/see_repls.rb +1 -1
- data/lib/slack/smart-bot/commands/on_bot/see_shortcuts.rb +27 -9
- data/lib/slack/smart-bot/commands/on_extended/bot_rules.rb +14 -1
- data/lib/slack/smart-bot/commands/on_master/admin_master/exit_bot.rb +3 -3
- data/lib/slack/smart-bot/commands/on_master/admin_master/notify_message.rb +1 -1
- data/lib/slack/smart-bot/commands/on_master/admin_master/set_maintenance.rb +41 -0
- data/lib/slack/smart-bot/commands/on_master/create_bot.rb +4 -8
- data/lib/slack/smart-bot/listen.rb +6 -5
- data/lib/slack/smart-bot/process.rb +230 -186
- data/lib/slack/smart-bot/process_first.rb +104 -87
- data/lib/slack/smart-bot/treat_message.rb +128 -52
- data/lib/slack/smart-bot/utils.rb +2 -0
- data/lib/slack/smart-bot/utils/answer.rb +18 -0
- data/lib/slack/smart-bot/utils/answer_delete.rb +15 -0
- data/lib/slack/smart-bot/utils/build_help.rb +57 -5
- data/lib/slack/smart-bot/utils/create_routine_thread.rb +48 -8
- data/lib/slack/smart-bot/utils/get_channels_name_and_id.rb +1 -7
- data/lib/slack/smart-bot/utils/get_help.rb +79 -17
- data/lib/slack/smart-bot/utils/save_stats.rb +21 -8
- data/lib/slack/smart-bot/utils/update_shortcuts_file.rb +6 -0
- data/whats_new.txt +24 -0
- metadata +23 -13
- data/lib/slack/smart-bot/commands/on_bot/admin_master/bot_stats.rb +0 -135
@@ -1,5 +1,5 @@
|
|
1
1
|
class SlackSmartBot
|
2
|
-
def process_first(user, text, dest, dchannel, typem, files, ts, thread_ts)
|
2
|
+
def process_first(user, text, dest, dchannel, typem, files, ts, thread_ts, routine)
|
3
3
|
nick = user.name
|
4
4
|
rules_file = ""
|
5
5
|
text.gsub!(/^!!/,'^') # to treat it just as ^
|
@@ -80,21 +80,21 @@ class SlackSmartBot
|
|
80
80
|
text.match(/^()\^\s*(.+)\s*/im) or
|
81
81
|
text.match(/^()!\s*(.+)\s*/im) or
|
82
82
|
text.match(/^()<@#{config[:nick_id]}>\s+(.+)\s*/im)
|
83
|
-
|
84
|
-
|
85
|
-
|
86
|
-
|
87
|
-
|
83
|
+
command2 = $2
|
84
|
+
if text.match?(/^()\^\s*(.+)/im)
|
85
|
+
add_double_excl = true
|
86
|
+
addexcl = false
|
87
|
+
if command2.match?(/^![^!]/) or command2.match?(/^\^/)
|
88
88
|
command2[0]=''
|
89
|
-
|
89
|
+
elsif command2.match?(/^!!/)
|
90
90
|
command2[0]=''
|
91
91
|
command2[1]=''
|
92
|
-
|
93
|
-
|
92
|
+
end
|
93
|
+
else
|
94
94
|
add_double_excl = false
|
95
95
|
addexcl = true
|
96
|
-
|
97
|
-
|
96
|
+
end
|
97
|
+
command = command2
|
98
98
|
else
|
99
99
|
addexcl = false
|
100
100
|
if text.include?('$') #for shortcuts inside commands
|
@@ -111,6 +111,10 @@ class SlackSmartBot
|
|
111
111
|
command.gsub!("$#{sc}", @shortcuts[nick][sc])
|
112
112
|
elsif @shortcuts.key?(:all) and @shortcuts[:all].keys.include?(sc)
|
113
113
|
command.gsub!("$#{sc}", @shortcuts[:all][sc])
|
114
|
+
elsif @shortcuts_global.key?(nick) and @shortcuts_global[nick].keys.include?(sc)
|
115
|
+
command.gsub!("$#{sc}", @shortcuts_global[nick][sc])
|
116
|
+
elsif @shortcuts_global.key?(:all) and @shortcuts_global[:all].keys.include?(sc)
|
117
|
+
command.gsub!("$#{sc}", @shortcuts_global[:all][sc])
|
114
118
|
end
|
115
119
|
end
|
116
120
|
command.scan(/\$([^\s]+)/i).flatten.each do |sc|
|
@@ -119,6 +123,10 @@ class SlackSmartBot
|
|
119
123
|
command.gsub!("$#{sc}", @shortcuts[nick][sc])
|
120
124
|
elsif @shortcuts.key?(:all) and @shortcuts[:all].keys.include?(sc)
|
121
125
|
command.gsub!("$#{sc}", @shortcuts[:all][sc])
|
126
|
+
elsif @shortcuts_global.key?(nick) and @shortcuts_global[nick].keys.include?(sc)
|
127
|
+
command.gsub!("$#{sc}", @shortcuts_global[nick][sc])
|
128
|
+
elsif @shortcuts_global.key?(:all) and @shortcuts_global[:all].keys.include?(sc)
|
129
|
+
command.gsub!("$#{sc}", @shortcuts_global[:all][sc])
|
122
130
|
end
|
123
131
|
end
|
124
132
|
text = command
|
@@ -126,13 +134,19 @@ class SlackSmartBot
|
|
126
134
|
text = "^" + text if add_double_excl
|
127
135
|
end
|
128
136
|
if command.scan(/^(shortcut|sc)\s+([^:]+)\s*$/i).any? or
|
129
|
-
|
130
|
-
|
137
|
+
(@shortcuts.keys.include?(:all) and @shortcuts[:all].keys.include?(command)) or
|
138
|
+
(@shortcuts.keys.include?(nick) and @shortcuts[nick].keys.include?(command)) or
|
139
|
+
(@shortcuts_global.keys.include?(:all) and @shortcuts_global[:all].keys.include?(command)) or
|
140
|
+
(@shortcuts_global.keys.include?(nick) and @shortcuts_global[nick].keys.include?(command))
|
131
141
|
command = $2.downcase unless $2.nil?
|
132
142
|
if @shortcuts.keys.include?(nick) and @shortcuts[nick].keys.include?(command)
|
133
143
|
text = @shortcuts[nick][command].dup
|
134
144
|
elsif @shortcuts.keys.include?(:all) and @shortcuts[:all].keys.include?(command)
|
135
145
|
text = @shortcuts[:all][command].dup
|
146
|
+
elsif @shortcuts_global.keys.include?(nick) and @shortcuts_global[nick].keys.include?(command)
|
147
|
+
text = @shortcuts_global[nick][command].dup
|
148
|
+
elsif @shortcuts_global.keys.include?(:all) and @shortcuts_global[:all].keys.include?(command)
|
149
|
+
text = @shortcuts_global[:all][command].dup
|
136
150
|
else
|
137
151
|
respond "Shortcut not found", dest unless dest[0] == "C" and dchannel != dest #on extended channel
|
138
152
|
return :next #jal
|
@@ -154,6 +168,7 @@ class SlackSmartBot
|
|
154
168
|
Thread.current[:files?] = !files.nil? && files.size>0
|
155
169
|
Thread.current[:ts] = ts
|
156
170
|
Thread.current[:thread_ts] = thread_ts
|
171
|
+
Thread.current[:routine] = routine
|
157
172
|
if thread_ts.to_s == ''
|
158
173
|
Thread.current[:on_thread] = false
|
159
174
|
Thread.current[:thread_ts] = Thread.current[:ts] # to create the thread if necessary
|
@@ -187,96 +202,98 @@ class SlackSmartBot
|
|
187
202
|
command = command2
|
188
203
|
on_demand = true
|
189
204
|
end
|
190
|
-
|
191
|
-
|
192
|
-
|
193
|
-
|
194
|
-
(
|
195
|
-
|
196
|
-
|
197
|
-
(@listening[nick].key?(
|
198
|
-
|
199
|
-
|
200
|
-
|
205
|
+
unless config.on_maintenance and processed
|
206
|
+
if @status == :on and
|
207
|
+
(!answer.empty? or
|
208
|
+
(@repl_sessions.key?(nick) and dest==@repl_sessions[nick][:dest] and
|
209
|
+
((@repl_sessions[nick][:on_thread] and thread_ts == @repl_sessions[nick][:thread_ts]) or
|
210
|
+
(!@repl_sessions[nick][:on_thread] and !Thread.current[:on_thread] ))) or
|
211
|
+
(@listening.key?(nick) and typem != :on_extended and
|
212
|
+
((@listening[nick].key?(dest) and !Thread.current[:on_thread]) or
|
213
|
+
(@listening[nick].key?(thread_ts) and Thread.current[:on_thread] ) )) or
|
214
|
+
dest[0] == "D" or on_demand)
|
215
|
+
@logger.info "command: #{nick}> #{command}" unless processed
|
216
|
+
#todo: verify this
|
201
217
|
|
202
|
-
|
203
|
-
|
204
|
-
|
205
|
-
|
206
|
-
|
207
|
-
|
218
|
+
if dest[0] == "C" or dest[0] == "G" or (dest[0] == "D" and typem == :on_call)
|
219
|
+
if typem != :on_call and @rules_imported.key?(user.id) and @rules_imported[user.id].key?(dchannel)
|
220
|
+
if @bots_created.key?(@rules_imported[user.id][dchannel])
|
221
|
+
if @bots_created[@rules_imported[user.id][dchannel]][:status] != :on
|
222
|
+
respond "The bot on that channel is not :on", dest
|
223
|
+
rules_file = ""
|
224
|
+
end
|
208
225
|
end
|
209
226
|
end
|
210
|
-
|
211
|
-
unless rules_file.empty?
|
212
|
-
begin
|
213
|
-
eval(File.new(config.path+rules_file).read) if File.exist?(config.path+rules_file)
|
214
|
-
rescue Exception => stack
|
215
|
-
@logger.fatal "ERROR ON RULES FILE: #{rules_file}"
|
216
|
-
@logger.fatal stack
|
217
|
-
end
|
218
|
-
if defined?(rules)
|
219
|
-
command[0] = "" if command[0] == "!"
|
220
|
-
command.gsub!(/^@\w+:*\s*/, "")
|
221
|
-
if method(:rules).parameters.size == 4
|
222
|
-
rules(user, command, processed, dest)
|
223
|
-
elsif method(:rules).parameters.size == 5
|
224
|
-
rules(user, command, processed, dest, files)
|
225
|
-
else
|
226
|
-
rules(user, command, processed, dest, files, rules_file)
|
227
|
-
end
|
228
|
-
else
|
229
|
-
@logger.warn "It seems like rules method is not defined"
|
230
|
-
end
|
231
|
-
end
|
232
|
-
elsif @rules_imported.key?(user.id) and @rules_imported[user.id].key?(user.id)
|
233
|
-
if @bots_created.key?(@rules_imported[user.id][user.id])
|
234
|
-
if @bots_created[@rules_imported[user.id][user.id]][:status] == :on
|
227
|
+
unless rules_file.empty?
|
235
228
|
begin
|
236
|
-
eval(File.new(config.path+rules_file).read) if File.exist?(config.path+rules_file)
|
229
|
+
eval(File.new(config.path+rules_file).read) if File.exist?(config.path+rules_file)
|
237
230
|
rescue Exception => stack
|
238
|
-
@logger.fatal "ERROR ON
|
231
|
+
@logger.fatal "ERROR ON RULES FILE: #{rules_file}"
|
239
232
|
@logger.fatal stack
|
240
233
|
end
|
241
|
-
|
242
|
-
|
243
|
-
|
234
|
+
if defined?(rules)
|
235
|
+
command[0] = "" if command[0] == "!"
|
236
|
+
command.gsub!(/^@\w+:*\s*/, "")
|
237
|
+
if method(:rules).parameters.size == 4
|
238
|
+
rules(user, command, processed, dest)
|
239
|
+
elsif method(:rules).parameters.size == 5
|
240
|
+
rules(user, command, processed, dest, files)
|
241
|
+
else
|
242
|
+
rules(user, command, processed, dest, files, rules_file)
|
243
|
+
end
|
244
|
+
else
|
245
|
+
@logger.warn "It seems like rules method is not defined"
|
246
|
+
end
|
247
|
+
end
|
248
|
+
elsif @rules_imported.key?(user.id) and @rules_imported[user.id].key?(user.id)
|
249
|
+
if @bots_created.key?(@rules_imported[user.id][user.id])
|
250
|
+
if @bots_created[@rules_imported[user.id][user.id]][:status] == :on
|
251
|
+
begin
|
252
|
+
eval(File.new(config.path+rules_file).read) if File.exist?(config.path+rules_file) and !['.','..'].include?(config.path + rules_file)
|
253
|
+
rescue Exception => stack
|
254
|
+
@logger.fatal "ERROR ON imported RULES FILE: #{rules_file}"
|
255
|
+
@logger.fatal stack
|
256
|
+
end
|
257
|
+
else
|
258
|
+
respond "The bot on <##{@rules_imported[user.id][user.id]}|#{@bots_created[@rules_imported[user.id][user.id]][:channel_name]}> is not :on", dest
|
259
|
+
rules_file = ""
|
260
|
+
end
|
244
261
|
end
|
245
|
-
end
|
246
262
|
|
247
|
-
|
248
|
-
|
249
|
-
|
250
|
-
|
251
|
-
|
252
|
-
|
253
|
-
|
254
|
-
|
263
|
+
unless rules_file.empty?
|
264
|
+
if defined?(rules)
|
265
|
+
command[0] = "" if command[0] == "!"
|
266
|
+
command.gsub!(/^@\w+:*\s*/, "")
|
267
|
+
if method(:rules).parameters.size == 4
|
268
|
+
rules(user, command, processed, dest)
|
269
|
+
elsif method(:rules).parameters.size == 5
|
270
|
+
rules(user, command, processed, dest, files)
|
271
|
+
else
|
272
|
+
rules(user, command, processed, dest, files, rules_file)
|
273
|
+
end
|
255
274
|
else
|
256
|
-
rules
|
275
|
+
@logger.warn "It seems like rules method is not defined"
|
257
276
|
end
|
258
|
-
|
259
|
-
|
277
|
+
end
|
278
|
+
else
|
279
|
+
@logger.info "it is a direct message with no rules file selected so no rules file executed."
|
280
|
+
if command.match?(/^\s*bot\s+rules\s*(.*)$/i)
|
281
|
+
respond "No rules running. You can use the command `use rules from CHANNEL` to specify the rules you want to use on this private conversation.\n`bot help` to see available commands.", dest
|
282
|
+
end
|
283
|
+
unless processed
|
284
|
+
dont_understand('')
|
260
285
|
end
|
261
286
|
end
|
262
|
-
else
|
263
|
-
@logger.info "it is a direct message with no rules file selected so no rules file executed."
|
264
|
-
if command.match?(/^\s*bot\s+rules\s*$/i)
|
265
|
-
respond "No rules running. You can use the command `use rules from CHANNEL` to specify the rules you want to use on this private conversation.\n`bot help` to see available commands.", dest
|
266
|
-
end
|
267
|
-
unless processed
|
268
|
-
dont_understand('')
|
269
|
-
end
|
270
|
-
end
|
271
287
|
|
272
|
-
|
273
|
-
|
274
|
-
|
275
|
-
|
276
|
-
|
288
|
+
if processed and @listening.key?(nick)
|
289
|
+
if Thread.current[:on_thread] and @listening[nick].key?(Thread.current[:thread_ts])
|
290
|
+
@listening[nick][Thread.current[:thread_ts]] = Time.now
|
291
|
+
elsif !Thread.current[:on_thread] and @listening[nick].key?(dest)
|
292
|
+
@listening[nick][dest] = Time.now
|
293
|
+
end
|
277
294
|
end
|
278
|
-
end
|
279
295
|
|
296
|
+
end
|
280
297
|
end
|
281
298
|
rescue Exception => stack
|
282
299
|
@logger.fatal stack
|
@@ -4,45 +4,57 @@ class SlackSmartBot
|
|
4
4
|
begin
|
5
5
|
unless data.text.to_s.match(/\A\s*\z/)
|
6
6
|
#to remove italic, bold... from data.text since there is no method on slack api
|
7
|
-
#only works when no @user or #channel mentioned
|
8
7
|
if remove_blocks and !data.blocks.nil? and data.blocks.size > 0
|
8
|
+
data_text = ''
|
9
9
|
data.blocks.each do |b|
|
10
10
|
if b.type == 'rich_text'
|
11
11
|
if b.elements.size > 0
|
12
12
|
b.elements.each do |e|
|
13
|
-
if e.type == 'rich_text_section'
|
14
|
-
if e.elements.size > 0 and (e.elements.type.uniq - ['link', 'text']) == []
|
15
|
-
|
13
|
+
if e.type == 'rich_text_section' or e.type == 'rich_text_preformatted'
|
14
|
+
if e.elements.size > 0 and (e.elements.type.uniq - ['link', 'text', 'user', 'channel']) == []
|
15
|
+
data_text += '```' if e.type == 'rich_text_preformatted'
|
16
16
|
e.elements.each do |el|
|
17
17
|
if el.type == 'text'
|
18
|
-
|
18
|
+
data_text += el.text
|
19
|
+
elsif el.type == 'user'
|
20
|
+
data_text += "<@#{el.user_id}>"
|
21
|
+
elsif el.type == 'channel'
|
22
|
+
tch = data.text.scan(/(<##{el.channel_id}\|[^\>]+>)/).join
|
23
|
+
data_text += tch
|
19
24
|
else
|
20
|
-
|
25
|
+
data_text += el.url
|
21
26
|
end
|
22
27
|
end
|
28
|
+
data_text += '```' if e.type == 'rich_text_preformatted'
|
23
29
|
end
|
24
|
-
break
|
25
30
|
end
|
26
31
|
end
|
27
32
|
end
|
28
|
-
break
|
29
33
|
end
|
30
34
|
end
|
35
|
+
data.text = data_text unless data_text == ''
|
31
36
|
end
|
32
37
|
data.text = CGI.unescapeHTML(data.text)
|
33
38
|
data.text.gsub!("\u00A0", " ") #to change (asc char 160) into blank space
|
34
39
|
end
|
40
|
+
data.text.gsub!('‘', "'")
|
35
41
|
data.text.gsub!('’', "'")
|
36
|
-
data.text.gsub!('“', '"')
|
37
|
-
|
42
|
+
data.text.gsub!('“', '"')
|
43
|
+
data.text.gsub!('”', '"')
|
44
|
+
rescue Exception => exc
|
38
45
|
@logger.warn "Impossible to unescape or clean format for data.text:#{data.text}"
|
46
|
+
@logger.warn exc.inspect
|
39
47
|
end
|
48
|
+
data.routine = false unless data.key?(:routine)
|
49
|
+
|
40
50
|
if config[:testing] and config.on_master_bot
|
41
51
|
open("#{config.path}/buffer.log", "a") { |f|
|
42
|
-
f.puts "|#{data.channel}|#{data.user}|#{data.text}"
|
52
|
+
f.puts "|#{data.channel}|#{data.user}|#{data.user_name}|#{data.text}"
|
43
53
|
}
|
44
54
|
end
|
45
|
-
if data.
|
55
|
+
if data.key?(:dest) and data.dest.to_s!='' # for run routines and publish on different channels
|
56
|
+
dest = data.dest
|
57
|
+
elsif data.channel[0] == "D" or data.channel[0] == "C" or data.channel[0] == "G" #Direct message or Channel or Private Channel
|
46
58
|
dest = data.channel
|
47
59
|
else # not treated
|
48
60
|
dest = nil
|
@@ -56,24 +68,42 @@ class SlackSmartBot
|
|
56
68
|
@pings << $1
|
57
69
|
end
|
58
70
|
typem = :dont_treat
|
59
|
-
if !dest.nil? and !data.text.nil? and !data.text.to_s.match?(
|
60
|
-
|
61
|
-
|
62
|
-
|
63
|
-
|
64
|
-
|
65
|
-
|
66
|
-
|
71
|
+
if !dest.nil? and !data.text.nil? and !data.text.to_s.match?(/\A\s*\z/)
|
72
|
+
#todo: we need to add mixed channels: @smart-bot on private1 #bot1cm <#CXDDFRDDF|bot2cu>: echo A
|
73
|
+
if data.text.match(/^\s*<@#{config[:nick_id]}>\s+(on\s+)?((<#\w+\|[^>]+>\s*)+)\s*:?\s*(.*)/im) or
|
74
|
+
data.text.match(/^\s*<@#{config[:nick_id]}>\s+(on\s+)?((#[a-zA-Z0-9]+\s*)+)\s*:?\s*(.*)/im) or
|
75
|
+
data.text.match(/^\s*<@#{config[:nick_id]}>\s+(on\s+)?(([a-zA-Z0-9]+\s*)+)\s*:\s*(.*)/im)
|
76
|
+
channels_rules = $2 #multiple channels @smart-bot on #channel1 #channel2 echo AAA
|
77
|
+
data_text = $4
|
78
|
+
channel_rules_name = ''
|
79
|
+
channel_rules = ''
|
80
|
+
channels_arr = channels_rules.scan(/<#(\w+)\|([^>]+)>/)
|
81
|
+
if channels_arr.size == 0
|
82
|
+
channels_arr = []
|
83
|
+
channels_rules.scan(/([^\s]+)/).each do |cn|
|
84
|
+
cna = cn.join.gsub('#','')
|
85
|
+
channels_arr << [@channels_id[cna], cna]
|
86
|
+
end
|
67
87
|
end
|
68
|
-
|
88
|
+
# to be treated only on the bots of the requested channels
|
89
|
+
channels_arr.each do |tcid, tcname|
|
90
|
+
if @channel_id == tcid
|
91
|
+
data.text = data_text
|
92
|
+
typem = :on_call
|
93
|
+
channel_rules = tcid
|
94
|
+
channel_rules_name = tcname
|
95
|
+
break
|
96
|
+
end
|
97
|
+
end
|
98
|
+
elsif data.channel == @master_bot_id
|
69
99
|
if config.on_master_bot #only to be treated on master bot channel
|
70
100
|
typem = :on_master
|
71
101
|
end
|
72
|
-
elsif @bots_created.key?(
|
73
|
-
if @channel_id ==
|
102
|
+
elsif @bots_created.key?(data.channel)
|
103
|
+
if @channel_id == data.channel #only to be treated by the bot on the channel
|
74
104
|
typem = :on_bot
|
75
105
|
end
|
76
|
-
elsif
|
106
|
+
elsif data.channel[0] == "D" #Direct message
|
77
107
|
get_rules_imported()
|
78
108
|
if @rules_imported.key?(data.user) && @rules_imported[data.user].key?(data.user) and
|
79
109
|
@bots_created.key?(@rules_imported[data.user][data.user])
|
@@ -85,21 +115,21 @@ class SlackSmartBot
|
|
85
115
|
#only to be treated by master bot
|
86
116
|
typem = :on_dm
|
87
117
|
end
|
88
|
-
elsif
|
118
|
+
elsif data.channel[0] == "C" or data.channel[0] == "G"
|
89
119
|
#only to be treated on the channel of the bot. excluding running ruby
|
90
|
-
if !config.on_master_bot and @bots_created.key?(@channel_id) and @bots_created[@channel_id][:extended].include?(@channels_name[
|
120
|
+
if !config.on_master_bot and @bots_created.key?(@channel_id) and @bots_created[@channel_id][:extended].include?(@channels_name[data.channel]) and
|
91
121
|
!data.text.match?(/^!?\s*(ruby|code)\s+/) and !data.text.match?(/^!?!?\s*(ruby|code)\s+/) and !data.text.match?(/^\^?\s*(ruby|code)\s+/)
|
92
122
|
typem = :on_extended
|
93
123
|
elsif config.on_master_bot and (data.text.match?(/^!?\s*(ruby|code)\s+/) or data.text.match?(/^!?!?\s*(ruby|code)\s+/) or data.text.match?(/^\^?\s*(ruby|code)\s+/) )
|
94
124
|
#or in case of running ruby, the master bot
|
95
125
|
@bots_created.each do |k, v|
|
96
|
-
if v.key?(:extended) and v[:extended].include?(@channels_name[
|
126
|
+
if v.key?(:extended) and v[:extended].include?(@channels_name[data.channel])
|
97
127
|
typem = :on_extended
|
98
128
|
break
|
99
129
|
end
|
100
130
|
end
|
101
131
|
end
|
102
|
-
if
|
132
|
+
if data.channel[0] == "G" and config.on_master_bot and typem != :on_extended #private group
|
103
133
|
typem = :on_pg
|
104
134
|
end
|
105
135
|
end
|
@@ -116,18 +146,27 @@ class SlackSmartBot
|
|
116
146
|
end
|
117
147
|
begin
|
118
148
|
#todo: when changed @questions user_id then move user_info inside the ifs to avoid calling it when not necessary
|
119
|
-
user_info =
|
120
|
-
|
149
|
+
user_info = get_user_info(data.user)
|
150
|
+
|
151
|
+
#user_info.user.id = data.user #todo: remove this line when slack issue with Wxxxx Uxxxx fixed
|
152
|
+
data.user = user_info.user.id #todo: remove this line when slack issue with Wxxxx Uxxxx fixed
|
153
|
+
if data.thread_ts.nil?
|
154
|
+
qdest = dest
|
155
|
+
else
|
156
|
+
qdest = data.thread_ts
|
157
|
+
end
|
158
|
+
if !answer(user_info.user.name, qdest).empty?
|
121
159
|
if data.text.match?(/^\s*(Bye|Bæ|Good\sBye|Adiós|Ciao|Bless|Bless\sBless|Adeu)\s(#{@salutations.join("|")})\s*$/i)
|
122
|
-
|
160
|
+
answer_delete(user_info.user.name, qdest)
|
123
161
|
command = data.text
|
124
162
|
else
|
125
|
-
command =
|
126
|
-
@
|
163
|
+
command = answer(user_info.user.name, qdest)
|
164
|
+
@answer[user_info.user.name][qdest] = data.text
|
165
|
+
@questions[user_info.user.name] = data.text # to be backwards compatible #todo remove it when 2.0
|
127
166
|
end
|
128
|
-
elsif @repl_sessions.key?(user_info.user.name) and
|
167
|
+
elsif @repl_sessions.key?(user_info.user.name) and data.channel==@repl_sessions[user_info.user.name][:dest] and
|
129
168
|
((@repl_sessions[user_info.user.name][:on_thread] and data.thread_ts == @repl_sessions[user_info.user.name][:thread_ts]) or
|
130
|
-
|
169
|
+
(!@repl_sessions[user_info.user.name][:on_thread] and data.thread_ts.to_s == '' ))
|
131
170
|
|
132
171
|
if data.text.match(/^\s*```(.*)```\s*$/im)
|
133
172
|
@repl_sessions[user_info.user.name][:command] = $1
|
@@ -140,16 +179,16 @@ class SlackSmartBot
|
|
140
179
|
end
|
141
180
|
|
142
181
|
#when added special characters on the message
|
143
|
-
if command.match(
|
182
|
+
if command.match(/\A\s*```(.*)```\s*\z/im)
|
144
183
|
command = $1
|
145
184
|
elsif command.size >= 2 and
|
146
|
-
|
185
|
+
((command[0] == "`" and command[-1] == "`") or (command[0] == "*" and command[-1] == "*") or (command[0] == "_" and command[-1] == "_"))
|
147
186
|
command = command[1..-2]
|
148
187
|
end
|
149
188
|
|
150
189
|
#ruby file attached
|
151
190
|
if !data.files.nil? and data.files.size == 1 and
|
152
|
-
|
191
|
+
(command.match?(/^(ruby|code)\s*$/) or (command.match?(/^\s*$/) and data.files[0].filetype == "ruby") or
|
153
192
|
(typem == :on_call and data.files[0].filetype == "ruby"))
|
154
193
|
res = Faraday.new("https://files.slack.com", headers: { "Authorization" => "Bearer #{config[:token]}" }).get(data.files[0].url_private)
|
155
194
|
command += " ruby" if command != "ruby"
|
@@ -160,47 +199,68 @@ class SlackSmartBot
|
|
160
199
|
command = "!" + command unless command[0] == "!" or command.match?(/^\s*$/) or command[0] == "^"
|
161
200
|
|
162
201
|
#todo: add pagination for case more than 1000 channels on the workspace
|
163
|
-
channels =
|
164
|
-
types: "private_channel,public_channel",
|
165
|
-
limit: "1000",
|
166
|
-
exclude_archived: "true",
|
167
|
-
).channels
|
202
|
+
channels = get_channels()
|
168
203
|
channel_found = channels.detect { |c| c.name == channel_rules_name }
|
169
|
-
members =
|
204
|
+
members = get_channel_members(@channels_id[channel_rules_name]) unless channel_found.nil?
|
170
205
|
if channel_found.nil?
|
171
206
|
@logger.fatal "Not possible to find the channel #{channel_rules_name}"
|
172
207
|
elsif channel_found.name == config.master_channel
|
173
|
-
respond "You cannot use the rules from Master Channel on any other channel.",
|
208
|
+
respond "You cannot use the rules from Master Channel on any other channel.", data.channel
|
174
209
|
elsif @status != :on
|
175
|
-
respond "The bot in that channel is not :on",
|
210
|
+
respond "The bot in that channel is not :on", data.channel
|
176
211
|
elsif data.user == channel_found.creator or members.include?(data.user)
|
177
|
-
process_first(user_info.user, command, dest, channel_rules, typem, data.files, data.ts, data.thread_ts)
|
212
|
+
process_first(user_info.user, command, dest, channel_rules, typem, data.files, data.ts, data.thread_ts, data.routine)
|
178
213
|
else
|
179
|
-
respond "You need to join the channel <##{channel_found.id}> to be able to use the rules.",
|
214
|
+
respond "You need to join the channel <##{channel_found.id}> to be able to use the rules.", data.channel
|
180
215
|
end
|
181
216
|
elsif config.on_master_bot and typem == :on_extended and
|
182
217
|
command.size > 0 and command[0] != "-"
|
183
218
|
# to run ruby only from the master bot for the case more than one extended
|
184
|
-
process_first(user_info.user, command, dest, @channel_id, typem, data.files, data.ts, data.thread_ts)
|
219
|
+
process_first(user_info.user, command, dest, @channel_id, typem, data.files, data.ts, data.thread_ts, data.routine)
|
185
220
|
elsif !config.on_master_bot and @bots_created[@channel_id].key?(:extended) and
|
186
221
|
@bots_created[@channel_id][:extended].include?(@channels_name[data.channel]) and
|
187
222
|
command.size > 0 and command[0] != "-"
|
188
|
-
process_first(user_info.user, command, dest, @channel_id, typem, data.files, data.ts, data.thread_ts)
|
223
|
+
process_first(user_info.user, command, dest, @channel_id, typem, data.files, data.ts, data.thread_ts, data.routine)
|
189
224
|
elsif (dest[0] == "D" or @channel_id == data.channel or data.user == config[:nick_id]) and
|
190
225
|
command.size > 0 and command[0] != "-"
|
191
|
-
process_first(user_info.user, command, dest, data.channel, typem, data.files, data.ts, data.thread_ts)
|
226
|
+
process_first(user_info.user, command, dest, data.channel, typem, data.files, data.ts, data.thread_ts, data.routine)
|
192
227
|
# if @botname on #channel_rules: do something
|
193
228
|
end
|
194
229
|
rescue Exception => stack
|
195
230
|
@logger.fatal stack
|
196
231
|
end
|
197
232
|
else
|
198
|
-
if !config.on_master_bot and !dest.nil? and (
|
233
|
+
if !config.on_master_bot and !dest.nil? and (data.channel == @master_bot_id or dest[0] == "D") and
|
199
234
|
data.text.match?(/^\s*bot\s+status\s*$/i) and @admin_users_id.include?(data.user)
|
200
235
|
respond "ping from #{config.channel}", dest
|
201
236
|
elsif !config.on_master_bot and !dest.nil? and data.user == config[:nick_id] and dest == @master_bot_id
|
202
237
|
# to treat on other bots the status messages populated on master bot
|
203
238
|
case data.text
|
239
|
+
when /From now on I'll be on maintenance status/i
|
240
|
+
sleep 2
|
241
|
+
if File.exist?("#{config.path}/config_tmp.status")
|
242
|
+
file_cts = IO.readlines("#{config.path}/config_tmp.status").join
|
243
|
+
unless file_cts.to_s() == ""
|
244
|
+
file_cts = eval(file_cts)
|
245
|
+
if file_cts.is_a?(Hash) and file_cts.key?(:on_maintenance)
|
246
|
+
config.on_maintenance = file_cts.on_maintenance
|
247
|
+
config.on_maintenance_message = file_cts.on_maintenance_message
|
248
|
+
end
|
249
|
+
end
|
250
|
+
end
|
251
|
+
when /From now on I won't be on maintenance/i
|
252
|
+
sleep 2
|
253
|
+
if File.exist?("#{config.path}/config_tmp.status")
|
254
|
+
file_cts = IO.readlines("#{config.path}/config_tmp.status").join
|
255
|
+
unless file_cts.to_s() == ""
|
256
|
+
file_cts = eval(file_cts)
|
257
|
+
if file_cts.is_a?(Hash) and file_cts.key?(:on_maintenance)
|
258
|
+
config.on_maintenance = file_cts.on_maintenance
|
259
|
+
config.on_maintenance_message = file_cts.on_maintenance_message
|
260
|
+
end
|
261
|
+
end
|
262
|
+
end
|
263
|
+
|
204
264
|
when /^Bot has been (closed|killed) by/i
|
205
265
|
sleep 2
|
206
266
|
get_bots_created()
|
@@ -213,6 +273,22 @@ class SlackSmartBot
|
|
213
273
|
when /removed the access to the rules of (.+) from (.+)\.$/i
|
214
274
|
sleep 2
|
215
275
|
get_bots_created()
|
276
|
+
when /global shortcut added/
|
277
|
+
sleep 2
|
278
|
+
if File.exist?("#{config.path}/shortcuts/shortcuts_global.rb")
|
279
|
+
file_sc = IO.readlines("#{config.path}/shortcuts/shortcuts_global.rb").join
|
280
|
+
unless file_sc.to_s() == ""
|
281
|
+
@shortcuts_global = eval(file_sc)
|
282
|
+
end
|
283
|
+
end
|
284
|
+
when /global shortcut deleted/
|
285
|
+
sleep 2
|
286
|
+
if File.exist?("#{config.path}/shortcuts/shortcuts_global.rb")
|
287
|
+
file_sc = IO.readlines("#{config.path}/shortcuts/shortcuts_global.rb").join
|
288
|
+
unless file_sc.to_s() == ""
|
289
|
+
@shortcuts_global = eval(file_sc)
|
290
|
+
end
|
291
|
+
end
|
216
292
|
end
|
217
293
|
end
|
218
294
|
end
|