slack-smart-bot 1.8.1 → 1.10.0

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 (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