slack-smart-bot 1.8.2 → 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.
Files changed (58) hide show
  1. checksums.yaml +4 -4
  2. data/README.md +18 -11
  3. data/lib/slack-smart-bot.rb +43 -44
  4. data/lib/slack-smart-bot_rules.rb +6 -6
  5. data/lib/slack/smart-bot/comm.rb +5 -1
  6. data/lib/slack/smart-bot/comm/ask.rb +12 -5
  7. data/lib/slack/smart-bot/comm/dont_understand.rb +1 -1
  8. data/lib/slack/smart-bot/comm/event_hello.rb +30 -0
  9. data/lib/slack/smart-bot/comm/get_channel_members.rb +8 -0
  10. data/lib/slack/smart-bot/comm/get_channels.rb +20 -0
  11. data/lib/slack/smart-bot/comm/get_user_info.rb +16 -0
  12. data/lib/slack/smart-bot/comm/react.rb +21 -8
  13. data/lib/slack/smart-bot/comm/respond.rb +10 -5
  14. data/lib/slack/smart-bot/comm/send_msg_channel.rb +2 -2
  15. data/lib/slack/smart-bot/comm/send_msg_user.rb +4 -4
  16. data/lib/slack/smart-bot/comm/unreact.rb +21 -8
  17. data/lib/slack/smart-bot/commands.rb +3 -1
  18. data/lib/slack/smart-bot/commands/general/bot_help.rb +16 -3
  19. data/lib/slack/smart-bot/commands/general/bot_stats.rb +313 -0
  20. data/lib/slack/smart-bot/commands/general/bot_status.rb +1 -1
  21. data/lib/slack/smart-bot/commands/general/bye_bot.rb +1 -1
  22. data/lib/slack/smart-bot/commands/general/hi_bot.rb +1 -1
  23. data/lib/slack/smart-bot/commands/general/use_rules.rb +2 -6
  24. data/lib/slack/smart-bot/commands/general/whats_new.rb +19 -0
  25. data/lib/slack/smart-bot/commands/on_bot/add_shortcut.rb +65 -33
  26. data/lib/slack/smart-bot/commands/on_bot/admin/extend_rules.rb +3 -7
  27. data/lib/slack/smart-bot/commands/on_bot/admin/pause_bot.rb +1 -0
  28. data/lib/slack/smart-bot/commands/on_bot/admin/see_routines.rb +8 -2
  29. data/lib/slack/smart-bot/commands/on_bot/admin/start_bot.rb +1 -0
  30. data/lib/slack/smart-bot/commands/on_bot/delete_repl.rb +1 -1
  31. data/lib/slack/smart-bot/commands/on_bot/delete_shortcut.rb +52 -21
  32. data/lib/slack/smart-bot/commands/on_bot/get_repl.rb +5 -5
  33. data/lib/slack/smart-bot/commands/on_bot/repl.rb +50 -18
  34. data/lib/slack/smart-bot/commands/on_bot/ruby_code.rb +34 -9
  35. data/lib/slack/smart-bot/commands/on_bot/run_repl.rb +2 -3
  36. data/lib/slack/smart-bot/commands/on_bot/see_repls.rb +1 -1
  37. data/lib/slack/smart-bot/commands/on_bot/see_shortcuts.rb +27 -9
  38. data/lib/slack/smart-bot/commands/on_extended/bot_rules.rb +14 -1
  39. data/lib/slack/smart-bot/commands/on_master/admin_master/exit_bot.rb +3 -3
  40. data/lib/slack/smart-bot/commands/on_master/admin_master/notify_message.rb +1 -1
  41. data/lib/slack/smart-bot/commands/on_master/admin_master/set_maintenance.rb +41 -0
  42. data/lib/slack/smart-bot/commands/on_master/create_bot.rb +4 -8
  43. data/lib/slack/smart-bot/listen.rb +6 -5
  44. data/lib/slack/smart-bot/process.rb +227 -188
  45. data/lib/slack/smart-bot/process_first.rb +104 -87
  46. data/lib/slack/smart-bot/treat_message.rb +98 -38
  47. data/lib/slack/smart-bot/utils.rb +2 -0
  48. data/lib/slack/smart-bot/utils/answer.rb +18 -0
  49. data/lib/slack/smart-bot/utils/answer_delete.rb +15 -0
  50. data/lib/slack/smart-bot/utils/build_help.rb +57 -5
  51. data/lib/slack/smart-bot/utils/create_routine_thread.rb +11 -2
  52. data/lib/slack/smart-bot/utils/get_channels_name_and_id.rb +1 -7
  53. data/lib/slack/smart-bot/utils/get_help.rb +79 -17
  54. data/lib/slack/smart-bot/utils/save_stats.rb +21 -8
  55. data/lib/slack/smart-bot/utils/update_shortcuts_file.rb +6 -0
  56. data/whats_new.txt +18 -0
  57. metadata +21 -12
  58. data/lib/slack/smart-bot/commands/on_bot/admin_master/bot_stats.rb +0 -195
@@ -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
- command2 = $2
84
- if text.match?(/^()\^\s*(.+)/im)
85
- add_double_excl = true
86
- addexcl = false
87
- if command2.match?(/^![^!]/) or command2.match?(/^\^/)
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
- elsif command2.match?(/^!!/)
89
+ elsif command2.match?(/^!!/)
90
90
  command2[0]=''
91
91
  command2[1]=''
92
- end
93
- else
92
+ end
93
+ else
94
94
  add_double_excl = false
95
95
  addexcl = true
96
- end
97
- command = command2
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
- (@shortcuts.keys.include?(:all) and @shortcuts[:all].keys.include?(command)) or
130
- (@shortcuts.keys.include?(nick) and @shortcuts[nick].keys.include?(command))
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
- if @status == :on and
191
- (@questions.key?(nick) or
192
- (@repl_sessions.key?(nick) and dest==@repl_sessions[nick][:dest] and
193
- ((@repl_sessions[nick][:on_thread] and thread_ts == @repl_sessions[nick][:thread_ts]) or
194
- (!@repl_sessions[nick][:on_thread] and !Thread.current[:on_thread] ))) or
195
- (@listening.key?(nick) and typem != :on_extended and
196
- ((@listening[nick].key?(dest) and !Thread.current[:on_thread]) or
197
- (@listening[nick].key?(thread_ts) and Thread.current[:on_thread] ) )) or
198
- dest[0] == "D" or on_demand)
199
- @logger.info "command: #{nick}> #{command}" unless processed
200
- #todo: verify this
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
- if dest[0] == "C" or dest[0] == "G" or (dest[0] == "D" and typem == :on_call)
203
- if typem != :on_call and @rules_imported.key?(user.id) and @rules_imported[user.id].key?(dchannel)
204
- if @bots_created.key?(@rules_imported[user.id][dchannel])
205
- if @bots_created[@rules_imported[user.id][dchannel]][:status] != :on
206
- respond "The bot on that channel is not :on", dest
207
- rules_file = ""
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
- end
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) and !['.','..'].include?(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 imported RULES FILE: #{rules_file}"
231
+ @logger.fatal "ERROR ON RULES FILE: #{rules_file}"
239
232
  @logger.fatal stack
240
233
  end
241
- else
242
- respond "The bot on <##{@rules_imported[user.id][user.id]}|#{@bots_created[@rules_imported[user.id][user.id]][:channel_name]}> is not :on", dest
243
- rules_file = ""
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
- unless rules_file.empty?
248
- if defined?(rules)
249
- command[0] = "" if command[0] == "!"
250
- command.gsub!(/^@\w+:*\s*/, "")
251
- if method(:rules).parameters.size == 4
252
- rules(user, command, processed, dest)
253
- elsif method(:rules).parameters.size == 5
254
- rules(user, command, processed, dest, files)
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(user, command, processed, dest, files, rules_file)
275
+ @logger.warn "It seems like rules method is not defined"
257
276
  end
258
- else
259
- @logger.warn "It seems like rules method is not defined"
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
- if processed and @listening.key?(nick)
273
- if Thread.current[:on_thread] and @listening[nick].key?(Thread.current[:thread_ts])
274
- @listening[nick][Thread.current[:thread_ts]] = Time.now
275
- elsif !Thread.current[:on_thread] and @listening[nick].key?(dest)
276
- @listening[nick][dest] = Time.now
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,42 +4,52 @@ 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
- data.text = ''
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
- data.text += el.text
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
- data.text += el.url
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 &nbsp; (asc char 160) into blank space
34
39
  end
40
+ data.text.gsub!('‘', "'")
35
41
  data.text.gsub!('’', "'")
36
- data.text.gsub!('“', '"')
37
- rescue
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
55
  if data.key?(:dest) and data.dest.to_s!='' # for run routines and publish on different channels
@@ -58,14 +68,22 @@ class SlackSmartBot
58
68
  @pings << $1
59
69
  end
60
70
  typem = :dont_treat
61
- if !dest.nil? and !data.text.nil? and !data.text.to_s.match?(/^\s*$/)
62
- if data.text.match(/^<@#{config[:nick_id]}>\s(on\s)?<#(\w+)\|([^>]+)>\s*:?\s*(.*)/im)
63
- channel_rules = $2
64
- channel_rules_name = $3
65
- # to be treated only on the bot of the requested channel
66
- if @channel_id == channel_rules
67
- data.text = $4
68
- typem = :on_call
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
69
87
  end
70
88
  elsif data.channel == @master_bot_id
71
89
  if config.on_master_bot #only to be treated on master bot channel
@@ -118,20 +136,27 @@ class SlackSmartBot
118
136
  end
119
137
  begin
120
138
  #todo: when changed @questions user_id then move user_info inside the ifs to avoid calling it when not necessary
121
- user_info = client.web_client.users_info(user: data.user)
139
+ user_info = get_user_info(data.user)
140
+
122
141
  #user_info.user.id = data.user #todo: remove this line when slack issue with Wxxxx Uxxxx fixed
123
142
  data.user = user_info.user.id #todo: remove this line when slack issue with Wxxxx Uxxxx fixed
124
- if @questions.key?(user_info.user.name)
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?
125
149
  if data.text.match?(/^\s*(Bye|Bæ|Good\sBye|Adiós|Ciao|Bless|Bless\sBless|Adeu)\s(#{@salutations.join("|")})\s*$/i)
126
- @questions.delete(user_info.user.name)
150
+ answer_delete(user_info.user.name, qdest)
127
151
  command = data.text
128
152
  else
129
- command = @questions[user_info.user.name]
130
- @questions[user_info.user.name] = data.text
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
131
156
  end
132
157
  elsif @repl_sessions.key?(user_info.user.name) and data.channel==@repl_sessions[user_info.user.name][:dest] and
133
158
  ((@repl_sessions[user_info.user.name][:on_thread] and data.thread_ts == @repl_sessions[user_info.user.name][:thread_ts]) or
134
- (!@repl_sessions[user_info.user.name][:on_thread] and data.thread_ts.to_s == '' ))
159
+ (!@repl_sessions[user_info.user.name][:on_thread] and data.thread_ts.to_s == '' ))
135
160
 
136
161
  if data.text.match(/^\s*```(.*)```\s*$/im)
137
162
  @repl_sessions[user_info.user.name][:command] = $1
@@ -144,16 +169,16 @@ class SlackSmartBot
144
169
  end
145
170
 
146
171
  #when added special characters on the message
147
- if command.match(/^\s*```(.*)```\s*$/im)
172
+ if command.match(/\A\s*```(.*)```\s*\z/im)
148
173
  command = $1
149
174
  elsif command.size >= 2 and
150
- ((command[0] == "`" and command[-1] == "`") or (command[0] == "*" and command[-1] == "*") or (command[0] == "_" and command[-1] == "_"))
175
+ ((command[0] == "`" and command[-1] == "`") or (command[0] == "*" and command[-1] == "*") or (command[0] == "_" and command[-1] == "_"))
151
176
  command = command[1..-2]
152
177
  end
153
178
 
154
179
  #ruby file attached
155
180
  if !data.files.nil? and data.files.size == 1 and
156
- (command.match?(/^(ruby|code)\s*$/) or (command.match?(/^\s*$/) and data.files[0].filetype == "ruby") or
181
+ (command.match?(/^(ruby|code)\s*$/) or (command.match?(/^\s*$/) and data.files[0].filetype == "ruby") or
157
182
  (typem == :on_call and data.files[0].filetype == "ruby"))
158
183
  res = Faraday.new("https://files.slack.com", headers: { "Authorization" => "Bearer #{config[:token]}" }).get(data.files[0].url_private)
159
184
  command += " ruby" if command != "ruby"
@@ -164,13 +189,9 @@ class SlackSmartBot
164
189
  command = "!" + command unless command[0] == "!" or command.match?(/^\s*$/) or command[0] == "^"
165
190
 
166
191
  #todo: add pagination for case more than 1000 channels on the workspace
167
- channels = client.web_client.conversations_list(
168
- types: "private_channel,public_channel",
169
- limit: "1000",
170
- exclude_archived: "true",
171
- ).channels
192
+ channels = get_channels()
172
193
  channel_found = channels.detect { |c| c.name == channel_rules_name }
173
- members = client.web_client.conversations_members(channel: @channels_id[channel_rules_name]).members unless channel_found.nil?
194
+ members = get_channel_members(@channels_id[channel_rules_name]) unless channel_found.nil?
174
195
  if channel_found.nil?
175
196
  @logger.fatal "Not possible to find the channel #{channel_rules_name}"
176
197
  elsif channel_found.name == config.master_channel
@@ -178,21 +199,21 @@ class SlackSmartBot
178
199
  elsif @status != :on
179
200
  respond "The bot in that channel is not :on", data.channel
180
201
  elsif data.user == channel_found.creator or members.include?(data.user)
181
- 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)
182
203
  else
183
204
  respond "You need to join the channel <##{channel_found.id}> to be able to use the rules.", data.channel
184
205
  end
185
206
  elsif config.on_master_bot and typem == :on_extended and
186
207
  command.size > 0 and command[0] != "-"
187
208
  # to run ruby only from the master bot for the case more than one extended
188
- 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)
189
210
  elsif !config.on_master_bot and @bots_created[@channel_id].key?(:extended) and
190
211
  @bots_created[@channel_id][:extended].include?(@channels_name[data.channel]) and
191
212
  command.size > 0 and command[0] != "-"
192
- 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)
193
214
  elsif (dest[0] == "D" or @channel_id == data.channel or data.user == config[:nick_id]) and
194
215
  command.size > 0 and command[0] != "-"
195
- 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)
196
217
  # if @botname on #channel_rules: do something
197
218
  end
198
219
  rescue Exception => stack
@@ -205,6 +226,29 @@ class SlackSmartBot
205
226
  elsif !config.on_master_bot and !dest.nil? and data.user == config[:nick_id] and dest == @master_bot_id
206
227
  # to treat on other bots the status messages populated on master bot
207
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
+
208
252
  when /^Bot has been (closed|killed) by/i
209
253
  sleep 2
210
254
  get_bots_created()
@@ -217,6 +261,22 @@ class SlackSmartBot
217
261
  when /removed the access to the rules of (.+) from (.+)\.$/i
218
262
  sleep 2
219
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
220
280
  end
221
281
  end
222
282
  end