slack-smart-bot 1.9.2 → 1.10.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- 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>
|