slack-smart-bot 1.10.0 → 1.11.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (104) hide show
  1. checksums.yaml +4 -4
  2. data/README.md +91 -21
  3. data/lib/slack/smart-bot/comm/delete.rb +13 -0
  4. data/lib/slack/smart-bot/comm/dont_understand.rb +2 -2
  5. data/lib/slack/smart-bot/comm/get_channel_members.rb +7 -3
  6. data/lib/slack/smart-bot/comm/get_presence.rb +20 -0
  7. data/lib/slack/smart-bot/comm/get_users.rb +1 -1
  8. data/lib/slack/smart-bot/comm/respond.rb +18 -13
  9. data/lib/slack/smart-bot/comm/send_msg_user.rb +12 -11
  10. data/lib/slack/smart-bot/comm.rb +2 -0
  11. data/lib/slack/smart-bot/commands/general/add_admin.rb +51 -0
  12. data/lib/slack/smart-bot/commands/general/add_announcement.rb +1 -1
  13. data/lib/slack/smart-bot/commands/general/add_team.rb +80 -0
  14. data/lib/slack/smart-bot/commands/general/allow_access.rb +67 -0
  15. data/lib/slack/smart-bot/commands/general/bot_help.rb +20 -11
  16. data/lib/slack/smart-bot/commands/general/delete_announcement.rb +1 -1
  17. data/lib/slack/smart-bot/commands/general/delete_share.rb +1 -1
  18. data/lib/slack/smart-bot/commands/general/delete_team.rb +34 -0
  19. data/lib/slack/smart-bot/commands/general/deny_access.rb +36 -0
  20. data/lib/slack/smart-bot/commands/general/ping_team.rb +100 -0
  21. data/lib/slack/smart-bot/commands/general/poster.rb +116 -0
  22. data/lib/slack/smart-bot/commands/general/remove_admin.rb +58 -0
  23. data/lib/slack/smart-bot/commands/general/see_access.rb +24 -0
  24. data/lib/slack/smart-bot/commands/general/see_admins.rb +33 -0
  25. data/lib/slack/smart-bot/commands/general/see_announcements.rb +6 -4
  26. data/lib/slack/smart-bot/commands/general/see_command_ids.rb +29 -0
  27. data/lib/slack/smart-bot/commands/general/see_favorite_commands.rb +3 -4
  28. data/lib/slack/smart-bot/commands/general/see_statuses.rb +34 -21
  29. data/lib/slack/smart-bot/commands/general/see_teams.rb +252 -0
  30. data/lib/slack/smart-bot/commands/general/share_messages.rb +1 -1
  31. data/lib/slack/smart-bot/commands/general/update_team.rb +109 -0
  32. data/lib/slack/smart-bot/commands/general_bot_commands.rb +271 -10
  33. data/lib/slack/smart-bot/commands/on_bot/add_shortcut.rb +2 -1
  34. data/lib/slack/smart-bot/commands/on_bot/admin/add_routine.rb +2 -1
  35. data/lib/slack/smart-bot/commands/on_bot/admin/extend_rules.rb +2 -1
  36. data/lib/slack/smart-bot/commands/on_bot/admin/pause_bot.rb +2 -1
  37. data/lib/slack/smart-bot/commands/on_bot/admin/pause_routine.rb +2 -1
  38. data/lib/slack/smart-bot/commands/on_bot/admin/remove_routine.rb +2 -1
  39. data/lib/slack/smart-bot/commands/on_bot/admin/run_routine.rb +3 -2
  40. data/lib/slack/smart-bot/commands/on_bot/admin/see_result_routine.rb +2 -1
  41. data/lib/slack/smart-bot/commands/on_bot/admin/see_routines.rb +10 -9
  42. data/lib/slack/smart-bot/commands/on_bot/admin/start_bot.rb +2 -1
  43. data/lib/slack/smart-bot/commands/on_bot/admin/start_routine.rb +2 -1
  44. data/lib/slack/smart-bot/commands/on_bot/admin/stop_using_rules_on.rb +2 -1
  45. data/lib/slack/smart-bot/commands/on_bot/admin_master/delete_message.rb +25 -0
  46. data/lib/slack/smart-bot/commands/on_bot/admin_master/get_bot_logs.rb +1 -0
  47. data/lib/slack/smart-bot/commands/on_bot/admin_master/react_to.rb +3 -1
  48. data/lib/slack/smart-bot/commands/on_bot/admin_master/send_message.rb +15 -2
  49. data/lib/slack/smart-bot/commands/on_bot/delete_repl.rb +2 -1
  50. data/lib/slack/smart-bot/commands/on_bot/delete_shortcut.rb +5 -4
  51. data/lib/slack/smart-bot/commands/on_bot/general/bot_stats.rb +400 -0
  52. data/lib/slack/smart-bot/commands/{general → on_bot/general}/bot_status.rb +1 -0
  53. data/lib/slack/smart-bot/commands/{general → on_bot/general}/leaderboard.rb +1 -0
  54. data/lib/slack/smart-bot/commands/{general → on_bot/general}/stop_using_rules.rb +1 -0
  55. data/lib/slack/smart-bot/commands/{general → on_bot/general}/suggest_command.rb +6 -0
  56. data/lib/slack/smart-bot/commands/{general → on_bot/general}/use_rules.rb +1 -0
  57. data/lib/slack/smart-bot/commands/{general → on_bot/general}/whats_new.rb +2 -1
  58. data/lib/slack/smart-bot/commands/on_bot/get_repl.rb +2 -1
  59. data/lib/slack/smart-bot/commands/on_bot/repl.rb +72 -15
  60. data/lib/slack/smart-bot/commands/on_bot/ruby_code.rb +1 -0
  61. data/lib/slack/smart-bot/commands/on_bot/run_repl.rb +11 -2
  62. data/lib/slack/smart-bot/commands/on_bot/see_repls.rb +2 -1
  63. data/lib/slack/smart-bot/commands/on_bot/see_shortcuts.rb +3 -2
  64. data/lib/slack/smart-bot/commands/on_master/admin/kill_bot_on_channel.rb +5 -4
  65. data/lib/slack/smart-bot/commands/on_master/admin_master/exit_bot.rb +3 -2
  66. data/lib/slack/smart-bot/commands/on_master/admin_master/notify_message.rb +2 -1
  67. data/lib/slack/smart-bot/commands/on_master/admin_master/publish_announcements.rb +3 -2
  68. data/lib/slack/smart-bot/commands/on_master/admin_master/set_general_message.rb +2 -1
  69. data/lib/slack/smart-bot/commands/on_master/admin_master/set_maintenance.rb +2 -1
  70. data/lib/slack/smart-bot/commands/on_master/create_bot.rb +1 -0
  71. data/lib/slack/smart-bot/commands/on_master/where_smartbot.rb +41 -0
  72. data/lib/slack/smart-bot/commands.rb +22 -7
  73. data/lib/slack/smart-bot/listen.rb +30 -30
  74. data/lib/slack/smart-bot/process.rb +38 -18
  75. data/lib/slack/smart-bot/process_first.rb +2 -2
  76. data/lib/slack/smart-bot/treat_message.rb +13 -17
  77. data/lib/slack/smart-bot/utils/build_help.rb +1 -1
  78. data/lib/slack/smart-bot/utils/create_routine_thread.rb +1 -1
  79. data/lib/slack/smart-bot/utils/get_access_channels.rb +13 -0
  80. data/lib/slack/smart-bot/utils/get_admins_channels.rb +13 -0
  81. data/lib/slack/smart-bot/utils/get_bots_created.rb +27 -10
  82. data/lib/slack/smart-bot/utils/get_channels_name_and_id.rb +7 -2
  83. data/lib/slack/smart-bot/utils/get_command_ids.rb +84 -0
  84. data/lib/slack/smart-bot/utils/get_help.rb +34 -18
  85. data/lib/slack/smart-bot/utils/get_repls.rb +22 -2
  86. data/lib/slack/smart-bot/utils/get_routines.rb +22 -2
  87. data/lib/slack/smart-bot/utils/get_teams.rb +22 -0
  88. data/lib/slack/smart-bot/utils/has_access.rb +25 -9
  89. data/lib/slack/smart-bot/utils/is_admin.rb +27 -0
  90. data/lib/slack/smart-bot/utils/save_stats.rb +46 -43
  91. data/lib/slack/smart-bot/utils/save_status.rb +21 -6
  92. data/lib/slack/smart-bot/utils/update_access_channels.rb +8 -0
  93. data/lib/slack/smart-bot/utils/update_admins_channels.rb +8 -0
  94. data/lib/slack/smart-bot/utils/update_bots_file.rb +28 -7
  95. data/lib/slack/smart-bot/utils/update_repls.rb +7 -4
  96. data/lib/slack/smart-bot/utils/update_routines.rb +9 -3
  97. data/lib/slack/smart-bot/utils/update_shortcuts_file.rb +13 -6
  98. data/lib/slack/smart-bot/utils/update_teams.rb +16 -0
  99. data/lib/slack/smart-bot/utils.rb +8 -0
  100. data/lib/slack-smart-bot.rb +28 -10
  101. data/lib/slack-smart-bot_general_commands.rb +16 -1
  102. data/whats_new.txt +16 -29
  103. metadata +64 -19
  104. data/lib/slack/smart-bot/commands/general/bot_stats.rb +0 -314
@@ -17,7 +17,7 @@ class SlackSmartBot
17
17
  # help: If 'clean' specified the repl won't pre execute the code written on the .smart-bot-repl file
18
18
  # help: To avoid a message to be treated, start the message with '-'.
19
19
  # help: Send _quit_, _bye_ or _exit_ to finish the session.
20
- # help: Send puts, print, p or pp if you want to print out something when using `run repl` later.
20
+ # help: Send puts, print, p or pp if you want to print out something when using _run repl_ later.
21
21
  # help: After 30 minutes of no communication with the Smart Bot the session will be dismissed.
22
22
  # help: If you declare on your rules file a method called 'project_folder' returning the path for the project folder, the code will be executed from that folder.
23
23
  # help: By default it will be automatically loaded the gems: string_pattern, nice_hash and nice_http
@@ -30,6 +30,7 @@ class SlackSmartBot
30
30
  # help: _repl delete_logs_
31
31
  # help: _private repl random-ssn_
32
32
  # help: <https://github.com/MarioRuiz/slack-smart-bot#repl|more info>
33
+ # help: command_id: :repl
33
34
  # help:
34
35
  def repl(dest, user, session_name, env_vars, rules_file, command, description, type)
35
36
  #todo: add more tests
@@ -78,11 +79,14 @@ class SlackSmartBot
78
79
  update_repls()
79
80
  end
80
81
  react :running
82
+ @ts_react ||= {}
81
83
  if Thread.current[:ts].to_s == ''
82
- @ts_react = Thread.current[:thread_ts]
84
+ @ts_react[session_name] = Thread.current[:thread_ts]
83
85
  else
84
- @ts_react = Thread.current[:ts]
86
+ @ts_react[session_name] = Thread.current[:ts]
85
87
  end
88
+ @ts_repl ||= {}
89
+ @ts_repl[session_name] = ''
86
90
 
87
91
  message = "Session name: *#{session_name}*
88
92
  From now on I will execute all you write as a Ruby command and I will keep the session open until you send `quit` or `bye` or `exit`.
@@ -115,14 +119,14 @@ class SlackSmartBot
115
119
  end
116
120
 
117
121
  process_to_run = '
118
- ruby -e "' + env_vars.join("\n") + '
122
+ ' + env_vars.join("\n") + '
119
123
  require \"amazing_print\"
120
124
  bindme' + serialt + ' = binding
121
125
  eval(\"require \'nice_http\'\" , bindme' + serialt + ')
122
126
  def ls(obj)
123
127
  (obj.methods - Object.methods)
124
128
  end
125
-
129
+ file_run_path = \"' + + File.expand_path(config.path) + '/repl/' + @channel_id + '/' + session_name + '.rb\"
126
130
  file_input_repl = File.open(\"' + File.expand_path(config.path) + '/repl/' + @channel_id + '/' + session_name + '.input\", \"r\")
127
131
  ' + pre_execute + '
128
132
  while true do
@@ -141,18 +145,40 @@ class SlackSmartBot
141
145
  end
142
146
  error = false
143
147
  begin
144
- resp_repl = eval(code_to_run_repl.gsub(/^\s*(puts|print|p|pp)\s/, \"\"), bindme' + serialt + ')
148
+ begin
149
+ original_stdout = $stdout
150
+ $stdout = StringIO.new
151
+ resp_repl = eval(code_to_run_repl, bindme' + serialt + ')
152
+ stdout_repl = $stdout.string
153
+ ensure
154
+ $stdout = original_stdout
155
+ end
145
156
  rescue Exception => resp_repl
146
157
  error = true
147
158
  end
148
- unless error
159
+ if error
160
+ open(\"' + File.expand_path(config.path) + '/repl/' + @channel_id + '/' + session_name + '.output\", \"a+\") {|f|
161
+ f.puts \"\`\`\`\n#{resp_repl.to_s.gsub(/^.+' + session_name + '\.rb:\d+:/,\"\")}\`\`\`\"
162
+ }
163
+ else
149
164
  if code_to_run_repl.match?(/^\s*p\s+/i)
165
+ resp_repl = stdout_repl unless stdout_repl.to_s == \'\'
166
+ if stdout_repl.to_s == \'\'
167
+ resp_repl = resp_repl.inspect
168
+ else
169
+ resp_repl = stdout_repl
170
+ end
150
171
  open(\"' + File.expand_path(config.path) + '/repl/' + @channel_id + '/' + session_name + '.output\", \"a+\") {|f|
151
- f.puts \"\`\`\`\n#{resp_repl.inspect}\n\`\`\`\"
172
+ f.puts \"\`\`\`\n#{resp_repl}\`\`\`\"
152
173
  }
153
174
  else
175
+ if stdout_repl.to_s == \'\'
176
+ resp_repl = resp_repl.ai
177
+ else
178
+ resp_repl = stdout_repl
179
+ end
154
180
  open(\"' + File.expand_path(config.path) + '/repl/' + @channel_id + '/' + session_name + '.output\", \"a+\") {|f|
155
- f.puts \"\`\`\`\n#{resp_repl.ai}\n\`\`\`\"
181
+ f.puts \"\`\`\`\n#{resp_repl}\`\`\`\"
156
182
  }
157
183
  end
158
184
  unless !add_to_run_repl
@@ -163,16 +189,35 @@ class SlackSmartBot
163
189
  end
164
190
  end
165
191
  end
166
- end"
192
+ end
167
193
  '
168
194
  unless rules_file.empty? # to get the project_folder
169
195
  begin
170
196
  eval(File.new(config.path+rules_file).read) if File.exist?(config.path+rules_file)
171
197
  end
172
198
  end
173
- started = Time.now
174
- process_to_run = ("cd #{project_folder} &&" + process_to_run) if defined?(project_folder)
199
+ process_to_run.gsub!('\"','"')
200
+ file_run_path = "./tmp/repl/#{@channel_id}/#{session_name}.rb"
201
+ if defined?(project_folder)
202
+ Dir.mkdir("#{project_folder}/tmp/") unless Dir.exist?("#{project_folder}/tmp/")
203
+ Dir.mkdir("#{project_folder}/tmp/repl") unless Dir.exist?("#{project_folder}/tmp/repl")
204
+ Dir.mkdir("#{project_folder}/tmp/repl/#{@channel_id}/") unless Dir.exist?("#{project_folder}/tmp/repl/#{@channel_id}/")
205
+ file_run = File.open(file_run_path.gsub('./',"#{project_folder}/"), "w")
206
+ file_run.write process_to_run
207
+ file_run.close
208
+ else
209
+ Dir.mkdir("./tmp/") unless Dir.exist?("./tmp/")
210
+ Dir.mkdir("./tmp/repl") unless Dir.exist?("./tmp/repl")
211
+ Dir.mkdir("./tmp/repl/#{@channel_id}/") unless Dir.exist?("./tmp/repl/#{@channel_id}/")
212
+ file_run = File.open(file_run_path, "w")
213
+ file_run.write process_to_run
214
+ file_run.close
215
+ end
175
216
 
217
+ process_to_run = "ruby #{file_run_path}"
218
+
219
+ started = Time.now
220
+ process_to_run = ("cd #{project_folder} && " + process_to_run) if defined?(project_folder)
176
221
  stdin, stdout, stderr, wait_thr = Open3.popen3(process_to_run)
177
222
  timeout = 30 * 60 # 30 minutes
178
223
 
@@ -185,7 +230,7 @@ class SlackSmartBot
185
230
  f.puts 'quit'
186
231
  }
187
232
  respond "REPL session finished: #{@repl_sessions[from][:name]}", dest
188
- unreact :running, @ts_react
233
+ unreact :running, @ts_react[@repl_sessions[from].name]
189
234
  pids = `pgrep -P #{@repl_sessions[from][:pid]}`.split("\n").map(&:to_i) #todo: it needs to be adapted for Windows
190
235
  pids.each do |pid|
191
236
  begin
@@ -199,6 +244,10 @@ class SlackSmartBot
199
244
  sleep 0.2
200
245
  resp_repl = file_output_repl.read
201
246
  if resp_repl.to_s!=''
247
+ if @ts_repl[@repl_sessions[from].name].to_s != ''
248
+ unreact(:running, @ts_repl[@repl_sessions[from].name])
249
+ @ts_repl[@repl_sessions[from].name] = ''
250
+ end
202
251
  if resp_repl.to_s.lines.count < 60 and resp_repl.to_s.size < 3500
203
252
  respond resp_repl, dest
204
253
  else
@@ -211,6 +260,8 @@ class SlackSmartBot
211
260
  @logger.fatal excp
212
261
  end
213
262
  end
263
+ elsif @repl_sessions.key?(from) and @repl_sessions[from][:command].to_s == ''
264
+ respond 'You are already in a repl on this SmartBot. You need to quit that one before starting a new one.'
214
265
  else
215
266
  @repl_sessions[from][:finished] = Time.now
216
267
  code = @repl_sessions[from][:command]
@@ -224,7 +275,9 @@ class SlackSmartBot
224
275
  code.match?(/open3/i) or code.match?(/bundle/i) or code.match?(/gemfile/i) or code.include?("%x") or
225
276
  code.include?("ENV") or code.match?(/=\s*IO/) or code.include?("Dir.") or
226
277
  code.match?(/=\s*File/) or code.match?(/=\s*Dir/) or code.match?(/<\s*File/) or code.match?(/<\s*Dir/) or
227
- code.match?(/\w+:\s*File/) or code.match?(/\w+:\s*Dir/)
278
+ code.match?(/\w+:\s*File/) or code.match?(/\w+:\s*Dir/) or
279
+ code.match?(/=?\s*(require|load)(\(|\s)/i)
280
+
228
281
  respond "Sorry I cannot run this due security reasons", dest
229
282
  else
230
283
  @repl_sessions[from][:input]<<code
@@ -234,7 +287,7 @@ class SlackSmartBot
234
287
  f.puts code
235
288
  }
236
289
  respond "REPL session finished: #{@repl_sessions[from][:name]}", dest
237
- unreact :running, @ts_react
290
+ unreact :running, @ts_react[@repl_sessions[from].name]
238
291
  pids = `pgrep -P #{@repl_sessions[from][:pid]}`.split("\n").map(&:to_i) #todo: it needs to be adapted for Windows
239
292
  pids.each do |pid|
240
293
  begin
@@ -246,6 +299,10 @@ class SlackSmartBot
246
299
  when /^\s*-/i
247
300
  #ommit
248
301
  else
302
+ if @ts_repl[@repl_sessions[from].name].to_s == ''
303
+ @ts_repl[@repl_sessions[from].name] = Thread.current[:ts]
304
+ react :running
305
+ end
249
306
  open("#{config.path}/repl/#{@channel_id}/#{@repl_sessions[from][:name]}.input", 'a+') {|f|
250
307
  f.puts code
251
308
  }
@@ -6,6 +6,7 @@ class SlackSmartBot
6
6
  # help: _code puts (34344/99)*(34+14)_
7
7
  # help: _ruby require 'json'; res=[]; 20.times {res<<rand(100)}; my_json={result: res}; puts my_json.to_json_
8
8
  # help: <https://github.com/MarioRuiz/slack-smart-bot#running-ruby-code-on-a-conversation|more info>
9
+ # help: command_id: :ruby_code
9
10
  # help:
10
11
 
11
12
  def ruby_code(dest, user, code, rules_file)
@@ -10,6 +10,7 @@ class SlackSmartBot
10
10
  # help: Example:
11
11
  # help: _run repl CreateCustomer LOCATION=spain HOST='https://10.30.40.50:8887'_
12
12
  # help: <https://github.com/MarioRuiz/slack-smart-bot#repl|more info>
13
+ # help: command_id: :run_repl
13
14
  # help:
14
15
  def run_repl(dest, user, session_name, env_vars, rules_file)
15
16
  #todo: add tests
@@ -21,7 +22,7 @@ class SlackSmartBot
21
22
  if File.exist?("#{config.path}/repl/#{@channel_id}/#{session_name}.run")
22
23
  if @repls.key?(session_name) and (@repls[session_name][:type] == :private or @repls[session_name][:type] == :private_clean) and
23
24
  @repls[session_name][:creator_name]!=user.name and
24
- !config.admins.include?(user.name)
25
+ !is_admin?(user.name)
25
26
  respond "The REPL with session name: #{session_name} is private", dest
26
27
  else
27
28
  if @repls.key?(session_name) #not temp
@@ -59,7 +60,15 @@ class SlackSmartBot
59
60
  respond "*#{session_name}*: Nothing returned."
60
61
  else
61
62
  if stdout.to_s.lines.count < 60 and stdout.to_s.size < 3500
62
- respond "*#{session_name}*: #{stdout}"
63
+ output = ''
64
+ stdout.each_line do |line|
65
+ if line.match?(/^{.+}$/) or line.match?(/^\[.+\]$/)
66
+ output += "```\n#{line}```\n"
67
+ else
68
+ output +=line
69
+ end
70
+ end
71
+ respond "*#{session_name}*: #{output}"
63
72
  else
64
73
  send_file(dest, "", 'response.rb', "", 'text/plain', "ruby", content: stdout)
65
74
  end
@@ -4,6 +4,7 @@ class SlackSmartBot
4
4
  # help: `see irbs`
5
5
  # help: It will display the repls
6
6
  # help: <https://github.com/MarioRuiz/slack-smart-bot#repl|more info>
7
+ # help: command_id: :see_repls
7
8
  # help:
8
9
  def see_repls(dest, user, typem)
9
10
  #todo: add tests
@@ -12,7 +13,7 @@ class SlackSmartBot
12
13
  if has_access?(__method__, user)
13
14
  message = ""
14
15
  @repls.sort.to_h.each do |session_name, repl|
15
- if (repl.creator_name == user.name or repl.type == :public or repl.type == :public_clean) or (config.admins.include?(user.name) and typem == :on_dm)
16
+ if (repl.creator_name == user.name or repl.type == :public or repl.type == :public_clean) or (is_admin?(user.name) and typem == :on_dm)
16
17
  message += "(#{repl.type}) *#{session_name}*: #{repl.description} / created: #{repl.created} / accessed: #{repl.accessed} / creator: #{repl.creator_name} / runs: #{repl.runs_by_creator+repl.runs_by_others} / gets: #{repl.gets} \n"
17
18
  end
18
19
  end
@@ -4,6 +4,7 @@ class SlackSmartBot
4
4
  # help: `see sc`
5
5
  # help: It will display the shortcuts stored for the user and for :all
6
6
  # help: <https://github.com/MarioRuiz/slack-smart-bot#shortcuts|more info>
7
+ # help: command_id: :see_shortcuts
7
8
  # help:
8
9
  def see_shortcuts(dest, user, typem)
9
10
  save_stats(__method__)
@@ -28,7 +29,7 @@ class SlackSmartBot
28
29
  end
29
30
  msg2 = ''
30
31
  if @shortcuts.keys.include?(from) and @shortcuts[from].keys.size > 0
31
- new_hash = @shortcuts[from].dup
32
+ new_hash = @shortcuts[from].deep_copy
32
33
  @shortcuts[:all].keys.each { |k| new_hash.delete(k) }
33
34
  if new_hash.keys.size > 0
34
35
  msg2 = "*Available shortcuts for #{from}:*\n"
@@ -38,7 +39,7 @@ class SlackSmartBot
38
39
  end
39
40
  end
40
41
  if @shortcuts_global.keys.include?(from) and @shortcuts_global[from].keys.size > 0
41
- new_hash = @shortcuts_global[from].dup
42
+ new_hash = @shortcuts_global[from].deep_copy
42
43
  @shortcuts_global[:all].keys.each { |k| new_hash.delete(k) }
43
44
  if new_hash.keys.size > 0
44
45
  msg2 = "*Available shortcuts for #{from}:*\n" if msg2 == ''
@@ -4,6 +4,7 @@ class SlackSmartBot
4
4
  # helpmaster: kills the bot on the specified channel
5
5
  # helpmaster: Only works if you are on Master channel and you created that bot or you are an admin user
6
6
  # helpmaster: <https://github.com/MarioRuiz/slack-smart-bot#bot-management|more info>
7
+ # helpmaster: command_id: :kill_bot_on_channel
7
8
  # helpmaster:
8
9
  def kill_bot_on_channel(dest, from, channel)
9
10
  save_stats(__method__)
@@ -20,15 +21,15 @@ class SlackSmartBot
20
21
  respond "There is no channel with that name: #{channel}, please be sure is written exactly the same", dest
21
22
  elsif @bots_created.keys.include?(channel_id)
22
23
  @bots_created[channel_id] ||= {}
23
- if @bots_created[channel_id][:admins].to_s.split(",").include?(from)
24
+ if @bots_created[channel_id][:admins].to_s.split(",").include?(from) # todo: consider adding is_admin?
24
25
  if @bots_created[channel_id][:thread].kind_of?(Thread) and @bots_created[channel_id][:thread].alive?
25
26
  @bots_created[channel_id][:thread].kill
26
27
  end
27
28
  @bots_created.delete(channel_id)
28
- update_bots_file()
29
- respond "Bot on channel: #{channel}, has been killed and deleted.", dest
30
29
  send_msg_channel(channel, "Bot has been killed by #{from}")
31
- save_status :off, :killed, "The admin killed SmartBot on *<##{channel_id}|#{@channels_name[channel_id]}>*"
30
+ respond "Bot on channel: #{channel}, has been killed and deleted.", dest
31
+ save_status :off, :killed, "The admin killed SmartBot on *##{@channels_name[channel_id]}*"
32
+ update_bots_file()
32
33
  else
33
34
  respond "You need to be the creator or an admin of that bot channel", dest
34
35
  end
@@ -7,11 +7,12 @@ class SlackSmartBot
7
7
  # helpadmin: The bot stops running and also stops all the bots created from this master channel
8
8
  # helpadmin: You can use this command only if you are an admin user and you are on the master channel
9
9
  # helpadmin: <https://github.com/MarioRuiz/slack-smart-bot#bot-management|more info>
10
+ # helpadmin: command_id: :exit_bot
10
11
  # helpadmin:
11
12
  def exit_bot(command, from, dest, display_name)
12
13
  save_stats(__method__)
13
14
  if config.on_master_bot
14
- if config.admins.include?(from) #admin user
15
+ if config.masters.include?(from) #admin user
15
16
  if answer.empty?
16
17
  ask("are you sure?", command, from, dest)
17
18
  else
@@ -22,7 +23,7 @@ class SlackSmartBot
22
23
  @bots_created.each { |key, value|
23
24
  value[:thread] = ""
24
25
  send_msg_channel(key, "Bot has been closed by #{from}")
25
- save_status :off, :exited, "The admin closed SmartBot on *<##{key}|#{value.channel_name}>*"
26
+ save_status :off, :exited, "The admin closed SmartBot on *##{value.channel_name}*"
26
27
  sleep 0.5
27
28
  }
28
29
  update_bots_file()
@@ -8,11 +8,12 @@ class SlackSmartBot
8
8
  # helpmaster: It will send a notification message to the specified channel and to its extended channels
9
9
  # helpmaster: Only works if you are on Master channel and you are a master admin user
10
10
  # helpmaster: <https://github.com/MarioRuiz/slack-smart-bot#sending-notifications|more info>
11
+ # helpmaster: command_id: :notify_message
11
12
  # helpmaster:
12
13
  def notify_message(dest, from, where, message)
13
14
  save_stats(__method__)
14
15
  if config.on_master_bot
15
- if config.admins.include?(from) #admin user
16
+ if config.masters.include?(from) #admin user
16
17
  if where.nil? #not all and not channel
17
18
  @bots_created.each do |k, v|
18
19
  respond message, k
@@ -6,17 +6,18 @@ class SlackSmartBot
6
6
  # helpmaster: The messages stored on a DM won't be published.
7
7
  # helpmaster: This is very convenient to be called from a *Routine* for example every weekday at 09:00.
8
8
  # helpmaster: <https://github.com/MarioRuiz/slack-smart-bot#announcements|more info>
9
+ # helpmaster: command_id: :publish_announcements
9
10
  # helpmaster:
10
11
  def publish_announcements(user)
11
12
  save_stats(__method__)
12
13
  if config.on_master_bot
13
- if config.admins.include?(user.name) #admin user
14
+ if config.masters.include?(user.name) #admin user
14
15
  channels = Dir.entries("#{config.path}/announcements/")
15
16
  channels.select! {|i| i[/\.csv$/]}
16
17
  channels.each do |channel|
17
18
  channel.gsub!('.csv','')
18
19
  unless channel[0]== 'D'
19
- see_announcements(user, '', channel, true, true)
20
+ see_announcements(user, '', channel, false, true)
20
21
  sleep 0.5 # to avoid reach ratelimit
21
22
  end
22
23
  end
@@ -11,11 +11,12 @@ class SlackSmartBot
11
11
  # helpmaster: _set general message `We will be on *maintenance* at *12:00*`_
12
12
  # helpmaster: _set general message `:information_source: Pay attention: We will be on *maintenance* in *#{((Time.new(2021,6,18,13,30,0)-Time.now)/60).to_i} minutes*`_
13
13
  # helpmaster: <https://github.com/MarioRuiz/slack-smart-bot#bot-management|more info>
14
+ # helpmaster: command_id: :set_general_message
14
15
  # helpmaster:
15
16
  def set_general_message(from, status, message)
16
17
  save_stats(__method__)
17
18
  if config.on_master_bot
18
- if config.admins.include?(from) #admin user
19
+ if config.masters.include?(from) #admin user
19
20
  if status == 'on'
20
21
  config.general_message = message
21
22
  respond "General message has been set."
@@ -14,11 +14,12 @@ class SlackSmartBot
14
14
  # helpmaster: _set maintenance on We are on maintenance. We'll be available again in #{((Time.new(2021,6,18,13,30,0)-Time.now)/60).to_i} minutes_
15
15
  # helpmaster: _turn maintenance on `We are on *maintenance* until *12:00*`_
16
16
  # helpmaster: <https://github.com/MarioRuiz/slack-smart-bot#bot-management|more info>
17
+ # helpmaster: command_id: :set_maintenance
17
18
  # helpmaster:
18
19
  def set_maintenance(from, status, message)
19
20
  save_stats(__method__)
20
21
  if config.on_master_bot
21
- if config.admins.include?(from) #admin user
22
+ if config.masters.include?(from) #admin user
22
23
  if message == ''
23
24
  config.on_maintenance_message = "Sorry I'm on maintenance so I cannot attend your request."
24
25
  else
@@ -9,6 +9,7 @@ class SlackSmartBot
9
9
  # helpmaster: Follow the instructions in case creating cloud bots
10
10
  # helpmaster: In case 'silent' won't display the Bot initialization message on the CHANNEL_NAME
11
11
  # helpmaster: <https://github.com/MarioRuiz/slack-smart-bot#bot-management|more info>
12
+ # helpmaster: command_id: :create_bot
12
13
  # helpmaster:
13
14
  def create_bot(dest, user, type, channel)
14
15
  cloud = type.include?('cloud')
@@ -0,0 +1,41 @@
1
+ class SlackSmartBot
2
+ # helpmaster: ----------------------------------------------
3
+ # helpmaster: `where is smartbot?`
4
+ # helpmaster: `which channels smartbot?`
5
+ # helpmaster: `where is a member smartbot?`
6
+ # helpmaster: It will list all channels where the smartbot is a member.
7
+ # helpmaster: command_id: :where_smartbot
8
+ # helpmaster:
9
+ def where_smartbot(user)
10
+ #todo: add tests
11
+ save_stats(__method__)
12
+ if has_access?(__method__, user)
13
+ channels = get_channels(bot_is_in: true)
14
+ message = []
15
+ extended = @bots_created.values.extended.flatten
16
+ channels.each do |c|
17
+ type = ''
18
+ unless c.id[0] == "D"
19
+ if @bots_created.key?(c.id)
20
+ type = '_`(SmartBot)`_'
21
+ elsif c.id == @master_bot_id
22
+ type = '_`(Master)`_'
23
+ elsif extended.include?(c.name)
24
+ @bots_created.each do |bot,values|
25
+ if values.extended.include?(c.name)
26
+ type += "_`(Extended from ##{values.channel_name})`_ "
27
+ end
28
+ end
29
+ end
30
+ if c.is_private?
31
+ message << "#{c.id}: *##{c.name}* #{type}"
32
+ else
33
+ message << "#{c.id}: *<##{c.id}>* #{type}"
34
+ end
35
+ end
36
+ end
37
+ message.sort!
38
+ respond "*<@#{config.nick_id}> is a member of:*\n\n#{message.join("\n")}"
39
+ end
40
+ end
41
+ end
@@ -1,20 +1,21 @@
1
- require_relative "commands/general/whats_new"
2
1
  require_relative "commands/general/hi_bot"
3
2
  require_relative "commands/general/bye_bot"
4
3
  require_relative "commands/general/bot_help"
5
- require_relative "commands/general/suggest_command"
4
+ require_relative "commands/on_bot/general/suggest_command"
6
5
  require_relative "commands/on_bot/ruby_code"
7
6
  require_relative "commands/on_bot/repl"
8
7
  require_relative "commands/on_bot/get_repl"
9
8
  require_relative "commands/on_bot/run_repl"
10
9
  require_relative "commands/on_bot/delete_repl"
11
10
  require_relative "commands/on_bot/see_repls"
12
- require_relative "commands/general/use_rules"
13
- require_relative "commands/general/stop_using_rules"
11
+ require_relative "commands/on_bot/general/whats_new"
12
+ require_relative "commands/on_bot/general/use_rules"
13
+ require_relative "commands/on_bot/general/stop_using_rules"
14
14
  require_relative "commands/on_master/admin_master/exit_bot"
15
15
  require_relative "commands/on_master/admin_master/notify_message"
16
16
  require_relative "commands/on_master/admin/kill_bot_on_channel"
17
17
  require_relative "commands/on_master/create_bot"
18
+ require_relative "commands/on_master/where_smartbot"
18
19
  require_relative "commands/on_bot/admin/add_routine"
19
20
  require_relative "commands/on_bot/admin/start_bot"
20
21
  require_relative "commands/on_bot/admin/pause_bot"
@@ -26,16 +27,17 @@ require_relative "commands/on_bot/admin/start_routine"
26
27
  require_relative "commands/on_bot/admin/see_routines"
27
28
  require_relative "commands/on_bot/admin/extend_rules"
28
29
  require_relative "commands/on_bot/admin/stop_using_rules_on"
29
- require_relative "commands/general/bot_status"
30
+ require_relative "commands/on_bot/general/bot_status"
30
31
  require_relative "commands/on_bot/add_shortcut"
31
32
  require_relative "commands/on_bot/delete_shortcut"
32
33
  require_relative "commands/on_bot/see_shortcuts"
33
34
  require_relative "commands/on_extended/bot_rules"
34
35
  require_relative "commands/on_bot/admin_master/get_bot_logs"
35
36
  require_relative "commands/on_bot/admin_master/send_message"
37
+ require_relative "commands/on_bot/admin_master/delete_message"
36
38
  require_relative "commands/on_bot/admin_master/react_to"
37
- require_relative "commands/general/bot_stats"
38
- require_relative "commands/general/leaderboard"
39
+ require_relative "commands/on_bot/general/bot_stats"
40
+ require_relative "commands/on_bot/general/leaderboard"
39
41
  require_relative "commands/general/add_announcement"
40
42
  require_relative "commands/general/delete_announcement"
41
43
  require_relative "commands/general/see_announcements"
@@ -48,3 +50,16 @@ require_relative "commands/general_bot_commands"
48
50
  require_relative "commands/general/share_messages"
49
51
  require_relative "commands/general/see_shares"
50
52
  require_relative "commands/general/delete_share"
53
+ require_relative "commands/general/see_admins"
54
+ require_relative "commands/general/add_admin"
55
+ require_relative "commands/general/remove_admin"
56
+ require_relative "commands/general/see_command_ids"
57
+ require_relative "commands/general/poster"
58
+ require_relative "commands/general/see_access"
59
+ require_relative "commands/general/allow_access"
60
+ require_relative "commands/general/deny_access"
61
+ require_relative "commands/general/add_team"
62
+ require_relative "commands/general/see_teams"
63
+ require_relative "commands/general/update_team"
64
+ require_relative "commands/general/ping_team"
65
+ require_relative "commands/general/delete_team"
@@ -4,39 +4,39 @@ class SlackSmartBot
4
4
  @pings = []
5
5
  @last_activity_check = Time.now
6
6
  get_bots_created()
7
- @buffer_complete = [] unless defined?(@buffer_complete)
8
- b = File.read("#{config.path}/buffer_complete.log")
9
- result = b.scan(/^\|(\w+)\|(\w+)\|(\w+)\|([^~]+)~~~/m)
10
- result.delete(nil)
11
- new_messages = result[@buffer_complete.size..-1]
12
- unless new_messages.nil? or new_messages.empty?
13
- @buffer_complete = result
14
- new_messages.each do |message|
15
- channel = message[0].strip
16
- user = message[1].strip
17
- user_name = message[2].strip
18
- command = message[3].to_s.strip
19
- # take in consideration that on simulation we are treating all messages even those that are not populated on real cases like when the message is not populated to the specific bot connection when message is sent with the bot
20
- @logger.info "treat message: #{message}" if config.testing
21
- if command.match?(/^\s*\-!!/) or command.match?(/^\s*\-\^/)
22
- command.scan(/`([^`]+)`/).flatten.each do |cmd|
23
- if cmd.to_s!=''
24
- cmd = "^#{cmd}"
25
- treat_message({channel: channel, user: user, text: cmd, user_name: user_name}, false)
26
- end
7
+ @buffer_complete = [] unless defined?(@buffer_complete)
8
+ b = File.read("#{config.path}/buffer_complete.log")
9
+ result = b.scan(/^\|(\w+)\|(\w+)\|(\w+)\|([^~]+)~~~/m)
10
+ result.delete(nil)
11
+ new_messages = result[@buffer_complete.size..-1]
12
+ unless new_messages.nil? or new_messages.empty?
13
+ @buffer_complete = result
14
+ new_messages.each do |message|
15
+ channel = message[0].strip
16
+ user = message[1].strip
17
+ user_name = message[2].strip
18
+ command = message[3].to_s.strip
19
+ # take in consideration that on simulation we are treating all messages even those that are not populated on real cases like when the message is not populated to the specific bot connection when message is sent with the bot
20
+ @logger.info "treat message: #{message}" if config.testing
21
+ if command.match?(/^\s*\-!!/) or command.match?(/^\s*\-\^/)
22
+ command.scan(/`([^`]+)`/).flatten.each do |cmd|
23
+ if cmd.to_s != ""
24
+ cmd = "^#{cmd}"
25
+ treat_message({ channel: channel, user: user, text: cmd, user_name: user_name }, false)
27
26
  end
28
- elsif command.match?(/^\s*\-!/)
29
- command.scan(/`([^`]+)`/).flatten.each do |cmd|
30
- if cmd.to_s!=''
31
- cmd = "!#{cmd}"
32
- treat_message({channel: channel, user: user, text: cmd, user_name: user_name}, false)
33
- end
27
+ end
28
+ elsif command.match?(/^\s*\-!/)
29
+ command.scan(/`([^`]+)`/).flatten.each do |cmd|
30
+ if cmd.to_s != ""
31
+ cmd = "!#{cmd}"
32
+ treat_message({ channel: channel, user: user, text: cmd, user_name: user_name }, false)
34
33
  end
35
- else
36
- treat_message({channel: channel, user: user, text: command, user_name: user_name})
37
34
  end
35
+ else
36
+ treat_message({ channel: channel, user: user, text: command, user_name: user_name })
38
37
  end
39
38
  end
39
+ end
40
40
  end
41
41
 
42
42
  def listen
@@ -48,7 +48,7 @@ class SlackSmartBot
48
48
  unless data.user == "USLACKBOT" or data.text.nil?
49
49
  if data.text.match?(/^\s*\-!!/) or data.text.match?(/^\s*\-\^/)
50
50
  data.text.scan(/`([^`]+)`/).flatten.each do |cmd|
51
- if cmd.to_s!=''
51
+ if cmd.to_s != ""
52
52
  datao = data.dup
53
53
  datao.text = "^#{cmd}"
54
54
  treat_message(datao, false)
@@ -56,7 +56,7 @@ class SlackSmartBot
56
56
  end
57
57
  elsif data.text.match?(/^\s*\-!/)
58
58
  data.text.scan(/`([^`]+)`/).flatten.each do |cmd|
59
- if cmd.to_s!=''
59
+ if cmd.to_s != ""
60
60
  datao = data.dup
61
61
  datao.text = "!#{cmd}"
62
62
  treat_message(datao, false)