slack-smart-bot 1.7.0 → 1.9.1

Sign up to get free protection for your applications and to get access to all the features.
Files changed (61) hide show
  1. checksums.yaml +4 -4
  2. data/README.md +24 -12
  3. data/lib/slack-smart-bot.rb +52 -43
  4. data/lib/slack-smart-bot_general_rules.rb +7 -4
  5. data/lib/slack-smart-bot_rules.rb +8 -6
  6. data/lib/slack/smart-bot/comm.rb +6 -1
  7. data/lib/slack/smart-bot/comm/ask.rb +12 -5
  8. data/lib/slack/smart-bot/comm/dont_understand.rb +1 -1
  9. data/lib/slack/smart-bot/comm/event_hello.rb +30 -0
  10. data/lib/slack/smart-bot/comm/get_channel_members.rb +8 -0
  11. data/lib/slack/smart-bot/comm/get_channels.rb +20 -0
  12. data/lib/slack/smart-bot/comm/get_user_info.rb +16 -0
  13. data/lib/slack/smart-bot/comm/react.rb +21 -8
  14. data/lib/slack/smart-bot/comm/respond.rb +11 -6
  15. data/lib/slack/smart-bot/comm/send_file.rb +1 -1
  16. data/lib/slack/smart-bot/comm/send_msg_channel.rb +2 -2
  17. data/lib/slack/smart-bot/comm/send_msg_user.rb +4 -4
  18. data/lib/slack/smart-bot/comm/unreact.rb +29 -0
  19. data/lib/slack/smart-bot/commands.rb +3 -1
  20. data/lib/slack/smart-bot/commands/general/bot_help.rb +16 -3
  21. data/lib/slack/smart-bot/commands/general/bot_stats.rb +313 -0
  22. data/lib/slack/smart-bot/commands/general/bot_status.rb +1 -1
  23. data/lib/slack/smart-bot/commands/general/bye_bot.rb +1 -1
  24. data/lib/slack/smart-bot/commands/general/hi_bot.rb +1 -1
  25. data/lib/slack/smart-bot/commands/general/use_rules.rb +2 -6
  26. data/lib/slack/smart-bot/commands/general/whats_new.rb +19 -0
  27. data/lib/slack/smart-bot/commands/on_bot/add_shortcut.rb +65 -33
  28. data/lib/slack/smart-bot/commands/on_bot/admin/add_routine.rb +33 -9
  29. data/lib/slack/smart-bot/commands/on_bot/admin/extend_rules.rb +3 -7
  30. data/lib/slack/smart-bot/commands/on_bot/admin/pause_bot.rb +1 -0
  31. data/lib/slack/smart-bot/commands/on_bot/admin/see_routines.rb +9 -2
  32. data/lib/slack/smart-bot/commands/on_bot/admin/start_bot.rb +1 -0
  33. data/lib/slack/smart-bot/commands/on_bot/delete_repl.rb +1 -1
  34. data/lib/slack/smart-bot/commands/on_bot/delete_shortcut.rb +52 -21
  35. data/lib/slack/smart-bot/commands/on_bot/get_repl.rb +5 -5
  36. data/lib/slack/smart-bot/commands/on_bot/repl.rb +50 -18
  37. data/lib/slack/smart-bot/commands/on_bot/ruby_code.rb +34 -9
  38. data/lib/slack/smart-bot/commands/on_bot/run_repl.rb +2 -3
  39. data/lib/slack/smart-bot/commands/on_bot/see_repls.rb +1 -1
  40. data/lib/slack/smart-bot/commands/on_bot/see_shortcuts.rb +27 -9
  41. data/lib/slack/smart-bot/commands/on_extended/bot_rules.rb +14 -1
  42. data/lib/slack/smart-bot/commands/on_master/admin_master/exit_bot.rb +3 -3
  43. data/lib/slack/smart-bot/commands/on_master/admin_master/notify_message.rb +1 -1
  44. data/lib/slack/smart-bot/commands/on_master/admin_master/set_maintenance.rb +41 -0
  45. data/lib/slack/smart-bot/commands/on_master/create_bot.rb +4 -8
  46. data/lib/slack/smart-bot/listen.rb +6 -5
  47. data/lib/slack/smart-bot/process.rb +227 -186
  48. data/lib/slack/smart-bot/process_first.rb +104 -87
  49. data/lib/slack/smart-bot/treat_message.rb +116 -52
  50. data/lib/slack/smart-bot/utils.rb +2 -0
  51. data/lib/slack/smart-bot/utils/answer.rb +18 -0
  52. data/lib/slack/smart-bot/utils/answer_delete.rb +15 -0
  53. data/lib/slack/smart-bot/utils/build_help.rb +57 -5
  54. data/lib/slack/smart-bot/utils/create_routine_thread.rb +48 -8
  55. data/lib/slack/smart-bot/utils/get_channels_name_and_id.rb +1 -7
  56. data/lib/slack/smart-bot/utils/get_help.rb +79 -17
  57. data/lib/slack/smart-bot/utils/save_stats.rb +21 -8
  58. data/lib/slack/smart-bot/utils/update_shortcuts_file.rb +6 -0
  59. data/whats_new.txt +18 -0
  60. metadata +22 -12
  61. data/lib/slack/smart-bot/commands/on_bot/admin_master/bot_stats.rb +0 -135
@@ -3,7 +3,6 @@ class SlackSmartBot
3
3
  # help: `get repl SESSION_NAME`
4
4
  # help: `get irb SESSION_NAME`
5
5
  # help: `get live SESSION_NAME`
6
- # help:
7
6
  # help: Will get the Ruby commands sent on that SESSION_NAME.
8
7
  # help:
9
8
  def get_repl(dest, user, session_name)
@@ -16,22 +15,23 @@ class SlackSmartBot
16
15
  Dir.mkdir("#{config.path}/repl") unless Dir.exist?("#{config.path}/repl")
17
16
  Dir.mkdir("#{config.path}/repl/#{@channel_id}") unless Dir.exist?("#{config.path}/repl/#{@channel_id}")
18
17
  if File.exist?("#{config.path}/repl/#{@channel_id}/#{session_name}.run")
19
- if @repls.key?(session_name) and @repls[session_name][:type] == :private and
18
+ if @repls.key?(session_name) and (@repls[session_name][:type] == :private or @repls[session_name][:type] == :private_clean) and
20
19
  @repls[session_name][:creator_name]!=user.name and
21
20
  !config.admins.include?(user.name)
22
21
  respond "The REPL with session name: #{session_name} is private", dest
23
22
  else
23
+ content = "require 'nice_http'\n"
24
24
  if @repls.key?(session_name)
25
25
  @repls[session_name][:accessed] = Time.now.to_s
26
26
  @repls[session_name][:gets] += 1
27
27
  update_repls()
28
28
  end
29
-
30
- content = "require 'nice_http'\n"
31
- if File.exist?("#{project_folder}/.smart-bot-repl")
29
+ if !@repls.key?(session_name) or
30
+ (File.exist?("#{project_folder}/.smart-bot-repl") and @repls[session_name][:type] != :private_clean and @repls[session_name][:type] != :public_clean)
32
31
  content += File.read("#{project_folder}/.smart-bot-repl")
33
32
  content += "\n"
34
33
  end
34
+
35
35
  content += File.read("#{config.path}/repl/#{@channel_id}/#{session_name}.run").gsub(/^(quit|exit|bye)$/i,'') #todo: remove this gsub it will never contain it
36
36
  File.write("#{config.path}/repl/#{@channel_id}/#{session_name}.rb", content, mode: "w+")
37
37
  send_file(dest, "REPL #{session_name} on #{config.channel}", "#{config.path}/repl/#{@channel_id}/#{session_name}.rb", " REPL #{session_name} on #{config.channel}", 'text/plain', "ruby")
@@ -5,15 +5,16 @@ class SlackSmartBot
5
5
  # help: `irb`
6
6
  # help: `repl SESSION_NAME`
7
7
  # help: `private repl SESSION_NAME`
8
+ # help: `clean repl SESSION_NAME`
8
9
  # help: `repl ENV_VAR=VALUE`
9
10
  # help: `repl SESSION_NAME ENV_VAR=VALUE ENV_VAR='VALUE'`
10
11
  # help: `repl SESSION_NAME: "DESCRIPTION"`
11
12
  # help: `repl SESSION_NAME: "DESCRIPTION" ENV_VAR=VALUE ENV_VAR='VALUE'`
12
- # help:
13
13
  # help: Will run all we write as a ruby command and will keep the session values.
14
14
  # help: SESSION_NAME only admits from a to Z, numbers, - and _
15
15
  # help: If no SESSION_NAME supplied it will be treated as a temporary REPL
16
16
  # help: If 'private' specified the repl will be accessible only by you and it will be displayed only to you when `see repls`
17
+ # help: If 'clean' specified the repl won't pre execute the code written on the .smart-bot-repl file
17
18
  # help: To avoid a message to be treated, start the message with '-'.
18
19
  # help: Send _quit_, _bye_ or _exit_ to finish the session.
19
20
  # help: Send puts, print, p or pp if you want to print out something when using `run repl` later.
@@ -78,7 +79,13 @@ class SlackSmartBot
78
79
  }
79
80
  update_repls()
80
81
  end
81
-
82
+ react :running
83
+ if Thread.current[:ts].to_s == ''
84
+ @ts_react = Thread.current[:thread_ts]
85
+ else
86
+ @ts_react = Thread.current[:ts]
87
+ end
88
+
82
89
  message = "Session name: *#{session_name}*
83
90
  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`.
84
91
  I will respond with the result so it is not necessary you send `print`, `puts`, `p` or `pp` unless you want it as the output when calling `run repl`.
@@ -96,6 +103,19 @@ class SlackSmartBot
96
103
  File.write("#{config.path}/repl/#{@channel_id}/#{@repl_sessions[from][:name]}.output", "", mode: "a+")
97
104
  File.write("#{config.path}/repl/#{@channel_id}/#{@repl_sessions[from][:name]}.run", "", mode: "a+")
98
105
 
106
+ if type != :private_clean and type != :public_clean
107
+ pre_execute = '
108
+ if File.exist?(\"./.smart-bot-repl\")
109
+ begin
110
+ eval(File.read(\"./.smart-bot-repl\"), bindme' + serialt + ')
111
+ rescue Exception => resp_repl
112
+ end
113
+ end
114
+ '
115
+ else
116
+ pre_execute = ''
117
+ end
118
+
99
119
  process_to_run = '
100
120
  ruby -e "' + env_vars.join("\n") + '
101
121
  require \"amazing_print\"
@@ -105,17 +125,12 @@ class SlackSmartBot
105
125
  (obj.methods - Object.methods)
106
126
  end
107
127
 
108
- file_input_repl = File.open(\"' + Dir.pwd + '/repl/' + @channel_id + '/' + session_name + '.input\", \"r\")
109
- if File.exist?(\"./.smart-bot-repl\")
110
- begin
111
- eval(File.read(\"./.smart-bot-repl\"), bindme' + serialt + ')
112
- rescue Exception => resp_repl
113
- end
114
- end
128
+ file_input_repl = File.open(\"' + File.expand_path(config.path) + '/repl/' + @channel_id + '/' + session_name + '.input\", \"r\")
129
+ ' + pre_execute + '
115
130
  while true do
116
131
  sleep 0.2
117
132
  code_to_run_repl = file_input_repl.read
118
- if code_to_run_repl.to_s!=''
133
+ if code_to_run_repl.to_s!=\"\"
119
134
  add_to_run_repl = true
120
135
  if code_to_run_repl.to_s.match?(/^quit$/i) or
121
136
  code_to_run_repl.to_s.match?(/^exit$/i) or
@@ -134,16 +149,16 @@ class SlackSmartBot
134
149
  end
135
150
  if resp_repl.to_s != \"\"
136
151
  if code_to_run_repl.match?(/^\s*p\s+/i)
137
- open(\"' + Dir.pwd + '/repl/' + @channel_id + '/' + session_name + '.output\", \"a+\") {|f|
152
+ open(\"' + File.expand_path(config.path) + '/repl/' + @channel_id + '/' + session_name + '.output\", \"a+\") {|f|
138
153
  f.puts \"\`\`\`\n#{resp_repl.inspect}\n\`\`\`\"
139
154
  }
140
155
  else
141
- open(\"' + Dir.pwd + '/repl/' + @channel_id + '/' + session_name + '.output\", \"a+\") {|f|
156
+ open(\"' + File.expand_path(config.path) + '/repl/' + @channel_id + '/' + session_name + '.output\", \"a+\") {|f|
142
157
  f.puts \"\`\`\`\n#{resp_repl.ai}\n\`\`\`\"
143
158
  }
144
159
  end
145
160
  unless error or !add_to_run_repl
146
- open(\"' + Dir.pwd + '/repl/' + @channel_id + '/' + session_name + '.run\", \"a+\") {|f|
161
+ open(\"' + File.expand_path(config.path) + '/repl/' + @channel_id + '/' + session_name + '.run\", \"a+\") {|f|
147
162
  f.puts code_to_run_repl
148
163
  }
149
164
  end
@@ -152,7 +167,6 @@ class SlackSmartBot
152
167
  end
153
168
  end"
154
169
  '
155
-
156
170
  unless rules_file.empty? # to get the project_folder
157
171
  begin
158
172
  eval(File.new(config.path+rules_file).read) if File.exist?(config.path+rules_file)
@@ -160,12 +174,12 @@ class SlackSmartBot
160
174
  end
161
175
  started = Time.now
162
176
  process_to_run = ("cd #{project_folder} &&" + process_to_run) if defined?(project_folder)
163
-
177
+
164
178
  stdin, stdout, stderr, wait_thr = Open3.popen3(process_to_run)
165
179
  timeout = 30 * 60 # 30 minutes
166
180
 
167
181
  file_output_repl = File.open("#{config.path}/repl/#{@channel_id}/#{session_name}.output", "r")
168
-
182
+ @repl_sessions[from][:pid] = wait_thr.pid
169
183
  while (wait_thr.status == 'run' or wait_thr.status == 'sleep') and @repl_sessions.key?(from)
170
184
  begin
171
185
  if (Time.now-@repl_sessions[from][:finished]) > timeout
@@ -173,6 +187,14 @@ class SlackSmartBot
173
187
  f.puts 'quit'
174
188
  }
175
189
  respond "REPL session finished: #{@repl_sessions[from][:name]}", dest
190
+ unreact :running, @ts_react
191
+ pids = `pgrep -P #{@repl_sessions[from][:pid]}`.split("\n").map(&:to_i) #todo: it needs to be adapted for Windows
192
+ pids.each do |pid|
193
+ begin
194
+ Process.kill("KILL", pid)
195
+ rescue
196
+ end
197
+ end
176
198
  @repl_sessions.delete(from)
177
199
  break
178
200
  end
@@ -199,10 +221,12 @@ class SlackSmartBot
199
221
  code.gsub!("\\r", "\r")
200
222
  # Disabled for the moment since it is deleting lines with '}'
201
223
  #code.gsub!(/^\W*$/, "") #to remove special chars from slack when copy/pasting.
202
- if code.match?(/System/i) or code.match?(/Kernel/i) or code.include?("File") or
224
+ if code.match?(/System/i) or code.match?(/Kernel/i) or code.include?("File.") or
203
225
  code.include?("`") or code.include?("exec") or code.include?("spawn") or code.include?("IO.") or
204
226
  code.match?(/open3/i) or code.match?(/bundle/i) or code.match?(/gemfile/i) or code.include?("%x") or
205
- code.include?("ENV") or code.match?(/=\s*IO/)
227
+ code.include?("ENV") or code.match?(/=\s*IO/) or code.include?("Dir.") or
228
+ code.match?(/=\s*File/) or code.match?(/=\s*Dir/) or code.match?(/<\s*File/) or code.match?(/<\s*Dir/) or
229
+ code.match?(/\w+:\s*File/) or code.match?(/\w+:\s*Dir/)
206
230
  respond "Sorry I cannot run this due security reasons", dest
207
231
  else
208
232
  @repl_sessions[from][:input]<<code
@@ -212,6 +236,14 @@ class SlackSmartBot
212
236
  f.puts code
213
237
  }
214
238
  respond "REPL session finished: #{@repl_sessions[from][:name]}", dest
239
+ unreact :running, @ts_react
240
+ pids = `pgrep -P #{@repl_sessions[from][:pid]}`.split("\n").map(&:to_i) #todo: it needs to be adapted for Windows
241
+ pids.each do |pid|
242
+ begin
243
+ Process.kill("KILL", pid)
244
+ rescue
245
+ end
246
+ end
215
247
  @repl_sessions.delete(from)
216
248
  when /^\s*-/i
217
249
  #ommit
@@ -13,39 +13,64 @@ class SlackSmartBot
13
13
  (!user.key?(:enterprise_user) or ( user.key?(:enterprise_user) and !config[:allow_access][__method__].include?(user[:enterprise_user].id)))
14
14
  respond "You don't have access to use this command, please contact an Admin to be able to use it: <@#{config.admins.join(">, <@")}>"
15
15
  else
16
- unless code.match?(/System/i) or code.match?(/Kernel/i) or code.include?("File") or
16
+ unless code.match?(/System/i) or code.match?(/Kernel/i) or code.include?("File.") or
17
17
  code.include?("`") or code.include?("exec") or code.include?("spawn") or code.include?("IO.") or
18
18
  code.match?(/open3/i) or code.match?(/bundle/i) or code.match?(/gemfile/i) or code.include?("%x") or
19
- code.include?("ENV") or code.match?(/=\s*IO/)
19
+ code.include?("ENV") or code.match?(/=\s*IO/) or code.include?("Dir.") or code.match?(/=\s*IO/) or
20
+ code.match?(/=\s*File/) or code.match?(/=\s*Dir/) or code.match?(/<\s*File/) or code.match?(/<\s*Dir/) or
21
+ code.match?(/\w+:\s*File/) or code.match?(/\w+:\s*Dir/)
22
+ react :running
20
23
  unless rules_file.empty?
21
24
  begin
22
25
  eval(File.new(config.path+rules_file).read) if File.exist?(config.path+rules_file)
23
26
  end
24
27
  end
25
28
 
26
- respond "Running", dest if code.size > 100
29
+ respond "Running", dest if code.size > 200
27
30
 
28
31
  begin
29
32
  code.gsub!(/^\W*$/, "") #to remove special chars from slack when copy/pasting
33
+ code.gsub!('$','\$') #to take $ as literal, fex: puts '$lolo' => puts '\$lolo'
30
34
  ruby = "ruby -e \"#{code.gsub('"', '\"')}\""
31
35
  if defined?(project_folder) and project_folder.to_s != "" and Dir.exist?(project_folder)
32
36
  ruby = ("cd #{project_folder} &&" + ruby)
33
37
  else
34
38
  def project_folder() "" end
35
39
  end
36
- stdout, stderr, status = Open3.capture3(ruby)
37
- if stderr == ""
38
- if stdout == ""
39
- respond "Nothing returned. Remember you need to use p or puts to print", dest
40
+
41
+ stdin, stdout, stderr, wait_thr = Open3.popen3(ruby)
42
+ timeout = timeoutt = 20
43
+ procstart = Time.now
44
+ while (wait_thr.status == 'run' or wait_thr.status == 'sleep') and timeout > 0
45
+ timeout -= 0.1
46
+ sleep 0.1
47
+ end
48
+ if timeout > 0
49
+ stdout = stdout.read
50
+ stderr = stderr.read
51
+ if stderr == ""
52
+ if stdout == ""
53
+ respond "Nothing returned. Remember you need to use p or puts to print", dest
54
+ else
55
+ respond stdout, dest
56
+ end
40
57
  else
41
- respond stdout, dest
58
+ respond "#{stderr}\n#{stdout}", dest
42
59
  end
43
60
  else
44
- respond "#{stderr}\n#{stdout}", dest
61
+ respond "The process didn't finish in #{timeoutt} secs so it was aborted. Timeout!"
62
+ pids = `pgrep -P #{wait_thr.pid}`.split("\n").map(&:to_i) #todo: it needs to be adapted for Windows
63
+ pids.each do |pid|
64
+ begin
65
+ Process.kill("KILL", pid)
66
+ rescue
67
+ end
68
+ end
45
69
  end
46
70
  rescue Exception => exc
47
71
  respond exc, dest
48
72
  end
73
+ unreact :running
49
74
  else
50
75
  respond "Sorry I cannot run this due security reasons", dest
51
76
  end
@@ -4,7 +4,6 @@ class SlackSmartBot
4
4
  # help: `run repl SESSION_NAME ENV_VAR=VALUE ENV_VAR=VALUE`
5
5
  # help: `run live SESSION_NAME`
6
6
  # help: `run irb SESSION_NAME`
7
- # help:
8
7
  # help: Will run the repl session specified and return the output.
9
8
  # help: You can supply the Environmental Variables you need for the Session
10
9
  # help: It will return only the values that were print out on the repl with puts, print, p or pp
@@ -22,7 +21,7 @@ class SlackSmartBot
22
21
  Dir.mkdir("#{config.path}/repl") unless Dir.exist?("#{config.path}/repl")
23
22
  Dir.mkdir("#{config.path}/repl/#{@channel_id}") unless Dir.exist?("#{config.path}/repl/#{@channel_id}")
24
23
  if File.exist?("#{config.path}/repl/#{@channel_id}/#{session_name}.run")
25
- if @repls.key?(session_name) and @repls[session_name][:type] == :private and
24
+ if @repls.key?(session_name) and (@repls[session_name][:type] == :private or @repls[session_name][:type] == :private_clean) and
26
25
  @repls[session_name][:creator_name]!=user.name and
27
26
  !config.admins.include?(user.name)
28
27
  respond "The REPL with session name: #{session_name} is private", dest
@@ -44,7 +43,7 @@ class SlackSmartBot
44
43
  eval(File.new(config.path+rules_file).read) if File.exist?(config.path+rules_file)
45
44
  end
46
45
  end
47
- if File.exist?("#{project_folder}/.smart-bot-repl")
46
+ if File.exist?("#{project_folder}/.smart-bot-repl") and @repls[session_name][:type] != :private_clean and @repls[session_name][:type] != :public_clean
48
47
  content += File.read("#{project_folder}/.smart-bot-repl")
49
48
  content += "\n"
50
49
  end
@@ -14,7 +14,7 @@ class SlackSmartBot
14
14
  else
15
15
  message = ""
16
16
  @repls.sort.to_h.each do |session_name, repl|
17
- if (repl.creator_name == user.name or repl.type == :public) or (config.admins.include?(user.name) and typem == :on_dm)
17
+ 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)
18
18
  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"
19
19
  end
20
20
  end
@@ -13,26 +13,44 @@ class SlackSmartBot
13
13
  else
14
14
  unless typem == :on_extended
15
15
  msg = ""
16
- if @shortcuts[:all].keys.size > 0
16
+ if @shortcuts[:all].keys.size > 0 or @shortcuts_global[:all].keys.size > 0
17
17
  msg = "*Available shortcuts for all:*\n"
18
- @shortcuts[:all].each { |name, value|
19
- msg += " _#{name}: #{value}_\n"
20
- }
18
+
19
+ if @shortcuts[:all].keys.size > 0
20
+ @shortcuts[:all].each { |name, value|
21
+ msg += " _#{name}: #{value}_\n"
22
+ }
23
+ end
24
+ if @shortcuts_global[:all].keys.size > 0
25
+ @shortcuts_global[:all].each { |name, value|
26
+ msg += " _#{name} (global): #{value}_\n"
27
+ }
28
+ end
21
29
  respond msg, dest
22
30
  end
23
-
31
+ msg2 = ''
24
32
  if @shortcuts.keys.include?(from) and @shortcuts[from].keys.size > 0
25
33
  new_hash = @shortcuts[from].dup
26
34
  @shortcuts[:all].keys.each { |k| new_hash.delete(k) }
27
35
  if new_hash.keys.size > 0
28
- msg = "*Available shortcuts for #{from}:*\n"
36
+ msg2 = "*Available shortcuts for #{from}:*\n"
29
37
  new_hash.each { |name, value|
30
- msg += " _#{name}: #{value}_\n"
38
+ msg2 += " _#{name}: #{value}_\n"
39
+ }
40
+ end
41
+ end
42
+ if @shortcuts_global.keys.include?(from) and @shortcuts_global[from].keys.size > 0
43
+ new_hash = @shortcuts_global[from].dup
44
+ @shortcuts_global[:all].keys.each { |k| new_hash.delete(k) }
45
+ if new_hash.keys.size > 0
46
+ msg2 = "*Available shortcuts for #{from}:*\n" if msg2 == ''
47
+ new_hash.each { |name, value|
48
+ msg2 += " _#{name} (global): #{value}_\n"
31
49
  }
32
- respond msg, dest
33
50
  end
34
51
  end
35
- respond "No shortcuts found", dest if msg == ""
52
+ respond msg2 unless msg2 == ''
53
+ respond "No shortcuts found" if (msg + msg2) == ""
36
54
  end
37
55
  end
38
56
  end
@@ -7,7 +7,15 @@ class SlackSmartBot
7
7
  respond "You don't have access to use this command, please contact an Admin to be able to use it: <@#{config.admins.join(">, <@")}>"
8
8
  else
9
9
  if typem == :on_extended or typem == :on_call #for the other cases above.
10
- help_filtered = get_help(rules_file, dest, from, true)
10
+
11
+ if help_command.to_s != ''
12
+ help_command = '' if help_command.to_s.match?(/^\s*expanded\s*$/i) or help_command.to_s.match?(/^\s*extended\s*$/i)
13
+ expanded = true
14
+ else
15
+ expanded = false
16
+ end
17
+
18
+ help_filtered = get_help(rules_file, dest, from, true, expanded)
11
19
 
12
20
  if help_command.to_s != ""
13
21
  help_found = false
@@ -38,6 +46,11 @@ class SlackSmartBot
38
46
  def git_project() "" end
39
47
  def project_folder() "" end
40
48
  end
49
+ unless expanded
50
+ message_not_expanded = "*If you want to see the expanded version of `bot rules`, please call `bot rules expanded`*\n"
51
+ message_not_expanded += "*Also to get specific expanded help for a specific command or rule call `bot rules COMMAND`*\n"
52
+ respond message_not_expanded
53
+ end
41
54
  end
42
55
  end
43
56
  end
@@ -11,10 +11,10 @@ class SlackSmartBot
11
11
  save_stats(__method__)
12
12
  if config.on_master_bot
13
13
  if config.admins.include?(from) #admin user
14
- unless @questions.keys.include?(from)
14
+ if answer.empty?
15
15
  ask("are you sure?", command, from, dest)
16
16
  else
17
- case @questions[from]
17
+ case answer
18
18
  when /yes/i, /yep/i, /sure/i
19
19
  respond "Game over!", dest
20
20
  respond "Ciao #{display_name}!", dest
@@ -33,7 +33,7 @@ class SlackSmartBot
33
33
  exit!
34
34
  end
35
35
  when /no/i, /nope/i, /cancel/i
36
- @questions.delete(from)
36
+ answer_delete(from)
37
37
  respond "Thanks, I'm happy to be alive", dest
38
38
  else
39
39
  ask("I don't understand, are you sure do you want me to close? (yes or no)", command, from, dest)
@@ -18,7 +18,7 @@ class SlackSmartBot
18
18
  end
19
19
  respond "Bot channels have been notified", dest
20
20
  elsif where == "all" #all
21
- myconv = client.web_client.users_conversations(exclude_archived: true, limit: 100, types: "im, public_channel,private_channel").channels
21
+ myconv = get_channels(bot_is_in: true)
22
22
  myconv.each do |c|
23
23
  respond message, c.id unless c.name == config.master_channel
24
24
  end
@@ -0,0 +1,41 @@
1
+ class SlackSmartBot
2
+ # helpmaster: ----------------------------------------------
3
+ # helpmaster: `set maintenance on`
4
+ # helpmaster: `set maintenance on MESSAGE`
5
+ # helpmaster: `set maintenance off`
6
+ # helpmaster: `turn maintenance on`
7
+ # helpmaster: `turn maintenance on MESSAGE`
8
+ # helpmaster: `turn maintenance off`
9
+ # helpmaster: The SmartBot will be on maintenance and responding with a generic message
10
+ # helpmaster: Only works if you are on Master channel and you are a master admin user
11
+ # helpmaster:
12
+ def set_maintenance(from, status, message)
13
+ save_stats(__method__)
14
+ if config.on_master_bot
15
+ if config.admins.include?(from) #admin user
16
+ if message == ''
17
+ config.on_maintenance_message = "Sorry I'm on maintenance so I cannot attend your request."
18
+ else
19
+ config.on_maintenance_message = message
20
+ end
21
+
22
+ if status == 'on'
23
+ config.on_maintenance = true
24
+ respond "From now on I'll be on maintenance status so I won't be responding accordingly."
25
+ else
26
+ config.on_maintenance = false
27
+ respond "From now on I won't be on maintenance. Everything is back to normal!"
28
+ end
29
+
30
+ file = File.open("#{config.path}/config_tmp.status", "w")
31
+ file.write config.inspect
32
+ file.close
33
+
34
+ else
35
+ respond 'Only master admins on master channel can use this command.'
36
+ end
37
+ else
38
+ respond 'Only master admins on master channel can use this command.'
39
+ end
40
+ end
41
+ end