slack-smart-bot 1.9.2 → 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 (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>