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