slack-smart-bot 1.8.1 → 1.10.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (92) hide show
  1. checksums.yaml +4 -4
  2. data/README.md +127 -21
  3. data/lib/slack/smart-bot/comm/ask.rb +55 -42
  4. data/lib/slack/smart-bot/comm/dont_understand.rb +2 -2
  5. data/lib/slack/smart-bot/comm/event_hello.rb +34 -0
  6. data/lib/slack/smart-bot/comm/get_channel_members.rb +13 -0
  7. data/lib/slack/smart-bot/comm/get_channels.rb +35 -0
  8. data/lib/slack/smart-bot/comm/get_user_info.rb +20 -0
  9. data/lib/slack/smart-bot/comm/get_users.rb +24 -0
  10. data/lib/slack/smart-bot/comm/react.rb +38 -8
  11. data/lib/slack/smart-bot/comm/respond.rb +219 -48
  12. data/lib/slack/smart-bot/comm/respond_direct.rb +2 -3
  13. data/lib/slack/smart-bot/comm/respond_thread.rb +5 -0
  14. data/lib/slack/smart-bot/comm/send_file.rb +38 -34
  15. data/lib/slack/smart-bot/comm/send_msg_channel.rb +27 -22
  16. data/lib/slack/smart-bot/comm/send_msg_user.rb +58 -33
  17. data/lib/slack/smart-bot/comm/unreact.rb +24 -7
  18. data/lib/slack/smart-bot/comm.rb +7 -1
  19. data/lib/slack/smart-bot/commands/general/add_announcement.rb +32 -0
  20. data/lib/slack/smart-bot/commands/general/bot_help.rb +68 -28
  21. data/lib/slack/smart-bot/commands/general/bot_stats.rb +314 -0
  22. data/lib/slack/smart-bot/commands/general/bot_status.rb +3 -5
  23. data/lib/slack/smart-bot/commands/general/bye_bot.rb +0 -7
  24. data/lib/slack/smart-bot/commands/general/delete_announcement.rb +34 -0
  25. data/lib/slack/smart-bot/commands/general/delete_share.rb +34 -0
  26. data/lib/slack/smart-bot/commands/general/hi_bot.rb +16 -11
  27. data/lib/slack/smart-bot/commands/general/leaderboard.rb +200 -0
  28. data/lib/slack/smart-bot/commands/general/see_announcements.rb +113 -0
  29. data/lib/slack/smart-bot/commands/general/see_favorite_commands.rb +54 -0
  30. data/lib/slack/smart-bot/commands/general/see_shares.rb +41 -0
  31. data/lib/slack/smart-bot/commands/general/see_statuses.rb +78 -0
  32. data/lib/slack/smart-bot/commands/general/share_messages.rb +58 -0
  33. data/lib/slack/smart-bot/commands/general/stop_using_rules.rb +11 -6
  34. data/lib/slack/smart-bot/commands/general/suggest_command.rb +30 -0
  35. data/lib/slack/smart-bot/commands/general/use_rules.rb +13 -16
  36. data/lib/slack/smart-bot/commands/general/whats_new.rb +19 -0
  37. data/lib/slack/smart-bot/commands/general_bot_commands.rb +243 -0
  38. data/lib/slack/smart-bot/commands/on_bot/add_shortcut.rb +67 -38
  39. data/lib/slack/smart-bot/commands/on_bot/admin/add_routine.rb +49 -14
  40. data/lib/slack/smart-bot/commands/on_bot/admin/extend_rules.rb +5 -7
  41. data/lib/slack/smart-bot/commands/on_bot/admin/pause_bot.rb +4 -1
  42. data/lib/slack/smart-bot/commands/on_bot/admin/pause_routine.rb +1 -0
  43. data/lib/slack/smart-bot/commands/on_bot/admin/remove_routine.rb +2 -3
  44. data/lib/slack/smart-bot/commands/on_bot/admin/run_routine.rb +6 -1
  45. data/lib/slack/smart-bot/commands/on_bot/admin/see_result_routine.rb +32 -0
  46. data/lib/slack/smart-bot/commands/on_bot/admin/see_routines.rb +12 -4
  47. data/lib/slack/smart-bot/commands/on_bot/admin/start_bot.rb +4 -1
  48. data/lib/slack/smart-bot/commands/on_bot/admin/start_routine.rb +1 -0
  49. data/lib/slack/smart-bot/commands/on_bot/admin/stop_using_rules_on.rb +2 -0
  50. data/lib/slack/smart-bot/commands/on_bot/admin_master/react_to.rb +32 -0
  51. data/lib/slack/smart-bot/commands/on_bot/admin_master/send_message.rb +24 -0
  52. data/lib/slack/smart-bot/commands/on_bot/delete_repl.rb +3 -5
  53. data/lib/slack/smart-bot/commands/on_bot/delete_shortcut.rb +54 -25
  54. data/lib/slack/smart-bot/commands/on_bot/get_repl.rb +7 -9
  55. data/lib/slack/smart-bot/commands/on_bot/repl.rb +55 -25
  56. data/lib/slack/smart-bot/commands/on_bot/ruby_code.rb +36 -13
  57. data/lib/slack/smart-bot/commands/on_bot/run_repl.rb +5 -7
  58. data/lib/slack/smart-bot/commands/on_bot/see_repls.rb +4 -6
  59. data/lib/slack/smart-bot/commands/on_bot/see_shortcuts.rb +29 -13
  60. data/lib/slack/smart-bot/commands/on_extended/bot_rules.rb +55 -9
  61. data/lib/slack/smart-bot/commands/on_master/admin/kill_bot_on_channel.rb +4 -1
  62. data/lib/slack/smart-bot/commands/on_master/admin_master/exit_bot.rb +5 -3
  63. data/lib/slack/smart-bot/commands/on_master/admin_master/notify_message.rb +2 -1
  64. data/lib/slack/smart-bot/commands/on_master/admin_master/publish_announcements.rb +32 -0
  65. data/lib/slack/smart-bot/commands/on_master/admin_master/set_general_message.rb +38 -0
  66. data/lib/slack/smart-bot/commands/on_master/admin_master/set_maintenance.rb +49 -0
  67. data/lib/slack/smart-bot/commands/on_master/create_bot.rb +30 -21
  68. data/lib/slack/smart-bot/commands.rb +19 -1
  69. data/lib/slack/smart-bot/listen.rb +7 -8
  70. data/lib/slack/smart-bot/process.rb +373 -192
  71. data/lib/slack/smart-bot/process_first.rb +202 -104
  72. data/lib/slack/smart-bot/treat_message.rb +325 -186
  73. data/lib/slack/smart-bot/utils/answer.rb +18 -0
  74. data/lib/slack/smart-bot/utils/answer_delete.rb +15 -0
  75. data/lib/slack/smart-bot/utils/build_help.rb +57 -5
  76. data/lib/slack/smart-bot/utils/create_routine_thread.rb +83 -30
  77. data/lib/slack/smart-bot/utils/get_bots_created.rb +4 -1
  78. data/lib/slack/smart-bot/utils/get_channels_name_and_id.rb +1 -7
  79. data/lib/slack/smart-bot/utils/get_help.rb +87 -35
  80. data/lib/slack/smart-bot/utils/get_shares.rb +12 -0
  81. data/lib/slack/smart-bot/utils/has_access.rb +12 -0
  82. data/lib/slack/smart-bot/utils/save_stats.rb +23 -8
  83. data/lib/slack/smart-bot/utils/save_status.rb +52 -0
  84. data/lib/slack/smart-bot/utils/update_shortcuts_file.rb +6 -0
  85. data/lib/slack/smart-bot/utils.rb +5 -0
  86. data/lib/slack-smart-bot.rb +88 -47
  87. data/lib/slack-smart-bot_general_commands.rb +46 -0
  88. data/lib/slack-smart-bot_general_rules.rb +5 -2
  89. data/lib/slack-smart-bot_rules.rb +49 -23
  90. data/whats_new.txt +36 -0
  91. metadata +44 -13
  92. data/lib/slack/smart-bot/commands/on_bot/admin_master/bot_stats.rb +0 -195
@@ -1,27 +1,49 @@
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, routine_name, routine_type)
3
3
  nick = user.name
4
4
  rules_file = ""
5
5
  text.gsub!(/^!!/,'^') # to treat it just as ^
6
+ shared = []
7
+ if @shares.key?(@channels_name[dest]) and (ts.to_s!='' or config.simulate) and (user.id!=config.nick_id or (user.id == config.nick_id and !text.match?(/\A\*?Shares from channel/)))
8
+ @shares[@channels_name[dest]].each do |row|
9
+ if row[:user_deleted]==''
10
+ if ((row[:type] == 'text' and text.include?(row[:condition][1..-2])) or (row[:type]=='regexp' and text.match?(/#{row[:condition][1..-2]}/im))) and !shared.include?(row[:to_channel])
11
+ if config.simulate
12
+ link = text
13
+ else
14
+ link = client.web_client.chat_getPermalink(channel: dest, message_ts: ts).permalink
15
+ end
16
+ respond "*<#{link}|Shared> by <@#{row[:user_created]}> from <##{dest}>* using share id #{row[:share_id]}", row[:to_channel]
17
+ shared << row[:to_channel]
18
+ sleep 0.2
19
+ end
20
+ end
21
+ end
22
+ end
23
+
6
24
  if typem == :on_call
7
25
  rules_file = config.rules_file
8
26
  elsif dest[0] == "C" or dest[0] == "G" # on a channel or private channel
9
27
  rules_file = config.rules_file
10
28
 
11
- if @rules_imported.key?(user.id) and @rules_imported[user.id].key?(dchannel)
12
- unless @bots_created.key?(@rules_imported[user.id][dchannel])
29
+ if @rules_imported.key?(user.name) and @rules_imported[user.name].key?(dchannel)
30
+ unless @bots_created.key?(@rules_imported[user.name][dchannel])
13
31
  get_bots_created()
14
32
  end
15
- if @bots_created.key?(@rules_imported[user.id][dchannel])
16
- rules_file = @bots_created[@rules_imported[user.id][dchannel]][:rules_file]
33
+ if @bots_created.key?(@rules_imported[user.name][dchannel])
34
+ rules_file = @bots_created[@rules_imported[user.name][dchannel]][:rules_file]
17
35
  end
18
36
  end
19
- elsif dest[0] == "D" and @rules_imported.key?(user.id) and @rules_imported[user.id].key?(user.id) #direct message
20
- unless @bots_created.key?(@rules_imported[user.id][user.id])
37
+ elsif dest[0] == "D" and @rules_imported.key?(user.name) and @rules_imported[user.name].key?(user.name) #direct message
38
+ unless @bots_created.key?(@rules_imported[user.name][user.name])
21
39
  get_bots_created()
22
40
  end
23
- if @bots_created.key?(@rules_imported[user.id][user.id])
24
- rules_file = @bots_created[@rules_imported[user.id][user.id]][:rules_file]
41
+ if @bots_created.key?(@rules_imported[user.name][user.name])
42
+ rules_file = @bots_created[@rules_imported[user.name][user.name]][:rules_file]
43
+ end
44
+ elsif dest[0] == 'D' and (!@rules_imported.key?(user.name) or ( @rules_imported.key?(user.name) and !@rules_imported[user.name].key?(user.name)))
45
+ if File.exist?("#{config.path}/rules/general_rules.rb")
46
+ rules_file = "/rules/general_rules.rb"
25
47
  end
26
48
  end
27
49
 
@@ -80,21 +102,21 @@ class SlackSmartBot
80
102
  text.match(/^()\^\s*(.+)\s*/im) or
81
103
  text.match(/^()!\s*(.+)\s*/im) or
82
104
  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?(/^\^/)
105
+ command2 = $2
106
+ if text.match?(/^()\^\s*(.+)/im)
107
+ add_double_excl = true
108
+ addexcl = false
109
+ if command2.match?(/^![^!]/) or command2.match?(/^\^/)
88
110
  command2[0]=''
89
- elsif command2.match?(/^!!/)
111
+ elsif command2.match?(/^!!/)
90
112
  command2[0]=''
91
113
  command2[1]=''
92
- end
93
- else
114
+ end
115
+ else
94
116
  add_double_excl = false
95
117
  addexcl = true
96
- end
97
- command = command2
118
+ end
119
+ command = command2
98
120
  else
99
121
  addexcl = false
100
122
  if text.include?('$') #for shortcuts inside commands
@@ -111,6 +133,10 @@ class SlackSmartBot
111
133
  command.gsub!("$#{sc}", @shortcuts[nick][sc])
112
134
  elsif @shortcuts.key?(:all) and @shortcuts[:all].keys.include?(sc)
113
135
  command.gsub!("$#{sc}", @shortcuts[:all][sc])
136
+ elsif @shortcuts_global.key?(nick) and @shortcuts_global[nick].keys.include?(sc)
137
+ command.gsub!("$#{sc}", @shortcuts_global[nick][sc])
138
+ elsif @shortcuts_global.key?(:all) and @shortcuts_global[:all].keys.include?(sc)
139
+ command.gsub!("$#{sc}", @shortcuts_global[:all][sc])
114
140
  end
115
141
  end
116
142
  command.scan(/\$([^\s]+)/i).flatten.each do |sc|
@@ -119,6 +145,10 @@ class SlackSmartBot
119
145
  command.gsub!("$#{sc}", @shortcuts[nick][sc])
120
146
  elsif @shortcuts.key?(:all) and @shortcuts[:all].keys.include?(sc)
121
147
  command.gsub!("$#{sc}", @shortcuts[:all][sc])
148
+ elsif @shortcuts_global.key?(nick) and @shortcuts_global[nick].keys.include?(sc)
149
+ command.gsub!("$#{sc}", @shortcuts_global[nick][sc])
150
+ elsif @shortcuts_global.key?(:all) and @shortcuts_global[:all].keys.include?(sc)
151
+ command.gsub!("$#{sc}", @shortcuts_global[:all][sc])
122
152
  end
123
153
  end
124
154
  text = command
@@ -126,13 +156,19 @@ class SlackSmartBot
126
156
  text = "^" + text if add_double_excl
127
157
  end
128
158
  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))
159
+ (@shortcuts.keys.include?(:all) and @shortcuts[:all].keys.include?(command)) or
160
+ (@shortcuts.keys.include?(nick) and @shortcuts[nick].keys.include?(command)) or
161
+ (@shortcuts_global.keys.include?(:all) and @shortcuts_global[:all].keys.include?(command)) or
162
+ (@shortcuts_global.keys.include?(nick) and @shortcuts_global[nick].keys.include?(command))
131
163
  command = $2.downcase unless $2.nil?
132
164
  if @shortcuts.keys.include?(nick) and @shortcuts[nick].keys.include?(command)
133
165
  text = @shortcuts[nick][command].dup
134
166
  elsif @shortcuts.keys.include?(:all) and @shortcuts[:all].keys.include?(command)
135
167
  text = @shortcuts[:all][command].dup
168
+ elsif @shortcuts_global.keys.include?(nick) and @shortcuts_global[nick].keys.include?(command)
169
+ text = @shortcuts_global[nick][command].dup
170
+ elsif @shortcuts_global.keys.include?(:all) and @shortcuts_global[:all].keys.include?(command)
171
+ text = @shortcuts_global[:all][command].dup
136
172
  else
137
173
  respond "Shortcut not found", dest unless dest[0] == "C" and dchannel != dest #on extended channel
138
174
  return :next #jal
@@ -146,6 +182,9 @@ class SlackSmartBot
146
182
  begin
147
183
  t = Thread.new do
148
184
  begin
185
+ processed = false
186
+ processed_rules = false
187
+
149
188
  Thread.current[:dest] = dest
150
189
  Thread.current[:user] = user
151
190
  Thread.current[:command] = command
@@ -154,30 +193,37 @@ class SlackSmartBot
154
193
  Thread.current[:files?] = !files.nil? && files.size>0
155
194
  Thread.current[:ts] = ts
156
195
  Thread.current[:thread_ts] = thread_ts
196
+ Thread.current[:routine] = routine
197
+ Thread.current[:routine_name] = routine_name
198
+ Thread.current[:routine_type] = routine_type
199
+ Thread.current[:dchannel] = dchannel
157
200
  if thread_ts.to_s == ''
158
201
  Thread.current[:on_thread] = false
159
202
  Thread.current[:thread_ts] = Thread.current[:ts] # to create the thread if necessary
160
203
  else
161
204
  Thread.current[:on_thread] = true
162
205
  end
163
- if (dest[0] == "C") || (dest[0] == "G") and @rules_imported.key?(user.id) &&
164
- @rules_imported[user.id].key?(dchannel) && @bots_created.key?(@rules_imported[user.id][dchannel])
165
- Thread.current[:using_channel] = @rules_imported[user.id][dchannel]
166
- elsif dest[0] == "D" && @rules_imported.key?(user.id) && @rules_imported[user.id].key?(user.id) and
167
- @bots_created.key?(@rules_imported[user.id][user.id])
168
- Thread.current[:using_channel] = @rules_imported[user.id][user.id]
206
+ if (dest[0] == "C") || (dest[0] == "G") and @rules_imported.key?(user.name) &&
207
+ @rules_imported[user.name].key?(dchannel) && @bots_created.key?(@rules_imported[user.name][dchannel])
208
+ Thread.current[:using_channel] = @rules_imported[user.name][dchannel]
209
+ elsif dest[0] == "D" && @rules_imported.key?(user.name) && @rules_imported[user.name].key?(user.name) and
210
+ @bots_created.key?(@rules_imported[user.name][user.name])
211
+ Thread.current[:using_channel] = @rules_imported[user.name][user.name]
169
212
  else
170
213
  Thread.current[:using_channel] = ''
171
214
  end
172
-
173
- processed = process(user, command, dest, dchannel, rules_file, typem, files, Thread.current[:thread_ts])
215
+ if typem == :on_pub or typem == :on_pg
216
+ processed = false
217
+ else
218
+ processed = process(user, command, dest, dchannel, rules_file, typem, files, Thread.current[:thread_ts])
219
+ end
174
220
  @logger.info "command: #{nick}> #{command}" if processed
175
221
  on_demand = false
176
- if command.match(/^@?(#{config[:nick]}):*\s+(.+)/im) or
177
- command.match(/^()!!(.+)/im) or
178
- command.match(/^()\^(.+)/im) or
179
- command.match(/^()!(.+)/im) or
180
- command.match(/^()<@#{config[:nick_id]}>\s+(.+)/im)
222
+ if command.match(/\A@?(#{config[:nick]}):*\s+(.+)/im) or
223
+ command.match(/\A()!!(.+)/im) or
224
+ command.match(/\A()\^(.+)/im) or
225
+ command.match(/\A()!(.+)/im) or
226
+ command.match(/\A()<@#{config[:nick_id]}>\s+(.+)/im)
181
227
  command2 = $2
182
228
  Thread.current[:command] = command2
183
229
  if command2.match?(/^()!!(.+)/im) or
@@ -187,96 +233,148 @@ class SlackSmartBot
187
233
  command = command2
188
234
  on_demand = true
189
235
  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
236
+ unless config.on_maintenance or @status != :on
237
+ if typem == :on_pub or typem == :on_pg or typem == :on_extended
238
+ if command.match(/\A\s*(#{@salutations.join("|")})\s+(rules|help)\s*(.+)?$/i) or command.match(/\A(#{@salutations.join("|")}),? what can I do/i)
239
+ $2.to_s.match?(/rules/i) ? specific = true : specific = false
240
+ help_command = $3
241
+ if typem == :on_extended and specific
242
+ bot_rules(dest, help_command, typem, rules_file, user)
243
+ else
244
+ bot_help(user, user.name, dest, dchannel, specific, help_command, rules_file)
245
+ end
246
+ processed = true
247
+ end
248
+ end
249
+ processed = (processed || general_bot_commands(user, command, dest, files) )
250
+ processed = (processed || general_commands(user, command, dest, files) ) if defined?(general_commands)
251
+ @logger.info "command: #{nick}> #{command}" if processed
252
+ end
201
253
 
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 = ""
254
+ if !config.on_maintenance and !processed and typem != :on_pub and typem != :on_pg
255
+ if @status == :on and
256
+ (!answer.empty? or
257
+ (@repl_sessions.key?(nick) and dest==@repl_sessions[nick][:dest] and
258
+ ((@repl_sessions[nick][:on_thread] and thread_ts == @repl_sessions[nick][:thread_ts]) or
259
+ (!@repl_sessions[nick][:on_thread] and !Thread.current[:on_thread] ))) or
260
+ (@listening.key?(nick) and typem != :on_extended and
261
+ ((@listening[nick].key?(dest) and !Thread.current[:on_thread]) or
262
+ (@listening[nick].key?(thread_ts) and Thread.current[:on_thread] ) )) or
263
+ dest[0] == "D" or on_demand)
264
+ @logger.info "command: #{nick}> #{command}" unless processed
265
+ #todo: verify this
266
+
267
+ if dest[0] == "C" or dest[0] == "G" or (dest[0] == "D" and typem == :on_call)
268
+ if typem != :on_call and @rules_imported.key?(user.name) and @rules_imported[user.name].key?(dchannel)
269
+ if @bots_created.key?(@rules_imported[user.name][dchannel])
270
+ if @bots_created[@rules_imported[user.name][dchannel]][:status] != :on
271
+ respond "The bot on that channel is not :on", dest
272
+ rules_file = ""
273
+ end
208
274
  end
209
275
  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
276
+ unless rules_file.empty?
277
+ begin
278
+ eval(File.new(config.path+rules_file).read) if File.exist?(config.path+rules_file)
279
+ rescue Exception => stack
280
+ @logger.fatal "ERROR ON RULES FILE: #{rules_file}"
281
+ @logger.fatal stack
282
+ end
283
+ if defined?(rules)
284
+ command[0] = "" if command[0] == "!"
285
+ command.gsub!(/^@\w+:*\s*/, "")
286
+ if method(:rules).parameters.size == 4
287
+ processed_rules = rules(user, command, processed, dest)
288
+ elsif method(:rules).parameters.size == 5
289
+ processed_rules = rules(user, command, processed, dest, files)
290
+ else
291
+ processed_rules = rules(user, command, processed, dest, files, rules_file)
292
+ end
293
+ else
294
+ @logger.warn "It seems like rules method is not defined"
295
+ end
217
296
  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)
297
+ elsif @rules_imported.key?(user.name) and @rules_imported[user.name].key?(user.name)
298
+ if @bots_created.key?(@rules_imported[user.name][user.name])
299
+ if @bots_created[@rules_imported[user.name][user.name]][:status] == :on
300
+ begin
301
+ eval(File.new(config.path+rules_file).read) if File.exist?(config.path+rules_file) and !['.','..'].include?(config.path + rules_file)
302
+ rescue Exception => stack
303
+ @logger.fatal "ERROR ON imported RULES FILE: #{rules_file}"
304
+ @logger.fatal stack
305
+ end
225
306
  else
226
- rules(user, command, processed, dest, files, rules_file)
307
+ respond "The bot on <##{@rules_imported[user.name][user.name]}|#{@bots_created[@rules_imported[user.name][user.name]][:channel_name]}> is not :on", dest
308
+ rules_file = ""
227
309
  end
228
- else
229
- @logger.warn "It seems like rules method is not defined"
230
310
  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
235
- begin
236
- eval(File.new(config.path+rules_file).read) if File.exist?(config.path+rules_file) and !['.','..'].include?(config.path + rules_file)
237
- rescue Exception => stack
238
- @logger.fatal "ERROR ON imported RULES FILE: #{rules_file}"
239
- @logger.fatal stack
311
+
312
+ unless rules_file.empty?
313
+ if defined?(rules)
314
+ command[0] = "" if command[0] == "!"
315
+ command.gsub!(/^@\w+:*\s*/, "")
316
+ if method(:rules).parameters.size == 4
317
+ processed_rules = rules(user, command, processed, dest)
318
+ elsif method(:rules).parameters.size == 5
319
+ processed_rules = rules(user, command, processed, dest, files)
320
+ else
321
+ processed_rules = rules(user, command, processed, dest, files, rules_file)
322
+ end
323
+ else
324
+ @logger.warn "It seems like rules method is not defined"
240
325
  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 = ""
244
326
  end
245
- end
327
+ elsif dest[0] == 'D' and
328
+ (!@rules_imported.key?(user.name) or ( @rules_imported.key?(user.name) and !@rules_imported[user.name].key?(user.name))) and
329
+ rules_file.include?('general_rules.rb')
330
+ begin
331
+ eval(File.new(config.path+rules_file).read) if File.exist?(config.path+rules_file) and !['.','..'].include?(config.path + rules_file)
332
+ rescue Exception => stack
333
+ @logger.fatal "ERROR ON imported RULES FILE: #{rules_file}"
334
+ @logger.fatal stack
335
+ end
246
336
 
247
- unless rules_file.empty?
248
- if defined?(rules)
337
+ if defined?(general_rules)
249
338
  command[0] = "" if command[0] == "!"
250
339
  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)
340
+ #todo: check to change processed > processed_rules
341
+ if method(:general_rules).parameters.size == 4
342
+ processed = general_rules(user, command, processed, dest)
343
+ elsif method(:general_rules).parameters.size == 5
344
+ processed = general_rules(user, command, processed, dest, files)
255
345
  else
256
- rules(user, command, processed, dest, files, rules_file)
346
+ processed = general_rules(user, command, processed, dest, files, rules_file)
257
347
  end
258
348
  else
259
- @logger.warn "It seems like rules method is not defined"
349
+ @logger.warn "It seems like general_rules method is not defined"
350
+ end
351
+ unless processed
352
+ dont_understand('')
353
+ end
354
+ else
355
+ @logger.info "it is a direct message with no rules file selected so no rules file executed."
356
+ if command.match?(/^\s*bot\s+rules\s*(.*)$/i)
357
+ 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
358
+ end
359
+ unless processed
360
+ dont_understand('')
260
361
  end
261
362
  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
363
 
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
364
+ processed = (processed_rules || processed)
365
+
366
+ if processed and @listening.key?(nick)
367
+ if Thread.current[:on_thread] and @listening[nick].key?(Thread.current[:thread_ts])
368
+ @listening[nick][Thread.current[:thread_ts]] = Time.now
369
+ elsif !Thread.current[:on_thread] and @listening[nick].key?(dest)
370
+ @listening[nick][dest] = Time.now
371
+ end
277
372
  end
278
373
  end
279
-
374
+ end
375
+
376
+ if processed and config.general_message != '' and !routine
377
+ respond eval("\"" + config.general_message + "\"")
280
378
  end
281
379
  rescue Exception => stack
282
380
  @logger.fatal stack
@@ -1,222 +1,361 @@
1
1
  class SlackSmartBot
2
2
  def treat_message(data, remove_blocks = true)
3
-
3
+ @buffered = false if config[:testing]
4
4
  begin
5
- unless data.text.to_s.match(/\A\s*\z/)
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
- if remove_blocks and !data.blocks.nil? and data.blocks.size > 0
9
- data.blocks.each do |b|
10
- if b.type == 'rich_text'
11
- if b.elements.size > 0
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 = ''
16
- e.elements.each do |el|
17
- if el.type == 'text'
18
- data.text += el.text
19
- else
20
- data.text += el.url
5
+ begin
6
+ unless data.text.to_s.match(/\A\s*\z/)
7
+ #to remove italic, bold... from data.text since there is no method on slack api
8
+ if remove_blocks and !data.blocks.nil? and data.blocks.size > 0
9
+ data_text = ''
10
+ data.blocks.each do |b|
11
+ if b.type == 'rich_text'
12
+ if b.elements.size > 0
13
+ b.elements.each do |e|
14
+ if e.type == 'rich_text_section' or e.type == 'rich_text_preformatted'
15
+ if e.elements.size > 0 and (e.elements.type.uniq - ['link', 'text', 'user', 'channel']) == []
16
+ data_text += '```' if e.type == 'rich_text_preformatted'
17
+ e.elements.each do |el|
18
+ if el.type == 'text'
19
+ data_text += el.text
20
+ elsif el.type == 'user'
21
+ data_text += "<@#{el.user_id}>"
22
+ elsif el.type == 'channel'
23
+ tch = data.text.scan(/(<##{el.channel_id}\|[^\>]*>)/).join
24
+ data_text += tch
25
+ else
26
+ data_text += el.url
27
+ end
21
28
  end
29
+ data_text += '```' if e.type == 'rich_text_preformatted'
22
30
  end
23
31
  end
24
- break
25
32
  end
26
33
  end
27
34
  end
28
- break
29
35
  end
36
+ data.text = data_text unless data_text == ''
30
37
  end
38
+ data.text = CGI.unescapeHTML(data.text)
39
+ data.text.gsub!("\u00A0", " ") #to change &nbsp; (asc char 160) into blank space
31
40
  end
32
- data.text = CGI.unescapeHTML(data.text)
33
- data.text.gsub!("\u00A0", " ") #to change &nbsp; (asc char 160) into blank space
41
+ data.text.gsub!('‘', "'")
42
+ data.text.gsub!('’', "'")
43
+ data.text.gsub!('“', '"')
44
+ data.text.gsub!('”', '"')
45
+ rescue Exception => exc
46
+ @logger.warn "Impossible to unescape or clean format for data.text:#{data.text}"
47
+ @logger.warn exc.inspect
34
48
  end
35
- data.text.gsub!('’', "'")
36
- data.text.gsub!('“', '"')
37
- rescue
38
- @logger.warn "Impossible to unescape or clean format for data.text:#{data.text}"
39
- end
40
- if config[:testing] and config.on_master_bot
41
- open("#{config.path}/buffer.log", "a") { |f|
42
- f.puts "|#{data.channel}|#{data.user}|#{data.text}"
43
- }
44
- end
45
- if data.channel[0] == "D" or data.channel[0] == "C" or data.channel[0] == "G" #Direct message or Channel or Private Channel
46
- dest = data.channel
47
- else # not treated
48
- dest = nil
49
- end
50
- #todo: sometimes data.user is nil, check the problem.
51
- @logger.warn "!dest is nil. user: #{data.user}, channel: #{data.channel}, message: #{data.text}" if dest.nil?
52
- if !data.files.nil? and data.files.size == 1 and data.text.to_s == "" and data.files[0].filetype == "ruby"
53
- data.text = "ruby"
54
- end
55
- if !dest.nil? and config.on_master_bot and !data.text.nil? and data.text.match(/^ping from (.+)\s*$/) and data.user == config[:nick_id]
56
- @pings << $1
57
- end
58
- typem = :dont_treat
59
- if !dest.nil? and !data.text.nil? and !data.text.to_s.match?(/^\s*$/)
60
- if data.text.match(/^<@#{config[:nick_id]}>\s(on\s)?<#(\w+)\|([^>]+)>\s*:?\s*(.*)/im)
61
- channel_rules = $2
62
- channel_rules_name = $3
63
- # to be treated only on the bot of the requested channel
64
- if @channel_id == channel_rules
65
- data.text = $4
66
- typem = :on_call
67
- end
68
- elsif dest == @master_bot_id
69
- if config.on_master_bot #only to be treated on master bot channel
70
- typem = :on_master
49
+
50
+ unless data.key?(:routine)
51
+ data.routine = false
52
+ data.routine_name = ''
53
+ data.routine_type = ''
54
+ end
55
+ if config[:testing] and config.on_master_bot and !@buffered
56
+ @buffered = true
57
+ open("#{config.path}/buffer.log", "a") { |f|
58
+ f.puts "|#{data.channel}|#{data.user}|#{data.user_name}|#{data.text}"
59
+ }
60
+ end
61
+ if data.key?(:dest) and data.dest.to_s!='' # for run routines and publish on different channels
62
+ dest = data.dest
63
+ elsif data.channel[0] == "D" or data.channel[0] == "C" or data.channel[0] == "G" #Direct message or Channel or Private Channel
64
+ dest = data.channel
65
+ else # not treated
66
+ dest = nil
67
+ end
68
+ #todo: sometimes data.user is nil, check the problem.
69
+ @logger.warn "!dest is nil. user: #{data.user}, channel: #{data.channel}, message: #{data.text}" if dest.nil?
70
+ if !data.files.nil? and data.files.size == 1 and data.text.to_s == "" and data.files[0].filetype == "ruby"
71
+ data.text = "ruby"
72
+ end
73
+ if !dest.nil? and config.on_master_bot and !data.text.nil? and data.text.match(/^ping from (.+)\s*$/) and data.user == config[:nick_id]
74
+ @pings << $1
75
+ end
76
+ typem = :dont_treat
77
+ if data.nil? or data.user.nil? or data.user.to_s==''
78
+ user_info = nil
79
+ @users = get_users() if @users.empty?
80
+ else
81
+ #todo: when changed @questions user_id then move user_info inside the ifs to avoid calling it when not necessary
82
+ user_info = @users.select{|u| u.id == data.user or (u.key?(:enterprise_user) and u.enterprise_user.id == data.user)}[-1]
83
+ if user_info.nil? or user_info.empty?
84
+ @users = get_users()
85
+ user_info = @users.select{|u| u.id == data.user or (u.key?(:enterprise_user) and u.enterprise_user.id == data.user)}[-1]
71
86
  end
72
- elsif @bots_created.key?(dest)
73
- if @channel_id == dest #only to be treated by the bot on the channel
74
- typem = :on_bot
87
+ end
88
+ if !dest.nil? and !data.text.nil? and !data.text.to_s.match?(/\A\s*\z/)
89
+ if data.channel[0] == "D" and !data.text.to_s.match?(/^\s*<@#{config[:nick_id]}>\s+/) and
90
+ (data.text.to_s.match?(/^\s*(on)?\s*<#\w+\|[^>]*>/i) or data.text.to_s.match?(/^\s*(on)?\s*#\w+/i))
91
+ data.text = "<@#{config[:nick_id]}> " + data.text.to_s
75
92
  end
76
- elsif dest[0] == "D" #Direct message
77
- get_rules_imported()
78
- if @rules_imported.key?(data.user) && @rules_imported[data.user].key?(data.user) and
79
- @bots_created.key?(@rules_imported[data.user][data.user])
80
- if @channel_id == @rules_imported[data.user][data.user]
81
- #only to be treated by the channel we are 'using'
93
+ #todo: we need to add mixed channels: @smart-bot on private1 #bot1cm <#CXDDFRDDF|bot2cu>: echo A
94
+ if data.text.match(/\A\^\^+/) # to open a thread it will be only when starting by single ^
95
+ typem = :dont_treat
96
+ elsif data.text.match(/^\s*<@#{config[:nick_id]}>\s+(on\s+)?((<#\w+\|[^>]*>\s*)+)\s*:?\s*(.*)/im) or
97
+ data.text.match(/^\s*<@#{config[:nick_id]}>\s+(on\s+)?((#[a-zA-Z0-9\-\_]+\s*)+)\s*:?\s*(.*)/im) or
98
+ data.text.match(/^\s*<@#{config[:nick_id]}>\s+(on\s+)?(([a-zA-Z0-9\-\_]+\s*)+)\s*:\s*(.*)/im)
99
+ channels_rules = $2 #multiple channels @smart-bot on #channel1 #channel2 echo AAA
100
+ data_text = $4
101
+ channel_rules_name = ''
102
+ channel_rules = ''
103
+ channels_arr = channels_rules.scan(/<#(\w+)\|([^>]*)>/)
104
+ if channels_arr.size == 0
105
+ channels_arr = []
106
+ channels_rules.scan(/([^\s]+)/).each do |cn|
107
+ cna = cn.join.gsub('#','')
108
+ if @channels_name.key?(cna)
109
+ channels_arr << [cna, @channels_name[cna]]
110
+ else
111
+ channels_arr << [@channels_id[cna], cna]
112
+ end
113
+ end
114
+ else
115
+ channels_arr.each do |row|
116
+ row[0] = @channels_id[row[1]] if row[0] == ''
117
+ row[1] = @channels_name[row[0]] if row[1] == ''
118
+ end
119
+ end
120
+
121
+ # to be treated only on the bots of the requested channels
122
+ channels_arr.each do |tcid, tcname|
123
+ if @channel_id == tcid
124
+ data.text = data_text
125
+ typem = :on_call
126
+ channel_rules = tcid
127
+ channel_rules_name = tcname
128
+ break
129
+ elsif @bots_created.key?(@channel_id) and @bots_created[@channel_id][:extended].include?(tcname)
130
+ data.text = data_text
131
+ typem = :on_call
132
+ channel_rules = @channel_id
133
+ channel_rules_name = @channels_name[@channel_id]
134
+ break
135
+ end
136
+ end
137
+
138
+ elsif data.channel == @master_bot_id
139
+ if config.on_master_bot #only to be treated on master bot channel
140
+ typem = :on_master
141
+ end
142
+ elsif @bots_created.key?(data.channel)
143
+ if @channel_id == data.channel #only to be treated by the bot on the channel
144
+ typem = :on_bot
145
+ end
146
+ elsif data.channel[0] == "D" #Direct message
147
+ get_rules_imported()
148
+ if @rules_imported.key?(user_info.name) && @rules_imported[user_info.name].key?(user_info.name) and
149
+ @bots_created.key?(@rules_imported[user_info.name][user_info.name])
150
+ if @channel_id == @rules_imported[user_info.name][user_info.name]
151
+ #only to be treated by the channel we are 'using'
152
+ typem = :on_dm
153
+ end
154
+ elsif config.on_master_bot
155
+ #only to be treated by master bot
82
156
  typem = :on_dm
83
157
  end
84
- elsif config.on_master_bot
85
- #only to be treated by master bot
86
- typem = :on_dm
87
- end
88
- elsif dest[0] == "C" or dest[0] == "G"
89
- #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[dest]) and
91
- !data.text.match?(/^!?\s*(ruby|code)\s+/) and !data.text.match?(/^!?!?\s*(ruby|code)\s+/) and !data.text.match?(/^\^?\s*(ruby|code)\s+/)
92
- typem = :on_extended
93
- 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
- #or in case of running ruby, the master bot
158
+ elsif data.channel[0] == "C" or data.channel[0] == "G"
159
+ #only to be treated on the channel of the bot. excluding running ruby
160
+ if !config.on_master_bot and @bots_created.key?(@channel_id) and @bots_created[@channel_id][:extended].include?(@channels_name[data.channel]) and
161
+ !data.text.match?(/^!?\s*(ruby|code)\s+/) and !data.text.match?(/^!?!?\s*(ruby|code)\s+/) and !data.text.match?(/^\^?\s*(ruby|code)\s+/)
162
+ typem = :on_extended
163
+ 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+/) )
164
+ #or in case of running ruby, the master bot
165
+ @bots_created.each do |k, v|
166
+ if v.key?(:extended) and v[:extended].include?(@channels_name[data.channel])
167
+ typem = :on_extended
168
+ break
169
+ end
170
+ end
171
+ end
172
+ extended = false
95
173
  @bots_created.each do |k, v|
96
- if v.key?(:extended) and v[:extended].include?(@channels_name[dest])
97
- typem = :on_extended
174
+ if v.key?(:extended) and v[:extended].include?(@channels_name[data.channel])
175
+ extended = true
98
176
  break
99
177
  end
100
178
  end
101
- end
102
- if dest[0] == "G" and config.on_master_bot and typem != :on_extended #private group
103
- typem = :on_pg
179
+ if data.channel[0] == "G" and config.on_master_bot and !extended #private group
180
+ typem = :on_pg
181
+ elsif data.channel[0] == 'C' and config.on_master_bot and !extended #public group
182
+ typem = :on_pub
183
+ end
104
184
  end
105
185
  end
106
- end
107
- unless typem == :dont_treat
108
- if (Time.now - @last_activity_check) > 60 * 30 #every 30 minutes
109
- @last_activity_check = Time.now
110
- @listening.each do |k,v|
111
- v.each do |kk, vv|
112
- @listening[k].delete(kk) if (Time.now - vv) > 60 * 30
113
- end
114
- @listening.delete(k) if @listening[k].empty?
186
+ load "#{config.path}/rules/general_commands.rb" if File.exists?("#{config.path}/rules/general_commands.rb") and @datetime_general_commands != File.mtime("#{config.path}/rules/general_commands.rb")
187
+ unless typem == :dont_treat or user_info.nil?
188
+ if (Time.now - @last_activity_check) > 60 * 30 #every 30 minutes
189
+ @last_activity_check = Time.now
190
+ @listening.each do |k,v|
191
+ v.each do |kk, vv|
192
+ @listening[k].delete(kk) if (Time.now - vv) > 60 * 30
193
+ end
194
+ @listening.delete(k) if @listening[k].empty?
195
+ end
115
196
  end
116
- end
117
- begin
118
- #todo: when changed @questions user_id then move user_info inside the ifs to avoid calling it when not necessary
119
- user_info = client.web_client.users_info(user: data.user)
120
- #user_info.user.id = data.user #todo: remove this line when slack issue with Wxxxx Uxxxx fixed
121
- data.user = user_info.user.id #todo: remove this line when slack issue with Wxxxx Uxxxx fixed
122
- if @questions.key?(user_info.user.name)
123
- if data.text.match?(/^\s*(Bye|Bæ|Good\sBye|Adiós|Ciao|Bless|Bless\sBless|Adeu)\s(#{@salutations.join("|")})\s*$/i)
124
- @questions.delete(user_info.user.name)
125
- command = data.text
197
+ begin
198
+ #user_info.id = data.user #todo: remove this line when slack issue with Wxxxx Uxxxx fixed
199
+ data.user = user_info.id #todo: remove this line when slack issue with Wxxxx Uxxxx fixed
200
+ if data.thread_ts.nil?
201
+ qdest = dest
126
202
  else
127
- command = @questions[user_info.user.name]
128
- @questions[user_info.user.name] = data.text
203
+ qdest = data.thread_ts
204
+ end
205
+ if !answer(user_info.name, qdest).empty?
206
+ if data.text.match?(/\A\s*(Bye|Bæ|Good\sBye|Adiós|Ciao|Bless|Bless\sBless|Adeu)\s(#{@salutations.join("|")})\s*$/i)
207
+ answer_delete(user_info.name, qdest)
208
+ command = data.text
209
+ else
210
+ command = answer(user_info.name, qdest)
211
+ @answer[user_info.name][qdest] = data.text
212
+ @questions[user_info.name] = data.text # to be backwards compatible #todo remove it when 2.0
213
+ end
214
+ elsif @repl_sessions.key?(user_info.name) and data.channel==@repl_sessions[user_info.name][:dest] and
215
+ ((@repl_sessions[user_info.name][:on_thread] and data.thread_ts == @repl_sessions[user_info.name][:thread_ts]) or
216
+ (!@repl_sessions[user_info.name][:on_thread] and data.thread_ts.to_s == '' ))
217
+
218
+ if data.text.match(/^\s*```(.*)```\s*$/im)
219
+ @repl_sessions[user_info.name][:command] = $1
220
+ else
221
+ @repl_sessions[user_info.name][:command] = data.text
222
+ end
223
+ command = 'repl'
224
+ else
225
+ command = data.text
129
226
  end
130
- elsif @repl_sessions.key?(user_info.user.name) and dest==@repl_sessions[user_info.user.name][:dest] and
131
- ((@repl_sessions[user_info.user.name][:on_thread] and data.thread_ts == @repl_sessions[user_info.user.name][:thread_ts]) or
132
- (!@repl_sessions[user_info.user.name][:on_thread] and data.thread_ts.to_s == '' ))
133
-
134
- if data.text.match(/^\s*```(.*)```\s*$/im)
135
- @repl_sessions[user_info.user.name][:command] = $1
136
- else
137
- @repl_sessions[user_info.user.name][:command] = data.text
138
- end
139
- command = 'repl'
140
- else
141
- command = data.text
142
- end
143
227
 
144
- #when added special characters on the message
145
- if command.match(/^\s*```(.*)```\s*$/im)
146
- command = $1
147
- elsif command.size >= 2 and
148
- ((command[0] == "`" and command[-1] == "`") or (command[0] == "*" and command[-1] == "*") or (command[0] == "_" and command[-1] == "_"))
149
- command = command[1..-2]
150
- end
228
+ #when added special characters on the message
229
+ if command.match(/\A\s*```(.*)```\s*\z/im)
230
+ command = $1
231
+ elsif command.size >= 2 and
232
+ ((command[0] == "`" and command[-1] == "`") or (command[0] == "*" and command[-1] == "*") or (command[0] == "_" and command[-1] == "_"))
233
+ command = command[1..-2]
234
+ end
151
235
 
152
- #ruby file attached
153
- if !data.files.nil? and data.files.size == 1 and
154
- (command.match?(/^(ruby|code)\s*$/) or (command.match?(/^\s*$/) and data.files[0].filetype == "ruby") or
155
- (typem == :on_call and data.files[0].filetype == "ruby"))
156
- res = Faraday.new("https://files.slack.com", headers: { "Authorization" => "Bearer #{config[:token]}" }).get(data.files[0].url_private)
157
- command += " ruby" if command != "ruby"
158
- command = "#{command} #{res.body.to_s.force_encoding("UTF-8")}"
159
- end
236
+ #ruby file attached
237
+ if !data.files.nil? and data.files.size == 1 and
238
+ (command.match?(/^(ruby|code)\s*$/) or (command.match?(/^\s*$/) and data.files[0].filetype == "ruby") or
239
+ (typem == :on_call and data.files[0].filetype == "ruby"))
240
+ res = Faraday.new("https://files.slack.com", headers: { "Authorization" => "Bearer #{config[:token]}" }).get(data.files[0].url_private)
241
+ command += " ruby" if command != "ruby"
242
+ command = "#{command} #{res.body.to_s.force_encoding("UTF-8")}"
243
+ end
160
244
 
161
- if typem == :on_call
162
- command = "!" + command unless command[0] == "!" or command.match?(/^\s*$/) or command[0] == "^"
245
+ if typem == :on_call
246
+ command = "!" + command unless command[0] == "!" or command.match?(/^\s*$/) or command[0] == "^"
163
247
 
164
- #todo: add pagination for case more than 1000 channels on the workspace
165
- channels = client.web_client.conversations_list(
166
- types: "private_channel,public_channel",
167
- limit: "1000",
168
- exclude_archived: "true",
169
- ).channels
170
- channel_found = channels.detect { |c| c.name == channel_rules_name }
171
- members = client.web_client.conversations_members(channel: @channels_id[channel_rules_name]).members unless channel_found.nil?
172
- if channel_found.nil?
173
- @logger.fatal "Not possible to find the channel #{channel_rules_name}"
174
- elsif channel_found.name == config.master_channel
175
- respond "You cannot use the rules from Master Channel on any other channel.", dest
176
- elsif @status != :on
177
- respond "The bot in that channel is not :on", dest
178
- elsif data.user == channel_found.creator or members.include?(data.user)
179
- process_first(user_info.user, command, dest, channel_rules, typem, data.files, data.ts, data.thread_ts)
180
- else
181
- respond "You need to join the channel <##{channel_found.id}> to be able to use the rules.", dest
182
- end
183
- elsif config.on_master_bot and typem == :on_extended and
184
- command.size > 0 and command[0] != "-"
185
- # to run ruby only from the master bot for the case more than one extended
186
- process_first(user_info.user, command, dest, @channel_id, typem, data.files, data.ts, data.thread_ts)
187
- elsif !config.on_master_bot and @bots_created[@channel_id].key?(:extended) and
188
- @bots_created[@channel_id][:extended].include?(@channels_name[data.channel]) and
189
- command.size > 0 and command[0] != "-"
190
- process_first(user_info.user, command, dest, @channel_id, typem, data.files, data.ts, data.thread_ts)
191
- elsif (dest[0] == "D" or @channel_id == data.channel or data.user == config[:nick_id]) and
192
- command.size > 0 and command[0] != "-"
193
- process_first(user_info.user, command, dest, data.channel, typem, data.files, data.ts, data.thread_ts)
194
- # if @botname on #channel_rules: do something
248
+ #todo: add pagination for case more than 1000 channels on the workspace
249
+ channels = get_channels()
250
+ channel_found = channels.detect { |c| c.name == channel_rules_name }
251
+ members = get_channel_members(@channels_id[channel_rules_name]) unless channel_found.nil?
252
+ if channel_found.nil?
253
+ @logger.fatal "Not possible to find the channel #{channel_rules_name}"
254
+ elsif channel_found.name == config.master_channel
255
+ respond "You cannot use the rules from Master Channel on any other channel.", data.channel
256
+ elsif @status != :on
257
+ respond "The bot in that channel is not :on", data.channel
258
+ elsif data.user == channel_found.creator or members.include?(data.user)
259
+ process_first(user_info, command, dest, channel_rules, typem, data.files, data.ts, data.thread_ts, data.routine, data.routine_name, data.routine_type)
260
+ else
261
+ respond "You need to join the channel <##{channel_found.id}> to be able to use the rules.", data.channel
262
+ end
263
+ elsif config.on_master_bot and typem == :on_extended and
264
+ command.size > 0 and command[0] != "-"
265
+ # to run ruby only from the master bot for the case more than one extended
266
+ process_first(user_info, command, dest, @channel_id, typem, data.files, data.ts, data.thread_ts, data.routine, data.routine_name, data.routine_type)
267
+ elsif !config.on_master_bot and @bots_created[@channel_id].key?(:extended) and
268
+ @bots_created[@channel_id][:extended].include?(@channels_name[data.channel]) and
269
+ command.size > 0 and command[0] != "-"
270
+ process_first(user_info, command, dest, @channel_id, typem, data.files, data.ts, data.thread_ts, data.routine, data.routine_name, data.routine_type)
271
+ elsif (dest[0] == "D" or @channel_id == data.channel or data.user == config[:nick_id]) and
272
+ command.size > 0 and command[0] != "-"
273
+ process_first(user_info, command, dest, data.channel, typem, data.files, data.ts, data.thread_ts, data.routine, data.routine_name, data.routine_type)
274
+ # if @botname on #channel_rules: do something
275
+ elsif typem == :on_pub or typem == :on_pg
276
+ process_first(user_info, command, dest, channel_rules, typem, data.files, data.ts, data.thread_ts, data.routine, data.routine_name, data.routine_type)
277
+ end
278
+ rescue Exception => stack
279
+ @logger.fatal stack
195
280
  end
196
- rescue Exception => stack
197
- @logger.fatal stack
198
- end
199
- else
200
- if !config.on_master_bot and !dest.nil? and (dest == @master_bot_id or dest[0] == "D") and
201
- data.text.match?(/^\s*bot\s+status\s*$/i) and @admin_users_id.include?(data.user)
202
- respond "ping from #{config.channel}", dest
203
- elsif !config.on_master_bot and !dest.nil? and data.user == config[:nick_id] and dest == @master_bot_id
204
- # to treat on other bots the status messages populated on master bot
205
- case data.text
206
- when /^Bot has been (closed|killed) by/i
207
- sleep 2
208
- get_bots_created()
209
- when /^Changed status on (.+) to :(.+)/i
210
- sleep 2
211
- get_bots_created()
212
- when /extended the rules from (.+) to be used on (.+)\.$/i
213
- sleep 2
214
- get_bots_created()
215
- when /removed the access to the rules of (.+) from (.+)\.$/i
216
- sleep 2
217
- get_bots_created()
281
+
282
+ else
283
+ @logger.warn "Pay attention there is no user on users with id #{data.user}" if user_info.nil?
284
+ if !config.on_master_bot and !dest.nil? and (data.channel == @master_bot_id or dest[0] == "D") and
285
+ data.text.match?(/^\s*(!|!!|\^)?\s*bot\s+status\s*$/i) and @admin_users_id.include?(data.user)
286
+ respond "ping from #{config.channel}", dest
287
+ elsif !config.on_master_bot and !dest.nil? and data.user == config[:nick_id] and dest == @master_bot_id
288
+ # to treat on other bots the status messages populated on master bot
289
+ case data.text
290
+ when /General message has been set\./i, /General message won't be displayed anymore./i
291
+ sleep 2
292
+ if File.exist?("#{config.path}/config_tmp.status")
293
+ file_cts = IO.readlines("#{config.path}/config_tmp.status").join
294
+ unless file_cts.to_s() == ""
295
+ file_cts = eval(file_cts)
296
+ if file_cts.is_a?(Hash) and file_cts.key?(:general_message)
297
+ config.general_message = file_cts.general_message
298
+ end
299
+ end
300
+ end
301
+ when /From now on I'll be on maintenance status/i
302
+ sleep 2
303
+ if File.exist?("#{config.path}/config_tmp.status")
304
+ file_cts = IO.readlines("#{config.path}/config_tmp.status").join
305
+ unless file_cts.to_s() == ""
306
+ file_cts = eval(file_cts)
307
+ if file_cts.is_a?(Hash) and file_cts.key?(:on_maintenance)
308
+ config.on_maintenance = file_cts.on_maintenance
309
+ config.on_maintenance_message = file_cts.on_maintenance_message
310
+ end
311
+ end
312
+ end
313
+ when /From now on I won't be on maintenance/i
314
+ sleep 2
315
+ if File.exist?("#{config.path}/config_tmp.status")
316
+ file_cts = IO.readlines("#{config.path}/config_tmp.status").join
317
+ unless file_cts.to_s() == ""
318
+ file_cts = eval(file_cts)
319
+ if file_cts.is_a?(Hash) and file_cts.key?(:on_maintenance)
320
+ config.on_maintenance = file_cts.on_maintenance
321
+ config.on_maintenance_message = file_cts.on_maintenance_message
322
+ end
323
+ end
324
+ end
325
+
326
+ when /^Bot has been (closed|killed) by/i
327
+ sleep 2
328
+ get_bots_created()
329
+ when /^Changed status on (.+) to :(.+)/i
330
+ sleep 2
331
+ get_bots_created()
332
+ when /extended the rules from (.+) to be used on (.+)\.$/i
333
+ sleep 2
334
+ get_bots_created()
335
+ when /removed the access to the rules of (.+) from (.+)\.$/i
336
+ sleep 2
337
+ get_bots_created()
338
+ when /global shortcut added/
339
+ sleep 2
340
+ if File.exist?("#{config.path}/shortcuts/shortcuts_global.rb")
341
+ file_sc = IO.readlines("#{config.path}/shortcuts/shortcuts_global.rb").join
342
+ unless file_sc.to_s() == ""
343
+ @shortcuts_global = eval(file_sc)
344
+ end
345
+ end
346
+ when /global shortcut deleted/
347
+ sleep 2
348
+ if File.exist?("#{config.path}/shortcuts/shortcuts_global.rb")
349
+ file_sc = IO.readlines("#{config.path}/shortcuts/shortcuts_global.rb").join
350
+ unless file_sc.to_s() == ""
351
+ @shortcuts_global = eval(file_sc)
352
+ end
353
+ end
354
+ end
218
355
  end
219
356
  end
357
+ rescue Exception => stack
358
+ @logger.fatal stack
220
359
  end
221
360
  end
222
361
  end