slack-smart-bot 1.9.2 → 1.10.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (86) hide show
  1. checksums.yaml +4 -4
  2. data/README.md +109 -11
  3. data/lib/slack/smart-bot/comm/ask.rb +55 -49
  4. data/lib/slack/smart-bot/comm/dont_understand.rb +1 -1
  5. data/lib/slack/smart-bot/comm/event_hello.rb +7 -3
  6. data/lib/slack/smart-bot/comm/get_channel_members.rb +9 -4
  7. data/lib/slack/smart-bot/comm/get_channels.rb +31 -16
  8. data/lib/slack/smart-bot/comm/get_user_info.rb +12 -8
  9. data/lib/slack/smart-bot/comm/get_users.rb +24 -0
  10. data/lib/slack/smart-bot/comm/react.rb +19 -2
  11. data/lib/slack/smart-bot/comm/respond.rb +217 -72
  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 +22 -18
  18. data/lib/slack/smart-bot/comm.rb +2 -0
  19. data/lib/slack/smart-bot/commands/general/add_announcement.rb +32 -0
  20. data/lib/slack/smart-bot/commands/general/bot_help.rb +59 -32
  21. data/lib/slack/smart-bot/commands/general/bot_stats.rb +10 -9
  22. data/lib/slack/smart-bot/commands/general/bot_status.rb +2 -4
  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 +7 -7
  36. data/lib/slack/smart-bot/commands/general_bot_commands.rb +243 -0
  37. data/lib/slack/smart-bot/commands/on_bot/add_shortcut.rb +2 -5
  38. data/lib/slack/smart-bot/commands/on_bot/admin/add_routine.rb +32 -11
  39. data/lib/slack/smart-bot/commands/on_bot/admin/extend_rules.rb +2 -0
  40. data/lib/slack/smart-bot/commands/on_bot/admin/pause_bot.rb +4 -2
  41. data/lib/slack/smart-bot/commands/on_bot/admin/pause_routine.rb +1 -0
  42. data/lib/slack/smart-bot/commands/on_bot/admin/remove_routine.rb +2 -3
  43. data/lib/slack/smart-bot/commands/on_bot/admin/run_routine.rb +6 -1
  44. data/lib/slack/smart-bot/commands/on_bot/admin/see_result_routine.rb +32 -0
  45. data/lib/slack/smart-bot/commands/on_bot/admin/see_routines.rb +4 -2
  46. data/lib/slack/smart-bot/commands/on_bot/admin/start_bot.rb +4 -2
  47. data/lib/slack/smart-bot/commands/on_bot/admin/start_routine.rb +1 -0
  48. data/lib/slack/smart-bot/commands/on_bot/admin/stop_using_rules_on.rb +2 -0
  49. data/lib/slack/smart-bot/commands/on_bot/admin_master/react_to.rb +32 -0
  50. data/lib/slack/smart-bot/commands/on_bot/admin_master/send_message.rb +24 -0
  51. data/lib/slack/smart-bot/commands/on_bot/delete_repl.rb +2 -4
  52. data/lib/slack/smart-bot/commands/on_bot/delete_shortcut.rb +2 -4
  53. data/lib/slack/smart-bot/commands/on_bot/get_repl.rb +2 -4
  54. data/lib/slack/smart-bot/commands/on_bot/repl.rb +5 -7
  55. data/lib/slack/smart-bot/commands/on_bot/ruby_code.rb +2 -4
  56. data/lib/slack/smart-bot/commands/on_bot/run_repl.rb +4 -5
  57. data/lib/slack/smart-bot/commands/on_bot/see_repls.rb +3 -5
  58. data/lib/slack/smart-bot/commands/on_bot/see_shortcuts.rb +2 -4
  59. data/lib/slack/smart-bot/commands/on_extended/bot_rules.rb +45 -12
  60. data/lib/slack/smart-bot/commands/on_master/admin/kill_bot_on_channel.rb +4 -1
  61. data/lib/slack/smart-bot/commands/on_master/admin_master/exit_bot.rb +2 -0
  62. data/lib/slack/smart-bot/commands/on_master/admin_master/notify_message.rb +1 -0
  63. data/lib/slack/smart-bot/commands/on_master/admin_master/publish_announcements.rb +32 -0
  64. data/lib/slack/smart-bot/commands/on_master/admin_master/set_general_message.rb +38 -0
  65. data/lib/slack/smart-bot/commands/on_master/admin_master/set_maintenance.rb +8 -0
  66. data/lib/slack/smart-bot/commands/on_master/create_bot.rb +27 -14
  67. data/lib/slack/smart-bot/commands.rb +16 -0
  68. data/lib/slack/smart-bot/listen.rb +1 -3
  69. data/lib/slack/smart-bot/process.rb +212 -74
  70. data/lib/slack/smart-bot/process_first.rb +118 -37
  71. data/lib/slack/smart-bot/treat_message.rb +313 -248
  72. data/lib/slack/smart-bot/utils/build_help.rb +3 -3
  73. data/lib/slack/smart-bot/utils/create_routine_thread.rb +81 -46
  74. data/lib/slack/smart-bot/utils/get_bots_created.rb +4 -1
  75. data/lib/slack/smart-bot/utils/get_help.rb +58 -68
  76. data/lib/slack/smart-bot/utils/get_shares.rb +12 -0
  77. data/lib/slack/smart-bot/utils/has_access.rb +12 -0
  78. data/lib/slack/smart-bot/utils/save_stats.rb +2 -0
  79. data/lib/slack/smart-bot/utils/save_status.rb +52 -0
  80. data/lib/slack/smart-bot/utils.rb +3 -0
  81. data/lib/slack-smart-bot.rb +45 -4
  82. data/lib/slack-smart-bot_general_commands.rb +46 -0
  83. data/lib/slack-smart-bot_general_rules.rb +5 -2
  84. data/lib/slack-smart-bot_rules.rb +43 -17
  85. data/whats_new.txt +32 -20
  86. metadata +24 -2
@@ -24,6 +24,8 @@ class SlackSmartBot
24
24
  else
25
25
  command_txt = data.command
26
26
  end
27
+ command_txt.gsub!(/```.+```/m,'```CODE```')
28
+ command_txt = "#{command_txt[0..99]}..." if command_txt.size > 100
27
29
 
28
30
  if data.routine
29
31
  user_name = "routine/#{data.user.name}"
@@ -0,0 +1,52 @@
1
+ class SlackSmartBot
2
+
3
+ def save_status(status, status_id, message)
4
+ require 'csv'
5
+ Dir.mkdir("#{config.path}/status") unless Dir.exist?("#{config.path}/status")
6
+
7
+ CSV.open("#{config.path}/status/#{config.channel}_status.csv", "a+") do |csv|
8
+ csv << [Time.now.strftime("%Y/%m/%d"), Time.now.strftime("%H:%M:%S"), status, status_id, message]
9
+ end
10
+ if status_id == :disconnected
11
+ Thread.new do
12
+ sleep 50
13
+ @logger.info "check disconnection 50 scs later #{@last_notified_status_id}"
14
+ unless @last_notified_status_id == :connected
15
+ respond ":red_circle: The *SmartBot* on *<##{@channel_id}|#{config.channel}>* is down. An admin will take a look. <@#{config.admins.join(">, <@")}>", config.status_channel
16
+ end
17
+ end
18
+ end
19
+ if @channels_id.is_a?(Hash) and @channels_id.keys.include?(config.status_channel)
20
+ is_back = false
21
+ m = ''
22
+ if (Time.now-@last_status_change) > 20 or !defined?(@last_notified_status_id)
23
+ if status_id == :connected
24
+ if defined?(@last_notified_status_id)
25
+ m = ":exclamation: :large_green_circle: The *SmartBot* on *<##{@channel_id}|#{config.channel}>* was not available for #{(Time.now-@last_status_change).round(0)} secs. *Now it is up and running again.*"
26
+ else
27
+ m = ":large_green_circle: The *SmartBot* on *<##{@channel_id}|#{config.channel}>* is up and running again."
28
+ end
29
+ end
30
+ end
31
+ if status_id == :paused
32
+ m = ":red_circle: #{message} *<##{@channel_id}|#{config.channel}>*"
33
+ elsif status_id == :started
34
+ m = ":large_green_circle: #{message} *<##{@channel_id}|#{config.channel}>*"
35
+ elsif status_id == :killed or status_id == :exited
36
+ m = ":red_circle: #{message}"
37
+ elsif config.on_master_bot and status_id == :maintenance_on
38
+ m = ":red_circle: The *SmartBot* is on maintenance so not possible to attend any request."
39
+ elsif config.on_master_bot and status_id == :maintenance_off
40
+ m = ":large_green_circle: The *SmartBot* is up and running again."
41
+ end
42
+ @last_status_change = Time.now
43
+ @last_notified_status_id = status_id
44
+ unless m == ''
45
+ respond m, config.status_channel
46
+ end
47
+ end
48
+
49
+
50
+ end
51
+
52
+ end
@@ -4,6 +4,7 @@ require_relative 'utils/get_bots_created'
4
4
  require_relative 'utils/get_channels_name_and_id'
5
5
  require_relative 'utils/get_help'
6
6
  require_relative 'utils/get_routines'
7
+ require_relative 'utils/get_shares'
7
8
  require_relative 'utils/get_rules_imported'
8
9
  require_relative 'utils/remove_hash_keys'
9
10
  require_relative 'utils/update_bots_file'
@@ -15,4 +16,6 @@ require_relative 'utils/get_repls'
15
16
  require_relative 'utils/update_repls'
16
17
  require_relative 'utils/answer'
17
18
  require_relative 'utils/answer_delete'
19
+ require_relative 'utils/has_access'
20
+ require_relative 'utils/save_status'
18
21
 
@@ -43,6 +43,9 @@ class SlackSmartBot
43
43
  config[:allow_access] = Hash.new unless config.key?(:allow_access)
44
44
  config[:on_maintenance] = false unless config.key?(:on_maintenance)
45
45
  config[:on_maintenance_message] = "Sorry I'm on maintenance so I cannot attend your request." unless config.key?(:on_maintenance_message)
46
+ config[:general_message] = "" unless config.key?(:general_message)
47
+ config[:logrtm] = false unless config.key?(:logrtm)
48
+ config[:status_channel] = 'smartbot-status' unless config.key?(:status_channel)
46
49
 
47
50
  if config.path.to_s!='' and config.file.to_s==''
48
51
  config.file = File.basename($0)
@@ -61,6 +64,8 @@ class SlackSmartBot
61
64
  Dir.mkdir("#{config.path}/logs") unless Dir.exist?("#{config.path}/logs")
62
65
  Dir.mkdir("#{config.path}/shortcuts") unless Dir.exist?("#{config.path}/shortcuts")
63
66
  Dir.mkdir("#{config.path}/routines") unless Dir.exist?("#{config.path}/routines")
67
+ Dir.mkdir("#{config.path}/announcements") unless Dir.exist?("#{config.path}/announcements")
68
+ Dir.mkdir("#{config.path}/shares") unless Dir.exist?("#{config.path}/shares")
64
69
  File.delete("#{config.path}/config_tmp.status") if File.exist?("#{config.path}/config_tmp.status")
65
70
 
66
71
  config.masters = MASTER_USERS if config.masters.to_s=='' and defined?(MASTER_USERS)
@@ -117,6 +122,7 @@ class SlackSmartBot
117
122
  File.new("#{config.path}/buffer_complete.log", "w") if config[:simulate] and config.on_master_bot
118
123
 
119
124
  self.config = config
125
+ save_status :off, :initializing, "Initializing bot: #{config_log.inspect}"
120
126
 
121
127
  unless config.simulate and config.key?(:client)
122
128
  Slack.configure do |conf|
@@ -128,10 +134,18 @@ class SlackSmartBot
128
134
  while restarts < 200 and !created
129
135
  begin
130
136
  @logger.info "Connecting #{config_log.inspect}"
137
+ save_status :off, :connecting, "Connecting #{config_log.inspect}"
131
138
  if config.simulate and config.key?(:client)
132
139
  self.client = config.client
133
140
  else
134
- self.client = Slack::RealTime::Client.new(start_method: :rtm_connect)
141
+ if config.logrtm
142
+ logrtmname = "#{config.path}/logs/rtm_#{config.channel}.log"
143
+ File.delete(logrtmname) if File.exists?(logrtmname)
144
+ @logrtm = Logger.new(logrtmname)
145
+ self.client = Slack::RealTime::Client.new(start_method: :rtm_connect, logger: @logrtm)
146
+ else
147
+ self.client = Slack::RealTime::Client.new(start_method: :rtm_connect)
148
+ end
135
149
  end
136
150
  created = true
137
151
  rescue Exception => e
@@ -141,6 +155,8 @@ class SlackSmartBot
141
155
  @logger.fatal "Rescued on creation: #{e.inspect}"
142
156
  @logger.info "Waiting 60 seconds to retry. restarts: #{restarts}"
143
157
  puts "#{Time.now}: Not able to create client. Waiting 60 seconds to retry: #{config_log.inspect}"
158
+ save_status :off, :waiting, "Not able to create client. Waiting 60 seconds to retry: #{config_log.inspect}"
159
+
144
160
  sleep 60
145
161
  else
146
162
  exit!
@@ -158,6 +174,11 @@ class SlackSmartBot
158
174
  @rules_imported = Hash.new()
159
175
  @routines = Hash.new()
160
176
  @repls = Hash.new()
177
+ @users = Hash.new()
178
+ @announcements = Hash.new()
179
+ @shares = Hash.new()
180
+ @last_status_change = Time.now
181
+
161
182
 
162
183
  if File.exist?("#{config.path}/shortcuts/#{config.shortcuts_file}")
163
184
  file_sc = IO.readlines("#{config.path}/shortcuts/#{config.shortcuts_file}").join
@@ -180,10 +201,17 @@ class SlackSmartBot
180
201
  if @bots_created.kind_of?(Hash) and config.start_bots
181
202
  @bots_created.each { |key, value|
182
203
  if !value.key?(:cloud) or (value.key?(:cloud) and value[:cloud] == false)
183
- @logger.info "ruby #{config.file_path} \"#{value[:channel_name]}\" \"#{value[:admins]}\" \"#{value[:rules_file]}\" #{value[:status].to_sym}"
204
+ if value.key?(:silent) and value.silent!=config.silent
205
+ silent = value.silent
206
+ else
207
+ silent = config.silent
208
+ end
209
+ @logger.info "BOT_SILENT=#{silent} ruby #{config.file_path} \"#{value[:channel_name]}\" \"#{value[:admins]}\" \"#{value[:rules_file]}\" #{value[:status].to_sym}"
184
210
  puts "Starting #{value[:channel_name]} Smart Bot"
211
+ save_status :off, :starting, "Starting #{value[:channel_name]} Smart Bot"
212
+
185
213
  t = Thread.new do
186
- `ruby #{config.file_path} \"#{value[:channel_name]}\" \"#{value[:admins]}\" \"#{value[:rules_file]}\" #{value[:status].to_sym}`
214
+ `BOT_SILENT=#{silent} ruby #{config.file_path} \"#{value[:channel_name]}\" \"#{value[:admins]}\" \"#{value[:rules_file]}\" #{value[:status].to_sym}`
187
215
  end
188
216
  value[:thread] = t
189
217
  sleep value[:admins].size
@@ -191,6 +219,12 @@ class SlackSmartBot
191
219
  }
192
220
  end
193
221
  end
222
+ general_rules_file = "/rules/general_rules.rb"
223
+ general_commands_file = "/rules/general_commands.rb"
224
+ default_general_rules = (__FILE__).gsub(/\/slack-smart-bot\.rb$/, "/slack-smart-bot_general_rules.rb")
225
+ default_general_commands = (__FILE__).gsub(/\/slack-smart-bot\.rb$/, "/slack-smart-bot_general_commands.rb")
226
+ FileUtils.copy_file(default_general_rules, config.path + general_rules_file) unless File.exist?(config.path + general_rules_file)
227
+ FileUtils.copy_file(default_general_commands, config.path + general_commands_file) unless File.exist?(config.path + general_commands_file)
194
228
 
195
229
  get_rules_imported()
196
230
 
@@ -213,9 +247,11 @@ class SlackSmartBot
213
247
  end
214
248
  rescue Slack::Web::Api::Errors::TooManyRequestsError
215
249
  @logger.fatal "TooManyRequestsError"
250
+ save_status :off, :TooManyRequestsError, "TooManyRequestsError please re run the bot and be sure of executing first: killall ruby"
216
251
  abort("TooManyRequestsError please re run the bot and be sure of executing first: killall ruby")
217
252
  rescue Exception => stack
218
253
  pp stack if config.testing
254
+ save_status :off, :wrong_admin_user, "The admin user specified on settings: #{config.admins.join(", ")}, doesn't exist on Slack. Execution aborted"
219
255
  abort("The admin user specified on settings: #{config.admins.join(", ")}, doesn't exist on Slack. Execution aborted")
220
256
  end
221
257
 
@@ -231,6 +267,7 @@ class SlackSmartBot
231
267
  @questions = Hash.new()
232
268
  @answer = Hash.new()
233
269
  @repl_sessions = Hash.new()
270
+ @datetime_general_commands = 0
234
271
  @channels_id = Hash.new()
235
272
  @channels_name = Hash.new()
236
273
  get_channels_name_and_id()
@@ -239,6 +276,8 @@ class SlackSmartBot
239
276
 
240
277
  get_routines()
241
278
  get_repls()
279
+ get_shares()
280
+
242
281
  if @routines.key?(@channel_id)
243
282
  @routines[@channel_id].each do |k, v|
244
283
  @routines[@channel_id][k][:running] = false
@@ -250,7 +289,7 @@ class SlackSmartBot
250
289
  @routines.each do |ch, rout|
251
290
  rout.each do |k, v|
252
291
  if !v[:running] and v[:channel_name] == config.channel
253
- create_routine_thread(k)
292
+ create_routine_thread(k, v)
254
293
  end
255
294
  end
256
295
  end
@@ -259,12 +298,14 @@ class SlackSmartBot
259
298
  m = "Connection closing, exiting. #{Time.now}"
260
299
  @logger.info m
261
300
  @logger.info _data
301
+ #save_status :off, :closing, "Connection closing, exiting." #todo: don't notify for the moment, remove when checked
262
302
  end
263
303
 
264
304
  client.on :closed do |_data|
265
305
  m = "Connection has been disconnected. #{Time.now}"
266
306
  @logger.info m
267
307
  @logger.info _data
308
+ save_status :off, :disconnected, "Connection has been disconnected."
268
309
  end
269
310
  end
270
311
  self
@@ -0,0 +1,46 @@
1
+ # add here the general commands you will be using in any channel where The SmartBot is part of. Not necessary to use ! or ^, it will answer directly.
2
+ def general_commands(user, command, dest, files = [])
3
+
4
+ begin
5
+ case command
6
+
7
+ # help: ----------------------------------------------
8
+ # help: `cls`
9
+ # help: `clear`
10
+ # help: `clear screen`
11
+ # help: `NUMBER cls`
12
+ # help: It will send a big empty message.
13
+ # help: NUMBER (optional): number of lines. Default 100. Max 200.
14
+ # help: command_id: :cls
15
+ # help:
16
+ when /\A\s*(\d*)\s*(clear|cls|clear\s+screen)\s*\z/i
17
+ save_stats :cls
18
+ $1.to_s == '' ? lines = 100 : lines = $1.to_i
19
+ lines = 200 if lines > 200
20
+ respond (">#{"\n"*lines}<")
21
+
22
+
23
+ # this is a hidden command that it is not listed when calling bot help
24
+ when /\A\s*(that's\s+)?(thanks|thank\s+you|I\s+love\s+you|nice|cool)\s+(#{@salutations.join("|")})\s*!*\s*$/i
25
+ save_stats :thanks
26
+ reactions = [:heart, :heart_eyes, :blush, :relaxed, :simple_smile, :smiley, :two_hearts, :heartbeat, :green_heart ]
27
+ reactions.sample(rand(3)+1).each {|rt| react rt }
28
+ responses = ['Thank YOU', "You're welcome", "You're very welcome", 'No problem', 'No worries', "Don't mention it", 'My pleasure',
29
+ 'Anytime', 'It was the least I could do', 'Glad to help', 'Sure', 'Pleasure', 'The pleasure is mine', 'It was nothing', 'Much obliged', "I'm happy to help",
30
+ 'Það var ekkert', 'De nada', 'No hay de qué', 'De rien', 'Bitte', 'Prego', 'मेरा सौभाग्य है', '不客氣', 'Παρακαλώ']
31
+ respond "#{responses.sample}#{'!'*rand(4)}"
32
+
33
+ else
34
+ return false
35
+ end
36
+ return true
37
+ rescue => exception
38
+ if defined?(@logger)
39
+ @logger.fatal exception
40
+ respond "Unexpected error!! Please contact an admin to solve it: <@#{config.admins.join(">, <@")}>"
41
+ else
42
+ puts exception
43
+ end
44
+ return false
45
+ end
46
+ end
@@ -13,7 +13,9 @@ def general_rules(user, command, processed, dest, files = [], rules_file = "")
13
13
  # help: Examples:
14
14
  # help: _echo I am the Smart Bot_
15
15
  # help: _100 echo :heart:_
16
- when /^(\d*)\s*echo\s(.+)/i
16
+ # help: command_id: :echo
17
+ # help:
18
+ when /\A\s*(\d*)\s*echo\s(.+)/i
17
19
  save_stats :echo
18
20
  $1.to_s == '' ? times = 1 : times = $1.to_i
19
21
  respond ($2*times).to_s
@@ -25,9 +27,10 @@ def general_rules(user, command, processed, dest, files = [], rules_file = "")
25
27
  rescue => exception
26
28
  if defined?(@logger)
27
29
  @logger.fatal exception
28
- respond "Unexpected error!! Please contact an admin to solve it: <@#{ADMIN_USERS.join(">, <@")}>"
30
+ respond "Unexpected error!! Please contact an admin to solve it: <@#{config.admins.join(">, <@")}>"
29
31
  else
30
32
  puts exception
31
33
  end
34
+ return false
32
35
  end
33
36
  end
@@ -40,15 +40,18 @@ def rules(user, command, processed, dest, files = [], rules_file = "")
40
40
 
41
41
  load "#{config.path}/rules/general_rules.rb"
42
42
 
43
- unless general_rules(user, command, processed, dest, files, rules_file)
43
+ if general_rules(user, command, processed, dest, files, rules_file)
44
+ return true
45
+ else
44
46
  begin
45
47
  case command
46
48
 
47
49
  # help: ----------------------------------------------
48
50
  # help: `go to sleep`
49
51
  # help: it will sleep the bot for 5 seconds
52
+ # help: command_id: :go_to_sleep
50
53
  # help:
51
- when /^go\sto\ssleep/i
54
+ when /\A\s*go\sto\ssleep/i
52
55
  save_stats :go_to_sleep
53
56
  if answer.empty?
54
57
  ask "do you want me to take a siesta?"
@@ -74,32 +77,41 @@ def rules(user, command, processed, dest, files = [], rules_file = "")
74
77
  # help: ----------------------------------------------
75
78
  # help: `run something`
76
79
  # help: It will run the process and report the results when done
80
+ # help: command_id: :run_something
77
81
  # help:
78
- when /^run something/i
82
+ when /\Arun something/i
79
83
  save_stats :run_something
80
- react :runner
84
+ if has_access?(:run_something, user)
85
+ react :runner
81
86
 
82
- process_to_run = "ruby -v"
83
- process_to_run = ("cd #{project_folder} &&" + process_to_run) if defined?(project_folder)
84
- stdout, stderr, status = Open3.capture3(process_to_run)
85
- unreact :runner
86
- if stderr == ""
87
- if stdout == ""
88
- respond "#{display_name}: Nothing returned."
87
+ process_to_run = "ruby -v"
88
+ process_to_run = ("cd #{project_folder} &&" + process_to_run) if defined?(project_folder)
89
+ stdout, stderr, status = Open3.capture3(process_to_run)
90
+ unreact :runner
91
+ if stderr == ""
92
+ if stdout == ""
93
+ respond "#{display_name}: Nothing returned."
94
+ else
95
+ respond "#{display_name}: #{stdout}"
96
+ end
89
97
  else
90
- respond "#{display_name}: #{stdout}"
98
+ respond "#{display_name}: #{stdout} #{stderr}"
91
99
  end
92
- else
93
- respond "#{display_name}: #{stdout} #{stderr}"
94
100
  end
95
101
 
96
102
  # Emoticons you can use with `react` command https://www.webfx.com/tools/emoji-cheat-sheet/
97
103
 
98
- # Examples for respond and respond_direct
104
+ # Examples for respond, respond_thread and respond_direct
99
105
  # # send 'the message' to the channel or direct message where the command was written
100
106
  # respond "the message"
101
107
  # # send 'the message' privately as a direct message to the user that sent the command
102
108
  # respond_direct "the message"
109
+ # # same thing can be done:
110
+ # respond "the message", :direct
111
+ # # send 'the message' opening a thread
112
+ # respond_thread "the message"
113
+ # # same thing can be done:
114
+ # respond 'the message', :on_thread
103
115
  # # send 'the message' to a specific channel name
104
116
  # respond "the message", 'my_channel'
105
117
  # # send 'the message' to a specific channel id
@@ -109,6 +121,19 @@ def rules(user, command, processed, dest, files = [], rules_file = "")
109
121
  # # send 'the message' to a specific user id as direct message
110
122
  # respond "the message", 'US3344D3'
111
123
 
124
+ # Example sending blocks https://api.slack.com/block-kit
125
+ # my_blocks = [
126
+ # { type: "context",
127
+ # elements:
128
+ # [
129
+ # { type: "plain_text", :text=>"\tInfo: " },
130
+ # { type: "image", image_url: "https://avatars.slack-edge.com/2021-03-23/182815_e54abb1dd_24.jpg", alt_text: "mario" },
131
+ # { type: "mrkdwn", text: " *Mario Ruiz* (marior) " }
132
+ # ]
133
+ # }
134
+ # ]
135
+ # respond blocks: my_blocks
136
+
112
137
  # Example downloading a file from slack
113
138
  # if !files.nil? and files.size == 1 and files[0].filetype == 'yaml'
114
139
  # require 'nice_http'
@@ -120,16 +145,17 @@ def rules(user, command, processed, dest, files = [], rules_file = "")
120
145
  # send_file(to, msg, filepath, title, format, type = "text")
121
146
  # send_file(dest, 'the message', "#{project_folder}/temp/logs_ptBI.log", 'title', 'text/plain', "text")
122
147
  # send_file(dest, 'the message', "#{project_folder}/temp/example.jpeg", 'title', 'image/jpeg', "jpg")
123
-
124
-
125
148
  else
126
149
  unless processed
127
150
  dont_understand()
128
151
  end
152
+ return false
129
153
  end
154
+ return true
130
155
  rescue => exception
131
156
  @logger.fatal exception
132
157
  respond "Unexpected error!! Please contact an admin to solve it: <@#{config.admins.join(">, <@")}>"
158
+ return false
133
159
  end
134
160
  end
135
161
  end
data/whats_new.txt CHANGED
@@ -1,24 +1,36 @@
1
- *Version 1.9.2* Released 2021-Apr-27
1
+ *Version 1.10.0* Released 2021-Sep-17
2
2
 
3
- - Bugfixing and small improvements
4
-
5
- ------------------------------
3
+ *For General users*
4
+ - When on a private conversation with the SmartBot (DM) and not using any channels rule on the conversation, the general_rules will be available.
5
+ - On DM with the SmartBot if you want to use a rule from a specific channel you can use also: `#CHANNEL RULE` or `on #CHANNEL RULE`. For example: `#sales get report for India`
6
+ - Now when using general commands, the SmartBot will be responding on any channel where is a member, even though is not listening to you. For example: `clear screen`
7
+ - Added command `suggest command` that will return the help content for a random command.
8
+ - New command `leaderboard` returns useful information about the use of the SmartBot.
9
+ - `add COLOR announcement MESSAGE`, `add EMOJI announcement MESSAGE` command stores the message on the announcement list labeled with the color/emoji specified, white by default. Aliases for announcement: statement, declaration, message. Related: `see announcements`, `delete announcement id`
10
+ - `hi bot` and `bye bot` can be called from any channel where the SmartBot is a member.
11
+ - Added general command `see statuses`, `who is on vacation?`, `who is not on vacation?`
12
+ - New general command `see favorite commands`. It will display the favorite commands in that channel.
13
+ - Now when running the `ruby` command it can be supplied a code block.
14
+ - New general command `share messages /REGEXP/ on #CHANNEL`, `share messages "TEXT" on #CHANNEL`, `see shares', `delete share ID`. It will automatically share new messages published that meet the specified criteria.
6
15
 
7
- *Version 1.9.0* Released 2021-Mar-18
16
+ *For Admin users*
17
+ - respond_thread method will send the respond creating a thread if necessary. It can be used also `respond 'msg', :on_thread`
18
+ - `respond 'msg', :direct` will send a direct message to the person that is executing the rule.
19
+ - You can add general commands that will be responding on any channel where the Smart Bot is a member even though is not 'listening to you'. Add them to '/rules/general_commands.rb
20
+ - when using `respond` you can supply two options: unfurl_links and unfurl_media. By default is a boolean: true
21
+ - added option 'weekdays' and 'weekends' for `create routine` command, for example: `add silent routine suggestions on weekdays at 09:00 suggest command`
22
+ - Added a new config for the SmartBot to log all RTM communication, admits `true` or `false`, by default `false`: `logrtm`
23
+ - Use the command `send message to` and `react to` to impersonate the SmartBot. Only accessible for Master Admins on a DM with the SmartBot.
24
+ - New command to see the result of the last run of a routine: `see result routine NAME`
25
+ - Now it is possible to create *bgroutine* then the results of the routine run won't be published.
26
+ - To display a general message after every command use: `set general message MESSAGE`. Use `set general message off` to stop displaying it.
27
+ - When adding a general message is possible to use interpolation
28
+ - If you are a master admin and you are on master channel then you can call `publish announcements` that will publish the announcements on all channels. The messages stored on a DM won't be published. This is very convenient to be called from a *Routine* for example every weekday at 09:00.
29
+ - Now it is possible to send blocks `respond blocks: my_blocks`. More info about blocks: https://api.slack.com/block-kit
30
+ - When using bgroutines if we want to avoid a file to be sent:
31
+ send_file(dest, 'description', "file_path", 'desc', 'text/plain', "text") unless Thread.current[:routine_type] == 'bgroutine'
32
+ - SmartBot will notify about SmartBot status changes if defined the status_channel in config file and the channel exists. By default: smartbot-status
8
33
 
9
- *For General users*
10
- - Added command `what's new` that will show this.
11
- - `bot stats` will return detailed statistics using the SmartBot. If you call it from a DM with the SmartBot you will see all stats for all Bot channels.
12
- - Possible to create 'global' shortcuts that will be available on any SmartBot Channel.
13
- - Added option to start a `repl` without pre-executing '.smart-bot-repl' source code in case exists. Just add `clean` before the `repl` command. For example: `clean repl Example`
14
- - When using `Ruby` command in case the process doesn't finish in 20 seconds will be aborted.
15
- - When creating rules/commands and asking a question now you can use 'answer' instead of '@questions'. Take a look at README.md for an example.
16
- - Using external calls, it is possible to send to more than one bot channel the same rule: `@smart-bot on #channel1 #channel2 #channel3 echo Lala`
17
- - `bot help` and `bot rules` return by default a short version of the commands. Call `bot help expanded` or `bot rules expanded` to get a full desciption of the commands.
18
- - It is possible to exclude routines from results when using `bot stats`
19
34
  ------------------------------
20
- *For Admin users*
21
- - `Bot stats` now shows the top 10 users and attaches the full list of users and commands.
22
- - Bot Stats. Now the routines are displayed as routine/USER
23
- - When creating routines now it is possible to publish in a different channel: `add routine run_tests at 17:05 #thechannel !run api tests`
24
- - `Turn maintenance on/off` command available
35
+
36
+ *Previous*: <https://github.com/MarioRuiz/slack-smart-bot/blob/dd23939f93ee95aca3c04d33cd1ce197d6efbd37/whats_new.txt|1.9.0>