slack-smart-bot 1.7.0 → 1.9.1
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 +52 -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 +11 -6
- 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 +2 -6
- 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 +33 -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 +227 -186
- data/lib/slack/smart-bot/process_first.rb +104 -87
- data/lib/slack/smart-bot/treat_message.rb +116 -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 +18 -0
- metadata +22 -12
- 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,32 @@ 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
|
-
if data.text.match(
|
61
|
-
|
62
|
-
|
63
|
-
|
64
|
-
|
65
|
-
|
66
|
-
|
71
|
+
if !dest.nil? and !data.text.nil? and !data.text.to_s.match?(/\A\s*\z/)
|
72
|
+
#if data.text.match(/^\s*<@#{config[:nick_id]}>\s+(on\s+)?<#(\w+)\|([^>]+)>\s*:?\s*(.*)/im)
|
73
|
+
if data.text.match(/^\s*<@#{config[:nick_id]}>\s+(on\s+)?((<#\w+\|[^>]+>\s*)+)\s*:?\s*(.*)/im)
|
74
|
+
channels_rules = $2 #multiple channels @smart-bot on #channel1 #channel2 echo AAA
|
75
|
+
data_text = $4
|
76
|
+
channel_rules_name = ''
|
77
|
+
channel_rules = ''
|
78
|
+
# to be treated only on the bots of the requested channels
|
79
|
+
channels_rules.scan(/<#(\w+)\|([^>]+)>/).each do |tcid, tcname|
|
80
|
+
if @channel_id == tcid
|
81
|
+
data.text = data_text
|
82
|
+
typem = :on_call
|
83
|
+
channel_rules = tcid
|
84
|
+
channel_rules_name = tcname
|
85
|
+
break
|
86
|
+
end
|
67
87
|
end
|
68
|
-
elsif
|
88
|
+
elsif data.channel == @master_bot_id
|
69
89
|
if config.on_master_bot #only to be treated on master bot channel
|
70
90
|
typem = :on_master
|
71
91
|
end
|
72
|
-
elsif @bots_created.key?(
|
73
|
-
if @channel_id ==
|
92
|
+
elsif @bots_created.key?(data.channel)
|
93
|
+
if @channel_id == data.channel #only to be treated by the bot on the channel
|
74
94
|
typem = :on_bot
|
75
95
|
end
|
76
|
-
elsif
|
96
|
+
elsif data.channel[0] == "D" #Direct message
|
77
97
|
get_rules_imported()
|
78
98
|
if @rules_imported.key?(data.user) && @rules_imported[data.user].key?(data.user) and
|
79
99
|
@bots_created.key?(@rules_imported[data.user][data.user])
|
@@ -85,21 +105,21 @@ class SlackSmartBot
|
|
85
105
|
#only to be treated by master bot
|
86
106
|
typem = :on_dm
|
87
107
|
end
|
88
|
-
elsif
|
108
|
+
elsif data.channel[0] == "C" or data.channel[0] == "G"
|
89
109
|
#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[
|
110
|
+
if !config.on_master_bot and @bots_created.key?(@channel_id) and @bots_created[@channel_id][:extended].include?(@channels_name[data.channel]) and
|
91
111
|
!data.text.match?(/^!?\s*(ruby|code)\s+/) and !data.text.match?(/^!?!?\s*(ruby|code)\s+/) and !data.text.match?(/^\^?\s*(ruby|code)\s+/)
|
92
112
|
typem = :on_extended
|
93
113
|
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
114
|
#or in case of running ruby, the master bot
|
95
115
|
@bots_created.each do |k, v|
|
96
|
-
if v.key?(:extended) and v[:extended].include?(@channels_name[
|
116
|
+
if v.key?(:extended) and v[:extended].include?(@channels_name[data.channel])
|
97
117
|
typem = :on_extended
|
98
118
|
break
|
99
119
|
end
|
100
120
|
end
|
101
121
|
end
|
102
|
-
if
|
122
|
+
if data.channel[0] == "G" and config.on_master_bot and typem != :on_extended #private group
|
103
123
|
typem = :on_pg
|
104
124
|
end
|
105
125
|
end
|
@@ -116,18 +136,27 @@ class SlackSmartBot
|
|
116
136
|
end
|
117
137
|
begin
|
118
138
|
#todo: when changed @questions user_id then move user_info inside the ifs to avoid calling it when not necessary
|
119
|
-
user_info =
|
120
|
-
|
139
|
+
user_info = get_user_info(data.user)
|
140
|
+
|
141
|
+
#user_info.user.id = data.user #todo: remove this line when slack issue with Wxxxx Uxxxx fixed
|
142
|
+
data.user = user_info.user.id #todo: remove this line when slack issue with Wxxxx Uxxxx fixed
|
143
|
+
if data.thread_ts.nil?
|
144
|
+
qdest = dest
|
145
|
+
else
|
146
|
+
qdest = data.thread_ts
|
147
|
+
end
|
148
|
+
if !answer(user_info.user.name, qdest).empty?
|
121
149
|
if data.text.match?(/^\s*(Bye|Bæ|Good\sBye|Adiós|Ciao|Bless|Bless\sBless|Adeu)\s(#{@salutations.join("|")})\s*$/i)
|
122
|
-
|
150
|
+
answer_delete(user_info.user.name, qdest)
|
123
151
|
command = data.text
|
124
152
|
else
|
125
|
-
command =
|
126
|
-
@
|
153
|
+
command = answer(user_info.user.name, qdest)
|
154
|
+
@answer[user_info.user.name][qdest] = data.text
|
155
|
+
@questions[user_info.user.name] = data.text # to be backwards compatible #todo remove it when 2.0
|
127
156
|
end
|
128
|
-
elsif @repl_sessions.key?(user_info.user.name) and
|
157
|
+
elsif @repl_sessions.key?(user_info.user.name) and data.channel==@repl_sessions[user_info.user.name][:dest] and
|
129
158
|
((@repl_sessions[user_info.user.name][:on_thread] and data.thread_ts == @repl_sessions[user_info.user.name][:thread_ts]) or
|
130
|
-
|
159
|
+
(!@repl_sessions[user_info.user.name][:on_thread] and data.thread_ts.to_s == '' ))
|
131
160
|
|
132
161
|
if data.text.match(/^\s*```(.*)```\s*$/im)
|
133
162
|
@repl_sessions[user_info.user.name][:command] = $1
|
@@ -140,16 +169,16 @@ class SlackSmartBot
|
|
140
169
|
end
|
141
170
|
|
142
171
|
#when added special characters on the message
|
143
|
-
if command.match(
|
172
|
+
if command.match(/\A\s*```(.*)```\s*\z/im)
|
144
173
|
command = $1
|
145
174
|
elsif command.size >= 2 and
|
146
|
-
|
175
|
+
((command[0] == "`" and command[-1] == "`") or (command[0] == "*" and command[-1] == "*") or (command[0] == "_" and command[-1] == "_"))
|
147
176
|
command = command[1..-2]
|
148
177
|
end
|
149
178
|
|
150
179
|
#ruby file attached
|
151
180
|
if !data.files.nil? and data.files.size == 1 and
|
152
|
-
|
181
|
+
(command.match?(/^(ruby|code)\s*$/) or (command.match?(/^\s*$/) and data.files[0].filetype == "ruby") or
|
153
182
|
(typem == :on_call and data.files[0].filetype == "ruby"))
|
154
183
|
res = Faraday.new("https://files.slack.com", headers: { "Authorization" => "Bearer #{config[:token]}" }).get(data.files[0].url_private)
|
155
184
|
command += " ruby" if command != "ruby"
|
@@ -160,47 +189,66 @@ class SlackSmartBot
|
|
160
189
|
command = "!" + command unless command[0] == "!" or command.match?(/^\s*$/) or command[0] == "^"
|
161
190
|
|
162
191
|
#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
|
192
|
+
channels = get_channels()
|
168
193
|
channel_found = channels.detect { |c| c.name == channel_rules_name }
|
169
|
-
members =
|
194
|
+
members = get_channel_members(@channels_id[channel_rules_name]) unless channel_found.nil?
|
170
195
|
if channel_found.nil?
|
171
196
|
@logger.fatal "Not possible to find the channel #{channel_rules_name}"
|
172
197
|
elsif channel_found.name == config.master_channel
|
173
|
-
respond "You cannot use the rules from Master Channel on any other channel.",
|
198
|
+
respond "You cannot use the rules from Master Channel on any other channel.", data.channel
|
174
199
|
elsif @status != :on
|
175
|
-
respond "The bot in that channel is not :on",
|
200
|
+
respond "The bot in that channel is not :on", data.channel
|
176
201
|
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)
|
202
|
+
process_first(user_info.user, command, dest, channel_rules, typem, data.files, data.ts, data.thread_ts, data.routine)
|
178
203
|
else
|
179
|
-
respond "You need to join the channel <##{channel_found.id}> to be able to use the rules.",
|
204
|
+
respond "You need to join the channel <##{channel_found.id}> to be able to use the rules.", data.channel
|
180
205
|
end
|
181
206
|
elsif config.on_master_bot and typem == :on_extended and
|
182
207
|
command.size > 0 and command[0] != "-"
|
183
208
|
# 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)
|
209
|
+
process_first(user_info.user, command, dest, @channel_id, typem, data.files, data.ts, data.thread_ts, data.routine)
|
185
210
|
elsif !config.on_master_bot and @bots_created[@channel_id].key?(:extended) and
|
186
211
|
@bots_created[@channel_id][:extended].include?(@channels_name[data.channel]) and
|
187
212
|
command.size > 0 and command[0] != "-"
|
188
|
-
process_first(user_info.user, command, dest, @channel_id, typem, data.files, data.ts, data.thread_ts)
|
213
|
+
process_first(user_info.user, command, dest, @channel_id, typem, data.files, data.ts, data.thread_ts, data.routine)
|
189
214
|
elsif (dest[0] == "D" or @channel_id == data.channel or data.user == config[:nick_id]) and
|
190
215
|
command.size > 0 and command[0] != "-"
|
191
|
-
process_first(user_info.user, command, dest, data.channel, typem, data.files, data.ts, data.thread_ts)
|
216
|
+
process_first(user_info.user, command, dest, data.channel, typem, data.files, data.ts, data.thread_ts, data.routine)
|
192
217
|
# if @botname on #channel_rules: do something
|
193
218
|
end
|
194
219
|
rescue Exception => stack
|
195
220
|
@logger.fatal stack
|
196
221
|
end
|
197
222
|
else
|
198
|
-
if !config.on_master_bot and !dest.nil? and (
|
223
|
+
if !config.on_master_bot and !dest.nil? and (data.channel == @master_bot_id or dest[0] == "D") and
|
199
224
|
data.text.match?(/^\s*bot\s+status\s*$/i) and @admin_users_id.include?(data.user)
|
200
225
|
respond "ping from #{config.channel}", dest
|
201
226
|
elsif !config.on_master_bot and !dest.nil? and data.user == config[:nick_id] and dest == @master_bot_id
|
202
227
|
# to treat on other bots the status messages populated on master bot
|
203
228
|
case data.text
|
229
|
+
when /From now on I'll be on maintenance status/i
|
230
|
+
sleep 2
|
231
|
+
if File.exist?("#{config.path}/config_tmp.status")
|
232
|
+
file_cts = IO.readlines("#{config.path}/config_tmp.status").join
|
233
|
+
unless file_cts.to_s() == ""
|
234
|
+
file_cts = eval(file_cts)
|
235
|
+
if file_cts.is_a?(Hash) and file_cts.key?(:on_maintenance)
|
236
|
+
config.on_maintenance = file_cts.on_maintenance
|
237
|
+
end
|
238
|
+
end
|
239
|
+
end
|
240
|
+
when /From now on I won't be on maintenance/i
|
241
|
+
sleep 2
|
242
|
+
if File.exist?("#{config.path}/config_tmp.status")
|
243
|
+
file_cts = IO.readlines("#{config.path}/config_tmp.status").join
|
244
|
+
unless file_cts.to_s() == ""
|
245
|
+
file_cts = eval(file_cts)
|
246
|
+
if file_cts.is_a?(Hash) and file_cts.key?(:on_maintenance)
|
247
|
+
config.on_maintenance = file_cts.on_maintenance
|
248
|
+
end
|
249
|
+
end
|
250
|
+
end
|
251
|
+
|
204
252
|
when /^Bot has been (closed|killed) by/i
|
205
253
|
sleep 2
|
206
254
|
get_bots_created()
|
@@ -213,6 +261,22 @@ class SlackSmartBot
|
|
213
261
|
when /removed the access to the rules of (.+) from (.+)\.$/i
|
214
262
|
sleep 2
|
215
263
|
get_bots_created()
|
264
|
+
when /global shortcut added/
|
265
|
+
sleep 2
|
266
|
+
if File.exist?("#{config.path}/shortcuts/shortcuts_global.rb")
|
267
|
+
file_sc = IO.readlines("#{config.path}/shortcuts/shortcuts_global.rb").join
|
268
|
+
unless file_sc.to_s() == ""
|
269
|
+
@shortcuts_global = eval(file_sc)
|
270
|
+
end
|
271
|
+
end
|
272
|
+
when /global shortcut deleted/
|
273
|
+
sleep 2
|
274
|
+
if File.exist?("#{config.path}/shortcuts/shortcuts_global.rb")
|
275
|
+
file_sc = IO.readlines("#{config.path}/shortcuts/shortcuts_global.rb").join
|
276
|
+
unless file_sc.to_s() == ""
|
277
|
+
@shortcuts_global = eval(file_sc)
|
278
|
+
end
|
279
|
+
end
|
216
280
|
end
|
217
281
|
end
|
218
282
|
end
|