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
@@ -1,12 +1,28 @@
|
|
1
1
|
class SlackSmartBot
|
2
|
-
|
3
|
-
|
4
|
-
|
5
|
-
|
6
|
-
|
7
|
-
|
2
|
+
def has_access?(method, user = nil)
|
3
|
+
user = Thread.current[:user] if user.nil?
|
4
|
+
if config[:allow_access].key?(method) and !config[:allow_access][method].include?(user.name) and !config[:allow_access][method].include?(user.id) and
|
5
|
+
(!user.key?(:enterprise_user) or (user.key?(:enterprise_user) and !config[:allow_access][method].include?(user[:enterprise_user].id)))
|
6
|
+
respond "You don't have access to use this command, please contact an Admin to be able to use it: <@#{config.admins.join(">, <@")}>"
|
7
|
+
return false
|
8
|
+
else
|
9
|
+
if Thread.current[:typem] == :on_call
|
10
|
+
channel = Thread.current[:dchannel]
|
11
|
+
elsif Thread.current[:using_channel].to_s == ""
|
12
|
+
channel = Thread.current[:dest]
|
13
|
+
else
|
14
|
+
channel = Thread.current[:using_channel]
|
15
|
+
end
|
16
|
+
if !@access_channels.key?(channel) or !@access_channels[channel].key?(method.to_s) or @access_channels[channel][method.to_s].include?(user.name)
|
17
|
+
return true
|
18
|
+
else
|
19
|
+
if @admins_channels.key?(channel) and !@admins_channels[channel].empty?
|
20
|
+
respond "You don't have access to use this command, please contact an Admin to be able to use it: <@#{@admins_channels[channel].join(">, <@")}>"
|
8
21
|
else
|
9
|
-
|
10
|
-
end
|
22
|
+
respond "You don't have access to use this command, please contact an Admin to be able to use it."
|
23
|
+
end
|
24
|
+
return false
|
25
|
+
end
|
11
26
|
end
|
12
|
-
end
|
27
|
+
end
|
28
|
+
end
|
@@ -0,0 +1,27 @@
|
|
1
|
+
class SlackSmartBot
|
2
|
+
def is_admin?(from=nil)
|
3
|
+
if from.nil?
|
4
|
+
user = Thread.current[:user]
|
5
|
+
from = user.name
|
6
|
+
end
|
7
|
+
|
8
|
+
if (Thread.current[:dchannel].to_s!='' and !@channels_creator.key?(Thread.current[:dchannel])) or
|
9
|
+
(Thread.current[:dest].to_s!='' and Thread.current[:dest][0]!='D' and !@channels_creator.key?(Thread.current[:dest])) or
|
10
|
+
(Thread.current[:using_channel].to_s!='' and !@channels_creator.key?(:using_channel))
|
11
|
+
get_channels_name_and_id()
|
12
|
+
end
|
13
|
+
|
14
|
+
if config.masters.include?(from) or
|
15
|
+
config.admins.include?(from) or
|
16
|
+
(Thread.current[:typem] == :on_call and @admins_channels.key?(Thread.current[:dchannel]) and @admins_channels[Thread.current[:dchannel]].include?(from)) or
|
17
|
+
(Thread.current[:using_channel].to_s == '' and @admins_channels.key?(Thread.current[:dest]) and @admins_channels[Thread.current[:dest]].include?(from)) or
|
18
|
+
(@admins_channels.key?(Thread.current[:using_channel]) and @admins_channels[Thread.current[:using_channel]].include?(from)) or
|
19
|
+
(Thread.current[:using_channel].to_s=='' and @channels_creator.key?(Thread.current[:dest]) and from == @channels_creator[Thread.current[:dest]]) or
|
20
|
+
(Thread.current[:typem] == :on_call and @channels_creator.key?(Thread.current[:dchannel]) and from == @channels_creator[Thread.current[:dchannel]]) or
|
21
|
+
(@channels_creator.key?(Thread.current[:using_channel]) and from == @channels_creator[Thread.current[:using_channel]])
|
22
|
+
return true
|
23
|
+
else
|
24
|
+
return false
|
25
|
+
end
|
26
|
+
end
|
27
|
+
end
|
@@ -1,47 +1,50 @@
|
|
1
1
|
class SlackSmartBot
|
2
|
-
|
3
|
-
|
4
|
-
|
5
|
-
|
6
|
-
|
7
|
-
|
8
|
-
|
9
|
-
|
10
|
-
end
|
11
|
-
end
|
12
|
-
if data.empty?
|
13
|
-
data = {
|
14
|
-
dest: Thread.current[:dest],
|
15
|
-
typem: Thread.current[:typem],
|
16
|
-
user: Thread.current[:user],
|
17
|
-
files: Thread.current[:files?],
|
18
|
-
command: Thread.current[:command],
|
19
|
-
routine: Thread.current[:routine]
|
20
|
-
}
|
21
|
-
end
|
22
|
-
if method.to_s == 'ruby_code' and data.files
|
23
|
-
command_txt = 'ruby'
|
24
|
-
else
|
25
|
-
command_txt = data.command
|
26
|
-
end
|
27
|
-
command_txt.gsub!(/```.+```/m,'```CODE```')
|
28
|
-
command_txt = "#{command_txt[0..99]}..." if command_txt.size > 100
|
29
|
-
|
30
|
-
if data.routine
|
31
|
-
user_name = "routine/#{data.user.name}"
|
32
|
-
user_id = "routine/#{data.user.id}"
|
33
|
-
else
|
34
|
-
user_name = data.user.name
|
35
|
-
user_id = data.user.id
|
36
|
-
end
|
37
|
-
CSV.open("#{config.stats_path}.#{Time.now.strftime("%Y-%m")}.log", "a+") do |csv|
|
38
|
-
csv << [Time.now, config.channel, @channel_id, @channels_name[data.dest], data.dest, data.typem, user_name, user_id, command_txt, method, data.files]
|
39
|
-
end
|
40
|
-
rescue Exception => exception
|
41
|
-
@logger.fatal "There was a problem on the stats"
|
42
|
-
@logger.fatal exception
|
2
|
+
def save_stats(method, data: {})
|
3
|
+
if has_access?(method, Thread.current[:user])
|
4
|
+
if config.stats
|
5
|
+
begin
|
6
|
+
require "csv"
|
7
|
+
if !File.exist?("#{config.stats_path}.#{Time.now.strftime("%Y-%m")}.log")
|
8
|
+
CSV.open("#{config.stats_path}.#{Time.now.strftime("%Y-%m")}.log", "wb") do |csv|
|
9
|
+
csv << ["date", "bot_channel", "bot_channel_id", "dest_channel", "dest_channel_id", "type_message", "user_name", "user_id", "text", "command", "files"]
|
43
10
|
end
|
11
|
+
end
|
12
|
+
if data.empty?
|
13
|
+
data = {
|
14
|
+
dest: Thread.current[:dest],
|
15
|
+
typem: Thread.current[:typem],
|
16
|
+
user: Thread.current[:user],
|
17
|
+
files: Thread.current[:files?],
|
18
|
+
command: Thread.current[:command],
|
19
|
+
routine: Thread.current[:routine],
|
20
|
+
}
|
21
|
+
end
|
22
|
+
if method.to_s == "ruby_code" and data.files
|
23
|
+
command_txt = "ruby"
|
24
|
+
else
|
25
|
+
command_txt = data.command
|
26
|
+
end
|
27
|
+
command_txt.gsub!(/```.+```/m, "```CODE```")
|
28
|
+
command_txt = "#{command_txt[0..99]}..." if command_txt.size > 100
|
29
|
+
|
30
|
+
if data.routine
|
31
|
+
user_name = "routine/#{data.user.name}"
|
32
|
+
user_id = "routine/#{data.user.id}"
|
33
|
+
else
|
34
|
+
user_name = data.user.name
|
35
|
+
user_id = data.user.id
|
36
|
+
end
|
37
|
+
CSV.open("#{config.stats_path}.#{Time.now.strftime("%Y-%m")}.log", "a+") do |csv|
|
38
|
+
csv << [Time.now, config.channel, @channel_id, @channels_name[data.dest], data.dest, data.typem, user_name, user_id, command_txt, method, data.files]
|
39
|
+
end
|
40
|
+
rescue Exception => exception
|
41
|
+
@logger.fatal "There was a problem on the stats"
|
42
|
+
@logger.fatal exception
|
44
43
|
end
|
44
|
+
end
|
45
|
+
else
|
46
|
+
sleep 0.2
|
47
|
+
Thread.exit
|
45
48
|
end
|
46
|
-
|
47
|
-
end
|
49
|
+
end
|
50
|
+
end
|
@@ -7,12 +7,23 @@ class SlackSmartBot
|
|
7
7
|
CSV.open("#{config.path}/status/#{config.channel}_status.csv", "a+") do |csv|
|
8
8
|
csv << [Time.now.strftime("%Y/%m/%d"), Time.now.strftime("%H:%M:%S"), status, status_id, message]
|
9
9
|
end
|
10
|
+
if defined?(@channels_list) #wait until the 'client' started
|
11
|
+
channel_info = @channels_list.select { |c| c.id == @channel_id}[-1]
|
12
|
+
if channel_info.nil? or channel_info.is_private
|
13
|
+
channel_link = "##{config.channel}"
|
14
|
+
else
|
15
|
+
channel_link = "<##{@channel_id}|#{config.channel}>"
|
16
|
+
end
|
17
|
+
else
|
18
|
+
channel_link = "##{config.channel}"
|
19
|
+
end
|
20
|
+
|
10
21
|
if status_id == :disconnected
|
11
22
|
Thread.new do
|
12
23
|
sleep 50
|
13
24
|
@logger.info "check disconnection 50 scs later #{@last_notified_status_id}"
|
14
25
|
unless @last_notified_status_id == :connected
|
15
|
-
respond ":red_circle: The *SmartBot* on
|
26
|
+
respond ":red_circle: The *SmartBot* on *#{channel_link}* is down. An admin will take a look. <@#{config.admins.join(">, <@")}>", config.status_channel
|
16
27
|
end
|
17
28
|
end
|
18
29
|
end
|
@@ -22,20 +33,24 @@ class SlackSmartBot
|
|
22
33
|
if (Time.now-@last_status_change) > 20 or !defined?(@last_notified_status_id)
|
23
34
|
if status_id == :connected
|
24
35
|
if defined?(@last_notified_status_id)
|
25
|
-
m = ":exclamation: :large_green_circle: The *SmartBot* on
|
36
|
+
m = ":exclamation: :large_green_circle: The *SmartBot* on *#{channel_link}* was not available for #{(Time.now-@last_status_change).round(0)} secs. *Now it is up and running again.*"
|
26
37
|
else
|
27
|
-
m = ":large_green_circle: The *SmartBot* on
|
38
|
+
m = ":large_green_circle: The *SmartBot* on *#{channel_link}* is up and running again."
|
28
39
|
end
|
29
40
|
end
|
30
41
|
end
|
31
42
|
if status_id == :paused
|
32
|
-
m = ":red_circle: #{message}
|
43
|
+
m = ":red_circle: #{message} *#{channel_link}*"
|
33
44
|
elsif status_id == :started
|
34
|
-
m = ":large_green_circle: #{message}
|
45
|
+
m = ":large_green_circle: #{message} *#{channel_link}*"
|
35
46
|
elsif status_id == :killed or status_id == :exited
|
36
47
|
m = ":red_circle: #{message}"
|
37
48
|
elsif config.on_master_bot and status_id == :maintenance_on
|
38
|
-
|
49
|
+
if message.to_s == "Sorry I'm on maintenance so I cannot attend your request."
|
50
|
+
m = ":red_circle: The *SmartBot* is on maintenance so not possible to attend any request."
|
51
|
+
else
|
52
|
+
m = ":red_circle: #{message}"
|
53
|
+
end
|
39
54
|
elsif config.on_master_bot and status_id == :maintenance_off
|
40
55
|
m = ":large_green_circle: The *SmartBot* is up and running again."
|
41
56
|
end
|
@@ -1,11 +1,32 @@
|
|
1
1
|
class SlackSmartBot
|
2
2
|
def update_bots_file
|
3
|
-
|
4
|
-
|
5
|
-
|
6
|
-
|
7
|
-
|
8
|
-
|
9
|
-
|
3
|
+
bots_file = config.file_path.gsub(".rb", "_bots.yaml")
|
4
|
+
|
5
|
+
if File.exist?(config.file_path.gsub(".rb", "_bots.rb")) #backwards compatible
|
6
|
+
file_conf = IO.readlines(config.file_path.gsub(".rb", "_bots.rb")).join
|
7
|
+
if file_conf.to_s() == ""
|
8
|
+
@bots_created = {}
|
9
|
+
else
|
10
|
+
@bots_created = eval(file_conf)
|
11
|
+
end
|
12
|
+
File.open(bots_file, 'w') {|file|
|
13
|
+
file.flock(File::LOCK_EX)
|
14
|
+
file.write(@bots_created.to_yaml)
|
15
|
+
file.flock(File::LOCK_UN)
|
16
|
+
}
|
17
|
+
File.delete(config.file_path.gsub(".rb", "_bots.rb"))
|
18
|
+
else
|
19
|
+
#not possible to use @bots_created.deep_copy since one of the fields contains a thread
|
20
|
+
bots_created = {}
|
21
|
+
@bots_created.each do |k,v|
|
22
|
+
bots_created[k] = v.dup
|
23
|
+
bots_created[k][:thread] = ''
|
24
|
+
end
|
25
|
+
File.open(bots_file, 'w') {|file|
|
26
|
+
file.flock(File::LOCK_EX)
|
27
|
+
file.write(bots_created.to_yaml)
|
28
|
+
file.flock(File::LOCK_UN)
|
29
|
+
}
|
30
|
+
end
|
10
31
|
end
|
11
32
|
end
|
@@ -1,8 +1,11 @@
|
|
1
1
|
class SlackSmartBot
|
2
|
-
|
3
2
|
def update_repls(channel = @channel_id)
|
4
|
-
|
5
|
-
|
6
|
-
file
|
3
|
+
require 'yaml'
|
4
|
+
repl_file = "#{config.path}/repl/repls_#{channel}.yaml"
|
5
|
+
File.open(repl_file, 'w') {|file|
|
6
|
+
file.flock(File::LOCK_EX)
|
7
|
+
file.write(@repls.to_yaml)
|
8
|
+
file.flock(File::LOCK_UN)
|
9
|
+
}
|
7
10
|
end
|
8
11
|
end
|
@@ -1,8 +1,11 @@
|
|
1
1
|
class SlackSmartBot
|
2
2
|
|
3
3
|
def update_routines(channel = @channel_id)
|
4
|
+
|
5
|
+
require 'yaml'
|
6
|
+
routines_file = "#{config.path}/routines/routines_#{channel}.yaml"
|
7
|
+
|
4
8
|
routines = {}
|
5
|
-
file = File.open("#{config.path}/routines/routines_#{channel}.rb", "w")
|
6
9
|
@routines.each do |k,v|
|
7
10
|
routines[k]={}
|
8
11
|
v.each do |kk,vv|
|
@@ -10,7 +13,10 @@ class SlackSmartBot
|
|
10
13
|
routines[k][kk][:thread]=""
|
11
14
|
end
|
12
15
|
end
|
13
|
-
|
14
|
-
|
16
|
+
File.open(routines_file, 'w') {|file|
|
17
|
+
file.flock(File::LOCK_EX)
|
18
|
+
file.write(routines.to_yaml)
|
19
|
+
file.flock(File::LOCK_UN)
|
20
|
+
}
|
15
21
|
end
|
16
22
|
end
|
@@ -1,13 +1,20 @@
|
|
1
1
|
class SlackSmartBot
|
2
2
|
def update_shortcuts_file
|
3
|
-
|
4
|
-
|
5
|
-
file
|
3
|
+
require 'yaml'
|
4
|
+
sc_file = "#{config.path}/shortcuts/#{config.shortcuts_file}"
|
5
|
+
File.open(sc_file, 'w') {|file|
|
6
|
+
file.flock(File::LOCK_EX)
|
7
|
+
file.write(@shortcuts.to_yaml)
|
8
|
+
file.flock(File::LOCK_UN)
|
9
|
+
}
|
6
10
|
|
7
11
|
if config.on_master_bot
|
8
|
-
|
9
|
-
|
10
|
-
|
12
|
+
sc_file = "#{config.path}/shortcuts/shortcuts_global.yaml"
|
13
|
+
File.open(sc_file, 'w') {|file|
|
14
|
+
file.flock(File::LOCK_EX)
|
15
|
+
file.write(@shortcuts_global.to_yaml)
|
16
|
+
file.flock(File::LOCK_UN)
|
17
|
+
}
|
11
18
|
end
|
12
19
|
end
|
13
20
|
end
|
@@ -0,0 +1,16 @@
|
|
1
|
+
class SlackSmartBot
|
2
|
+
def update_teams(team=nil)
|
3
|
+
require 'yaml'
|
4
|
+
unless team.nil?
|
5
|
+
get_teams()
|
6
|
+
@teams.merge!(team)
|
7
|
+
end
|
8
|
+
teams_file = config.file_path.gsub(".rb", "_teams.yaml")
|
9
|
+
File.open(teams_file, 'w') {|file|
|
10
|
+
file.flock(File::LOCK_EX)
|
11
|
+
file.write(@teams.to_yaml)
|
12
|
+
file.flock(File::LOCK_UN)
|
13
|
+
}
|
14
|
+
@datetime_teams_file = File.mtime(teams_file)
|
15
|
+
end
|
16
|
+
end
|
@@ -18,4 +18,12 @@ require_relative 'utils/answer'
|
|
18
18
|
require_relative 'utils/answer_delete'
|
19
19
|
require_relative 'utils/has_access'
|
20
20
|
require_relative 'utils/save_status'
|
21
|
+
require_relative 'utils/get_admins_channels'
|
22
|
+
require_relative 'utils/update_admins_channels'
|
23
|
+
require_relative 'utils/is_admin'
|
24
|
+
require_relative 'utils/get_access_channels'
|
25
|
+
require_relative 'utils/update_access_channels'
|
26
|
+
require_relative 'utils/get_command_ids'
|
27
|
+
require_relative 'utils/get_teams'
|
28
|
+
require_relative 'utils/update_teams'
|
21
29
|
|
data/lib/slack-smart-bot.rb
CHANGED
@@ -9,6 +9,7 @@ require "open3"
|
|
9
9
|
require "nice_http"
|
10
10
|
require "nice_hash"
|
11
11
|
require 'cgi'
|
12
|
+
require 'yaml'
|
12
13
|
|
13
14
|
require_relative "slack/smart-bot/comm"
|
14
15
|
require_relative "slack/smart-bot/listen"
|
@@ -66,6 +67,7 @@ class SlackSmartBot
|
|
66
67
|
Dir.mkdir("#{config.path}/routines") unless Dir.exist?("#{config.path}/routines")
|
67
68
|
Dir.mkdir("#{config.path}/announcements") unless Dir.exist?("#{config.path}/announcements")
|
68
69
|
Dir.mkdir("#{config.path}/shares") unless Dir.exist?("#{config.path}/shares")
|
70
|
+
Dir.mkdir("#{config.path}/rules") unless Dir.exist?("#{config.path}/rules")
|
69
71
|
File.delete("#{config.path}/config_tmp.status") if File.exist?("#{config.path}/config_tmp.status")
|
70
72
|
|
71
73
|
config.masters = MASTER_USERS if config.masters.to_s=='' and defined?(MASTER_USERS)
|
@@ -77,7 +79,7 @@ class SlackSmartBot
|
|
77
79
|
default_rules = (__FILE__).gsub(/\.rb$/, "_rules.rb")
|
78
80
|
FileUtils.copy_file(default_rules, config.path + '/' + config.rules_file)
|
79
81
|
end
|
80
|
-
config.admins = config.masters unless config.admins.to_s!=''
|
82
|
+
config.admins = config.masters.dup unless config.admins.to_s!=''
|
81
83
|
config.channel = config.master_channel unless config.channel.to_s!=''
|
82
84
|
config.status_init = :on unless config.status_init.to_s!=''
|
83
85
|
else
|
@@ -89,7 +91,7 @@ class SlackSmartBot
|
|
89
91
|
config.rules_file[0]='' if config.rules_file[0]=='.'
|
90
92
|
config.rules_file='/'+config.rules_file if config.rules_file[0]!='/'
|
91
93
|
|
92
|
-
config.shortcuts_file = "slack-smart-bot_shortcuts_#{config.channel}.
|
94
|
+
config.shortcuts_file = "slack-smart-bot_shortcuts_#{config.channel}.yaml".gsub(" ", "_")
|
93
95
|
if config.channel == config.master_channel
|
94
96
|
config.on_master_bot = true
|
95
97
|
config.start_bots = true unless config.key?(:start_bots)
|
@@ -140,7 +142,7 @@ class SlackSmartBot
|
|
140
142
|
else
|
141
143
|
if config.logrtm
|
142
144
|
logrtmname = "#{config.path}/logs/rtm_#{config.channel}.log"
|
143
|
-
File.delete(logrtmname) if File.
|
145
|
+
File.delete(logrtmname) if File.exist?(logrtmname)
|
144
146
|
@logrtm = Logger.new(logrtmname)
|
145
147
|
self.client = Slack::RealTime::Client.new(start_method: :rtm_connect, logger: @logrtm)
|
146
148
|
else
|
@@ -179,24 +181,34 @@ class SlackSmartBot
|
|
179
181
|
@shares = Hash.new()
|
180
182
|
@last_status_change = Time.now
|
181
183
|
|
182
|
-
|
183
|
-
|
184
|
-
|
185
|
-
|
186
|
-
|
184
|
+
if File.exist?("#{config.path}/shortcuts/#{config.shortcuts_file}".gsub('.yaml','.rb')) #backwards compatible
|
185
|
+
file_conf = IO.readlines("#{config.path}/shortcuts/#{config.shortcuts_file}".gsub('.yaml','.rb')).join
|
186
|
+
if file_conf.to_s() == ""
|
187
|
+
@shortcuts = {}
|
188
|
+
else
|
189
|
+
@shortcuts = eval(file_conf)
|
187
190
|
end
|
191
|
+
File.open("#{config.path}/shortcuts/#{config.shortcuts_file}", 'w') {|file| file.write(@shortcuts.to_yaml) }
|
192
|
+
File.delete("#{config.path}/shortcuts/#{config.shortcuts_file}".gsub('.yaml','.rb'))
|
193
|
+
elsif File.exist?("#{config.path}/shortcuts/#{config.shortcuts_file}")
|
194
|
+
@shortcuts = YAML.load(File.read("#{config.path}/shortcuts/#{config.shortcuts_file}"))
|
188
195
|
end
|
189
|
-
if File.exist?("#{config.path}/shortcuts/shortcuts_global.rb")
|
196
|
+
if File.exist?("#{config.path}/shortcuts/shortcuts_global.rb") #backwards compatible
|
190
197
|
file_sc = IO.readlines("#{config.path}/shortcuts/shortcuts_global.rb").join
|
198
|
+
@shortcuts_global = {}
|
191
199
|
unless file_sc.to_s() == ""
|
192
200
|
@shortcuts_global = eval(file_sc)
|
193
201
|
end
|
202
|
+
File.open("#{config.path}/shortcuts/shortcuts_global.yaml", 'w') {|file| file.write(@shortcuts_global.to_yaml) }
|
203
|
+
File.delete("#{config.path}/shortcuts/shortcuts_global.rb")
|
204
|
+
elsif File.exist?("#{config.path}/shortcuts/shortcuts_global.yaml")
|
205
|
+
@shortcuts_global = YAML.load(File.read("#{config.path}/shortcuts/shortcuts_global.yaml"))
|
194
206
|
end
|
195
207
|
|
196
208
|
get_routines()
|
197
209
|
get_repls()
|
198
210
|
|
199
|
-
if config.on_master_bot and File.exist?(config.file_path.gsub(".rb", "_bots.rb"))
|
211
|
+
if config.on_master_bot and (File.exist?(config.file_path.gsub(".rb", "_bots.rb")) or File.exist?(config.file_path.gsub('.rb', '_bots.yaml')))
|
200
212
|
get_bots_created()
|
201
213
|
if @bots_created.kind_of?(Hash) and config.start_bots
|
202
214
|
@bots_created.each { |key, value|
|
@@ -270,13 +282,19 @@ class SlackSmartBot
|
|
270
282
|
@datetime_general_commands = 0
|
271
283
|
@channels_id = Hash.new()
|
272
284
|
@channels_name = Hash.new()
|
285
|
+
@channels_creator = Hash.new()
|
286
|
+
@channels_list = Hash.new()
|
273
287
|
get_channels_name_and_id()
|
274
288
|
@channel_id = @channels_id[config.channel].dup
|
275
289
|
@master_bot_id = @channels_id[config.master_channel].dup
|
276
290
|
|
291
|
+
Dir.mkdir("#{config.path}/rules/#{@channel_id}") unless Dir.exist?("#{config.path}/rules/#{@channel_id}/")
|
292
|
+
|
277
293
|
get_routines()
|
278
294
|
get_repls()
|
279
295
|
get_shares()
|
296
|
+
get_admins_channels()
|
297
|
+
get_access_channels()
|
280
298
|
|
281
299
|
if @routines.key?(@channel_id)
|
282
300
|
@routines[@channel_id].each do |k, v|
|
@@ -21,7 +21,7 @@ def general_commands(user, command, dest, files = [])
|
|
21
21
|
|
22
22
|
|
23
23
|
# this is a hidden command that it is not listed when calling bot help
|
24
|
-
when /\
|
24
|
+
when /\s*(that's\s+)?(thanks|thank\s+you|I\s+love\s+you|nice|cool)\s+(#{@salutations.join("|")})\s*!*\s*$/i
|
25
25
|
save_stats :thanks
|
26
26
|
reactions = [:heart, :heart_eyes, :blush, :relaxed, :simple_smile, :smiley, :two_hearts, :heartbeat, :green_heart ]
|
27
27
|
reactions.sample(rand(3)+1).each {|rt| react rt }
|
@@ -30,6 +30,21 @@ def general_commands(user, command, dest, files = [])
|
|
30
30
|
'Það var ekkert', 'De nada', 'No hay de qué', 'De rien', 'Bitte', 'Prego', 'मेरा सौभाग्य है', '不客氣', 'Παρακαλώ']
|
31
31
|
respond "#{responses.sample}#{'!'*rand(4)}"
|
32
32
|
|
33
|
+
# this is a hidden command that it is not listed when calling bot help
|
34
|
+
when /\s*.*happy\s+birthday.*(<@\w+>)\s*.*$/i, /\s*.*(<@\w+>).*happy\s+birthday\s*.*$/i
|
35
|
+
unless Thread.current[:on_thread]
|
36
|
+
save_stats :happy_birthday
|
37
|
+
happy_user = $1
|
38
|
+
reactions = [:tada, :cake, :birthday]
|
39
|
+
sleep 30
|
40
|
+
reactions.sample(rand(3)+1).each {|rt| react rt }
|
41
|
+
sleep (rand(10)+5)*60 # so SmartBot is not the first one
|
42
|
+
responses = ['Happy birthday', "Very happy birthday", "Happy happy happy birthday", "Have a fabulous birthday", 'May all your wishes come true',
|
43
|
+
'Many happy returns of the day', 'I wish you a wonderful birthday', 'Have a great one', 'I hope you have a fantastic day and a fantastic year to come',
|
44
|
+
'To your happiness', "Don't count the candles. Enjoy the party", 'May your day be as awesome as you are', 'The best things in life are yet to come']
|
45
|
+
respond "#{happy_user} #{responses.sample}#{'!'*rand(4)}", :on_thread
|
46
|
+
end
|
47
|
+
|
33
48
|
else
|
34
49
|
return false
|
35
50
|
end
|
data/whats_new.txt
CHANGED
@@ -1,36 +1,23 @@
|
|
1
|
-
*Version 1.
|
1
|
+
*Version 1.11.0* Released 2022-May-09
|
2
2
|
|
3
3
|
*For General users*
|
4
|
-
-
|
5
|
-
-
|
6
|
-
-
|
7
|
-
-
|
8
|
-
-
|
9
|
-
-
|
10
|
-
-
|
11
|
-
-
|
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.
|
4
|
+
- `run repl` displays results as code in case a value on stdout is returned as Hash or Array (<https://github.com/MarioRuiz/slack-smart-bot/issues/41|#41>).
|
5
|
+
- `repl` command displays results when using iterators and printing results (<https://github.com/MarioRuiz/slack-smart-bot/issues/35|#35>).
|
6
|
+
- `see command ids` will return the command ids. (<https://github.com/MarioRuiz/slack-smart-bot/issues/43|#43>)
|
7
|
+
- `poster MESSAGE`, `poster :EMOTICON_TEXT: MESSAGE`, `poster :EMOTICON_TEXT: :EMOTICON_BACKGROUND: MESSAGE`, `poster MINUTESm MESSAGE` It will create a poster with the message supplied. By default will be autodeleted 1 minute later. (<https://github.com/MarioRuiz/slack-smart-bot/issues/34|#34>)
|
8
|
+
- `who is available?` show members of the channel that are on line and not on a meeting or vacation or sick. (<https://github.com/MarioRuiz/slack-smart-bot/issues/52|#52>)
|
9
|
+
- You can add, update, see, ping, contact, and delete teams. When calling `see TEAM_NAME team` the availability of the members will be displayed. Call `bot help teams` for more info. (<https://github.com/MarioRuiz/slack-smart-bot/issues/53|#53>)
|
10
|
+
- repl improvements (<https://github.com/MarioRuiz/slack-smart-bot/issues/54|#54>)
|
11
|
+
- new Master command `where is smartbot?` will return the channels where the SmartBot is a member. (<https://github.com/MarioRuiz/slack-smart-bot/issues/56|#56>)
|
15
12
|
|
16
13
|
*For Admin users*
|
17
|
-
-
|
18
|
-
- `
|
19
|
-
-
|
20
|
-
-
|
21
|
-
-
|
22
|
-
-
|
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
|
14
|
+
- When calling `respond` it can be supplied the argument `return_message: true` to get access to the posted message. `msg = respond('my message', return_message: true)` (<https://github.com/MarioRuiz/slack-smart-bot/issues/31|#31>)
|
15
|
+
- New command `delete message URL` will delete the SmartBot message supplied. Only for Master Admins (<https://github.com/MarioRuiz/slack-smart-bot/issues/32|#32>).
|
16
|
+
- `send message` accept also the url of the message to respond on a thread. Only for Master Admins (<https://github.com/MarioRuiz/slack-smart-bot/issues/39|#39>).
|
17
|
+
- `react to` accept also the url of the message. Only for Master Admins (<https://github.com/MarioRuiz/slack-smart-bot/issues/40|#40>).
|
18
|
+
- You can add, remove and list admins of any channel by using: `add admin @user`, `remove admin @user` and `see admins`. You need to be the creator of the channel, a Master admin or an admin (<https://github.com/MarioRuiz/slack-smart-bot/issues/42|#42>).
|
19
|
+
- `see access COMMAND_ID`, `allow access COMMAND_ID`, `allow access COMMAND_ID @user1 @user99` and `deny access COMMAND_ID`: Allows us to decide which commands are accessible on every channel. (<https://github.com/MarioRuiz/slack-smart-bot/issues/44|#44>).
|
33
20
|
|
34
21
|
------------------------------
|
35
22
|
|
36
|
-
*Previous*: <https://github.com/MarioRuiz/slack-smart-bot/blob/dd23939f93ee95aca3c04d33cd1ce197d6efbd37/whats_new.txt|1.
|
23
|
+
*Previous*: <https://github.com/MarioRuiz/slack-smart-bot/blob/dd23939f93ee95aca3c04d33cd1ce197d6efbd37/whats_new.txt|1.10.0>
|