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.
- checksums.yaml +4 -4
- data/README.md +91 -21
- data/lib/slack/smart-bot/comm/delete.rb +13 -0
- data/lib/slack/smart-bot/comm/dont_understand.rb +2 -2
- data/lib/slack/smart-bot/comm/get_channel_members.rb +7 -3
- data/lib/slack/smart-bot/comm/get_presence.rb +20 -0
- data/lib/slack/smart-bot/comm/get_users.rb +1 -1
- data/lib/slack/smart-bot/comm/respond.rb +18 -13
- data/lib/slack/smart-bot/comm/send_msg_user.rb +12 -11
- data/lib/slack/smart-bot/comm.rb +2 -0
- data/lib/slack/smart-bot/commands/general/add_admin.rb +51 -0
- data/lib/slack/smart-bot/commands/general/add_announcement.rb +1 -1
- data/lib/slack/smart-bot/commands/general/add_team.rb +80 -0
- data/lib/slack/smart-bot/commands/general/allow_access.rb +67 -0
- data/lib/slack/smart-bot/commands/general/bot_help.rb +20 -11
- data/lib/slack/smart-bot/commands/general/delete_announcement.rb +1 -1
- data/lib/slack/smart-bot/commands/general/delete_share.rb +1 -1
- data/lib/slack/smart-bot/commands/general/delete_team.rb +34 -0
- data/lib/slack/smart-bot/commands/general/deny_access.rb +36 -0
- data/lib/slack/smart-bot/commands/general/ping_team.rb +100 -0
- data/lib/slack/smart-bot/commands/general/poster.rb +116 -0
- data/lib/slack/smart-bot/commands/general/remove_admin.rb +58 -0
- data/lib/slack/smart-bot/commands/general/see_access.rb +24 -0
- data/lib/slack/smart-bot/commands/general/see_admins.rb +33 -0
- data/lib/slack/smart-bot/commands/general/see_announcements.rb +6 -4
- data/lib/slack/smart-bot/commands/general/see_command_ids.rb +29 -0
- data/lib/slack/smart-bot/commands/general/see_favorite_commands.rb +3 -4
- data/lib/slack/smart-bot/commands/general/see_statuses.rb +34 -21
- data/lib/slack/smart-bot/commands/general/see_teams.rb +252 -0
- data/lib/slack/smart-bot/commands/general/share_messages.rb +1 -1
- data/lib/slack/smart-bot/commands/general/update_team.rb +109 -0
- data/lib/slack/smart-bot/commands/general_bot_commands.rb +271 -10
- data/lib/slack/smart-bot/commands/on_bot/add_shortcut.rb +2 -1
- data/lib/slack/smart-bot/commands/on_bot/admin/add_routine.rb +2 -1
- data/lib/slack/smart-bot/commands/on_bot/admin/extend_rules.rb +2 -1
- data/lib/slack/smart-bot/commands/on_bot/admin/pause_bot.rb +2 -1
- data/lib/slack/smart-bot/commands/on_bot/admin/pause_routine.rb +2 -1
- data/lib/slack/smart-bot/commands/on_bot/admin/remove_routine.rb +2 -1
- data/lib/slack/smart-bot/commands/on_bot/admin/run_routine.rb +3 -2
- data/lib/slack/smart-bot/commands/on_bot/admin/see_result_routine.rb +2 -1
- data/lib/slack/smart-bot/commands/on_bot/admin/see_routines.rb +10 -9
- data/lib/slack/smart-bot/commands/on_bot/admin/start_bot.rb +2 -1
- data/lib/slack/smart-bot/commands/on_bot/admin/start_routine.rb +2 -1
- data/lib/slack/smart-bot/commands/on_bot/admin/stop_using_rules_on.rb +2 -1
- data/lib/slack/smart-bot/commands/on_bot/admin_master/delete_message.rb +25 -0
- data/lib/slack/smart-bot/commands/on_bot/admin_master/get_bot_logs.rb +1 -0
- data/lib/slack/smart-bot/commands/on_bot/admin_master/react_to.rb +3 -1
- data/lib/slack/smart-bot/commands/on_bot/admin_master/send_message.rb +15 -2
- data/lib/slack/smart-bot/commands/on_bot/delete_repl.rb +2 -1
- data/lib/slack/smart-bot/commands/on_bot/delete_shortcut.rb +5 -4
- data/lib/slack/smart-bot/commands/on_bot/general/bot_stats.rb +400 -0
- data/lib/slack/smart-bot/commands/{general → on_bot/general}/bot_status.rb +1 -0
- data/lib/slack/smart-bot/commands/{general → on_bot/general}/leaderboard.rb +1 -0
- data/lib/slack/smart-bot/commands/{general → on_bot/general}/stop_using_rules.rb +1 -0
- data/lib/slack/smart-bot/commands/{general → on_bot/general}/suggest_command.rb +6 -0
- data/lib/slack/smart-bot/commands/{general → on_bot/general}/use_rules.rb +1 -0
- data/lib/slack/smart-bot/commands/{general → on_bot/general}/whats_new.rb +2 -1
- data/lib/slack/smart-bot/commands/on_bot/get_repl.rb +2 -1
- data/lib/slack/smart-bot/commands/on_bot/repl.rb +72 -15
- data/lib/slack/smart-bot/commands/on_bot/ruby_code.rb +1 -0
- data/lib/slack/smart-bot/commands/on_bot/run_repl.rb +11 -2
- data/lib/slack/smart-bot/commands/on_bot/see_repls.rb +2 -1
- data/lib/slack/smart-bot/commands/on_bot/see_shortcuts.rb +3 -2
- data/lib/slack/smart-bot/commands/on_master/admin/kill_bot_on_channel.rb +5 -4
- data/lib/slack/smart-bot/commands/on_master/admin_master/exit_bot.rb +3 -2
- data/lib/slack/smart-bot/commands/on_master/admin_master/notify_message.rb +2 -1
- data/lib/slack/smart-bot/commands/on_master/admin_master/publish_announcements.rb +3 -2
- data/lib/slack/smart-bot/commands/on_master/admin_master/set_general_message.rb +2 -1
- data/lib/slack/smart-bot/commands/on_master/admin_master/set_maintenance.rb +2 -1
- data/lib/slack/smart-bot/commands/on_master/create_bot.rb +1 -0
- data/lib/slack/smart-bot/commands/on_master/where_smartbot.rb +41 -0
- data/lib/slack/smart-bot/commands.rb +22 -7
- data/lib/slack/smart-bot/listen.rb +30 -30
- data/lib/slack/smart-bot/process.rb +38 -18
- data/lib/slack/smart-bot/process_first.rb +2 -2
- data/lib/slack/smart-bot/treat_message.rb +13 -17
- data/lib/slack/smart-bot/utils/build_help.rb +1 -1
- data/lib/slack/smart-bot/utils/create_routine_thread.rb +1 -1
- data/lib/slack/smart-bot/utils/get_access_channels.rb +13 -0
- data/lib/slack/smart-bot/utils/get_admins_channels.rb +13 -0
- data/lib/slack/smart-bot/utils/get_bots_created.rb +27 -10
- data/lib/slack/smart-bot/utils/get_channels_name_and_id.rb +7 -2
- data/lib/slack/smart-bot/utils/get_command_ids.rb +84 -0
- data/lib/slack/smart-bot/utils/get_help.rb +34 -18
- data/lib/slack/smart-bot/utils/get_repls.rb +22 -2
- data/lib/slack/smart-bot/utils/get_routines.rb +22 -2
- data/lib/slack/smart-bot/utils/get_teams.rb +22 -0
- data/lib/slack/smart-bot/utils/has_access.rb +25 -9
- data/lib/slack/smart-bot/utils/is_admin.rb +27 -0
- data/lib/slack/smart-bot/utils/save_stats.rb +46 -43
- data/lib/slack/smart-bot/utils/save_status.rb +21 -6
- data/lib/slack/smart-bot/utils/update_access_channels.rb +8 -0
- data/lib/slack/smart-bot/utils/update_admins_channels.rb +8 -0
- data/lib/slack/smart-bot/utils/update_bots_file.rb +28 -7
- data/lib/slack/smart-bot/utils/update_repls.rb +7 -4
- data/lib/slack/smart-bot/utils/update_routines.rb +9 -3
- data/lib/slack/smart-bot/utils/update_shortcuts_file.rb +13 -6
- data/lib/slack/smart-bot/utils/update_teams.rb +16 -0
- data/lib/slack/smart-bot/utils.rb +8 -0
- data/lib/slack-smart-bot.rb +28 -10
- data/lib/slack-smart-bot_general_commands.rb +16 -1
- data/whats_new.txt +16 -29
- metadata +64 -19
- 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
|
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
|
-
|
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
|
-
|
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
|
-
|
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
|
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
|
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
|
-
|
174
|
-
|
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
|
-
!
|
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
|
-
|
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 (
|
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].
|
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].
|
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
|
-
|
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.
|
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
|
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.
|
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.
|
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,
|
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.
|
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.
|
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/
|
13
|
-
require_relative "commands/general/
|
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
|
-
|
8
|
-
|
9
|
-
|
10
|
-
|
11
|
-
|
12
|
-
|
13
|
-
|
14
|
-
|
15
|
-
|
16
|
-
|
17
|
-
|
18
|
-
|
19
|
-
|
20
|
-
|
21
|
-
|
22
|
-
|
23
|
-
|
24
|
-
|
25
|
-
|
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
|
-
|
29
|
-
|
30
|
-
|
31
|
-
|
32
|
-
|
33
|
-
|
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)
|