slack-smart-bot 1.10.0 → 1.12.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 +134 -23
- 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 +24 -13
- data/lib/slack/smart-bot/comm/send_msg_user.rb +12 -11
- data/lib/slack/smart-bot/comm/set_status.rb +21 -0
- data/lib/slack/smart-bot/comm.rb +3 -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_memo_team.rb +117 -0
- data/lib/slack/smart-bot/commands/general/add_team.rb +80 -0
- data/lib/slack/smart-bot/commands/general/add_vacation.rb +51 -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_memo_team.rb +69 -0
- data/lib/slack/smart-bot/commands/general/delete_share.rb +1 -1
- data/lib/slack/smart-bot/commands/general/delete_team.rb +54 -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/remove_vacation.rb +27 -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 +7 -5
- 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 +402 -0
- data/lib/slack/smart-bot/commands/general/see_vacations.rb +58 -0
- data/lib/slack/smart-bot/commands/general/see_vacations_team.rb +136 -0
- data/lib/slack/smart-bot/commands/general/set_memo_status.rb +58 -0
- data/lib/slack/smart-bot/commands/general/share_messages.rb +1 -1
- data/lib/slack/smart-bot/commands/general/update_team.rb +130 -0
- data/lib/slack/smart-bot/commands/general_bot_commands.rb +442 -13
- 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 +416 -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/kill_repl.rb +32 -0
- data/lib/slack/smart-bot/commands/on_bot/repl.rb +73 -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 +117 -28
- 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 +6 -3
- 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 +30 -7
- data/lib/slack/smart-bot/listen.rb +30 -30
- data/lib/slack/smart-bot/process.rb +53 -23
- data/lib/slack/smart-bot/process_first.rb +2 -2
- data/lib/slack/smart-bot/treat_message.rb +23 -17
- data/lib/slack/smart-bot/utils/build_help.rb +1 -1
- data/lib/slack/smart-bot/utils/check_vacations.rb +43 -0
- 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 +33 -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 +36 -19
- 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/get_vacations.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 +52 -42
- data/lib/slack/smart-bot/utils/save_status.rb +22 -7
- data/lib/slack/smart-bot/utils/update_access_channels.rb +8 -0
- data/lib/slack/smart-bot/utils/update_admins_channels.rb +25 -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/update_vacations.rb +16 -0
- data/lib/slack/smart-bot/utils.rb +11 -0
- data/lib/slack-smart-bot.rb +50 -12
- data/lib/slack-smart-bot_general_commands.rb +16 -1
- data/whats_new.txt +12 -30
- metadata +78 -21
- data/lib/slack/smart-bot/commands/general/bot_stats.rb +0 -314
@@ -0,0 +1,84 @@
|
|
1
|
+
class SlackSmartBot
|
2
|
+
def get_command_ids
|
3
|
+
commands = {
|
4
|
+
general: [],
|
5
|
+
on_bot_general: [],
|
6
|
+
on_bot_on_demand: [],
|
7
|
+
on_bot_admin: [],
|
8
|
+
on_bot_master_admin: [],
|
9
|
+
on_extended: [],
|
10
|
+
on_master: [],
|
11
|
+
on_master_admin: [],
|
12
|
+
on_master_master_admin: [],
|
13
|
+
general_commands: [],
|
14
|
+
general_rules: [],
|
15
|
+
rules: []
|
16
|
+
}
|
17
|
+
typem = Thread.current[:typem]
|
18
|
+
user = Thread.current[:user]
|
19
|
+
# :on_call, :on_bot, :on_extended, :on_dm, :on_master, :on_pg, :on_pub
|
20
|
+
admin = is_admin?(user.name)
|
21
|
+
|
22
|
+
commands[:general] = (Dir.entries("#{__dir__}/../commands/general/").select { |e| e.match?(/\.rb/) }).sort.join('|').gsub('.rb','').split('|')
|
23
|
+
general = File.read("#{__dir__}/../commands/general_bot_commands.rb")
|
24
|
+
commands[:general] += general.scan(/^\s*#\s*help\w*:\s+command_id:\s+:(\w+)\s*$/i).flatten
|
25
|
+
commands[:general].uniq!
|
26
|
+
|
27
|
+
if typem == :on_bot or typem == :on_master
|
28
|
+
commands[:on_bot_general] = (Dir.entries("#{__dir__}/../commands/on_bot/general/").select { |e| e.match?(/\.rb/) }).sort.join('|').gsub('.rb','').split('|')
|
29
|
+
end
|
30
|
+
|
31
|
+
if typem == :on_bot or typem == :on_master
|
32
|
+
commands[:on_bot_on_demand] = (Dir.entries("#{__dir__}/../commands/on_bot/").select { |e| e.match?(/\.rb/) }).sort.join('|').gsub('.rb','').split('|')
|
33
|
+
end
|
34
|
+
|
35
|
+
if (typem == :on_bot or typem == :on_master) and admin
|
36
|
+
commands[:on_bot_admin] = (Dir.entries("#{__dir__}/../commands/on_bot/admin/").select { |e| e.match?(/\.rb/) }).sort.join('|').gsub('.rb','').split('|')
|
37
|
+
end
|
38
|
+
|
39
|
+
if (typem == :on_bot or typem == :on_master) and config.masters.include?(user.name)
|
40
|
+
commands[:on_bot_master_admin] = (Dir.entries("#{__dir__}/../commands/on_bot/admin_master/").select { |e| e.match?(/\.rb/) }).sort.join('|').gsub('.rb','').split('|')
|
41
|
+
end
|
42
|
+
|
43
|
+
if typem == :on_extended
|
44
|
+
commands[:on_extended] = (Dir.entries("#{__dir__}/../commands/on_extended/").select { |e| e.match?(/\.rb/) }).sort.join('|').gsub('.rb','').split('|')
|
45
|
+
commands[:on_extended]+= ['repl', 'see_repls', 'get_repl', 'run_repl', 'delete_repl', 'kill_repl', 'ruby_code']
|
46
|
+
end
|
47
|
+
|
48
|
+
if typem == :on_master
|
49
|
+
commands[:on_master] = (Dir.entries("#{__dir__}/../commands/on_master/").select { |e| e.match?(/\.rb/) }).sort.join('|').gsub('.rb','').split('|')
|
50
|
+
end
|
51
|
+
|
52
|
+
if typem == :on_master and admin
|
53
|
+
commands[:on_master_admin] = (Dir.entries("#{__dir__}/../commands/on_master/admin/").select { |e| e.match?(/\.rb/) }).sort.join('|').gsub('.rb','').split('|')
|
54
|
+
end
|
55
|
+
|
56
|
+
if typem == :on_master and config.masters.include?(user.name)
|
57
|
+
commands[:on_master_master_admin] = (Dir.entries("#{__dir__}/../commands/on_master/admin_master/").select { |e| e.match?(/\.rb/) }).sort.join('|').gsub('.rb','').split('|')
|
58
|
+
end
|
59
|
+
|
60
|
+
if File.exist?("#{config.path}/rules/general_commands.rb")
|
61
|
+
general_commands = File.read("#{config.path}/rules/general_commands.rb")
|
62
|
+
commands[:general_commands] = general_commands.scan(/^\s*#\s*help\w*:\s+command_id:\s+:(\w+)\s*$/i).flatten
|
63
|
+
commands[:general_commands]+= general_commands.scan(/^\s*save_stats\(?\s*:(\w+)\s*,?/i).flatten
|
64
|
+
commands[:general_commands].uniq!
|
65
|
+
end
|
66
|
+
|
67
|
+
if typem == :on_extended or typem ==:on_call or typem == :on_bot or typem == :on_master or (typem == :on_dm and Thread.current[:using_channel].to_s != '')
|
68
|
+
if Thread.current.key?(:rules_file) and File.exist?(config.path + Thread.current[:rules_file])
|
69
|
+
rules = File.read(config.path + Thread.current[:rules_file])
|
70
|
+
commands[:rules] = rules.scan(/^\s*#\s*help\w*:\s+command_id:\s+:(\w+)\s*$/i).flatten
|
71
|
+
commands[:rules]+= rules.scan(/^\s*save_stats\(?\s*:(\w+)\s*,?/i).flatten
|
72
|
+
commands[:rules].uniq!
|
73
|
+
|
74
|
+
if File.exist?("#{config.path}/rules/general_rules.rb")
|
75
|
+
general_rules = File.read("#{config.path}/rules/general_rules.rb")
|
76
|
+
commands[:general_rules] = general_rules.scan(/^\s*#\s*help\w*:\s+command_id:\s+:(\w+)\s*$/i).flatten
|
77
|
+
commands[:general_rules]+= general_rules.scan(/^\s*save_stats\(?\s*:(\w+)\s*,?/i).flatten
|
78
|
+
commands[:general_rules].uniq!
|
79
|
+
end
|
80
|
+
end
|
81
|
+
end
|
82
|
+
return commands
|
83
|
+
end
|
84
|
+
end
|
@@ -1,14 +1,18 @@
|
|
1
1
|
class SlackSmartBot
|
2
2
|
def get_help(rules_file, dest, from, only_rules, expanded, descriptions: true, only_normal_user: false)
|
3
3
|
order = {
|
4
|
-
general: [:
|
5
|
-
|
4
|
+
general: [:bot_help, :hi_bot, :bye_bot, :add_admin, :remove_admin, :see_admins, :poster, :add_announcement, :delete_announcement,
|
5
|
+
:see_announcements, :see_command_ids, :share_messages, :see_shares, :delete_share, :see_favorite_commands, :see_statuses,
|
6
|
+
:allow_access, :see_access, :deny_access, :add_team, :add_memo_team, :delete_memo_team, :set_memo_status, :see_teams, :update_team, :ping_team, :delete_team,
|
7
|
+
:add_vacation, :remove_vacation, :see_vacations, :see_vacations_team],
|
8
|
+
on_bot_general: [:whats_new, :suggest_command, :bot_status, :use_rules, :stop_using_rules, :bot_stats, :leaderboard],
|
9
|
+
on_bot: [:ruby_code, :repl, :get_repl, :run_repl, :delete_repl, :see_repls, :kill_repl, :add_shortcut, :delete_shortcut, :see_shortcuts],
|
6
10
|
on_bot_admin: [:extend_rules, :stop_using_rules_on, :start_bot, :pause_bot, :add_routine,
|
7
11
|
:see_routines, :start_routine, :pause_routine, :remove_routine, :see_result_routine, :run_routine]
|
8
12
|
}
|
9
13
|
if config.masters.include?(from)
|
10
14
|
user_type = :master # master admin
|
11
|
-
elsif
|
15
|
+
elsif is_admin?(from)
|
12
16
|
user_type = :admin
|
13
17
|
else
|
14
18
|
user_type = :normal #normal user
|
@@ -66,9 +70,15 @@ class SlackSmartBot
|
|
66
70
|
end
|
67
71
|
|
68
72
|
help[:general_commands_file] = build_help("#{__dir__}/../commands/general_bot_commands.rb", expanded)[user_type].values.join("\n") + "\n" unless only_rules
|
69
|
-
if File.
|
73
|
+
if File.exist?(config.path + '/rules/general_commands.rb') and !only_rules
|
70
74
|
help[:general_commands_file] += build_help(config.path+'/rules/general_commands.rb', expanded)[user_type].values.join("\n") + "\n"
|
71
75
|
end
|
76
|
+
if help.key?(:on_bot)
|
77
|
+
commands_on_extended_from_on_bot = [:repl, :see_repls, :get_repl, :run_repl, :delete_repl, :kill_repl, :ruby_code]
|
78
|
+
commands_on_extended_from_on_bot.each do |cm|
|
79
|
+
help[:on_extended][cm] = help[:on_bot][cm] if help[:on_bot].key?(cm)
|
80
|
+
end
|
81
|
+
end
|
72
82
|
help = remove_hash_keys(help, :admin_master) unless user_type == :master
|
73
83
|
help = remove_hash_keys(help, :admin) unless user_type == :admin or user_type == :master
|
74
84
|
help = remove_hash_keys(help, :on_master) unless channel_type == :master_bot
|
@@ -101,36 +111,33 @@ class SlackSmartBot
|
|
101
111
|
You need to join the specified channel to be able to use those rules.
|
102
112
|
Also you can use this command to call another bot from a channel with a running bot.
|
103
113
|
\n"
|
104
|
-
txt +="
|
105
|
-
The commands you will be able to use from a channel without a bot:
|
106
|
-
*bot rules*, *ruby CODE*, *add shortcut NAME: COMMAND*, *delete shortcut NAME*, *see shortcuts*, *shortcut NAME*
|
107
|
-
*And all the specific rules of the Channel*\n"
|
108
114
|
end
|
109
115
|
|
110
|
-
if help.key?(:
|
116
|
+
if help.key?(:general_commands_file)
|
117
|
+
txt += "===================================
|
118
|
+
*General commands on any channel where the Smart Bot is a member:*\n" if descriptions
|
119
|
+
txt += help.general_commands_file
|
120
|
+
end
|
121
|
+
|
122
|
+
if help.key?(:on_bot) and help.on_bot.key?(:general) and channel_type != :external and channel_type != :extended
|
111
123
|
if descriptions
|
112
124
|
if channel_type == :direct
|
113
125
|
txt += "===================================
|
114
126
|
*General commands:*\n"
|
115
127
|
else
|
116
128
|
txt += "===================================
|
117
|
-
*General commands even when the Smart Bot is not listening to you:*\n"
|
129
|
+
*General commands on Bot channel even when the Smart Bot is not listening to you:*\n"
|
118
130
|
end
|
119
131
|
end
|
120
|
-
order.
|
121
|
-
txt += help.general[o]
|
132
|
+
order.on_bot_general.each do |o|
|
133
|
+
txt += help.on_bot.general[o]
|
122
134
|
end
|
123
135
|
if channel_type == :master_bot
|
124
136
|
txt += help.on_master.create_bot
|
137
|
+
txt += help.on_master.where_smartbot
|
125
138
|
end
|
126
139
|
end
|
127
140
|
|
128
|
-
if help.key?(:general_commands_file)
|
129
|
-
txt += "===================================
|
130
|
-
*General commands on any channel where the Smart Bot is a member:*\n" if descriptions
|
131
|
-
txt += help.general_commands_file
|
132
|
-
end
|
133
|
-
|
134
141
|
if help.key?(:on_bot) and channel_type != :external and channel_type != :extended
|
135
142
|
if descriptions
|
136
143
|
if channel_type == :direct
|
@@ -138,13 +145,23 @@ class SlackSmartBot
|
|
138
145
|
*General commands on bot, DM or on external call on demand:*\n"
|
139
146
|
else
|
140
147
|
txt += "===================================
|
141
|
-
*General commands only when the Smart Bot is listening to you or on demand:*\n"
|
148
|
+
*General commands on Bot channel only when the Smart Bot is listening to you or on demand:*\n"
|
142
149
|
end
|
143
150
|
end
|
144
151
|
order.on_bot.each do |o|
|
145
152
|
txt += help.on_bot[o]
|
146
153
|
end
|
147
154
|
end
|
155
|
+
if help.key?(:on_extended) and channel_type == :extended and help[:on_extended].keys.size > 0
|
156
|
+
if descriptions
|
157
|
+
txt += "===================================
|
158
|
+
*General commands on Extended channel only on demand:*\n"
|
159
|
+
end
|
160
|
+
commands_on_extended_from_on_bot.each do |o|
|
161
|
+
txt += help.on_extended[o]
|
162
|
+
end
|
163
|
+
end
|
164
|
+
|
148
165
|
if help.key?(:on_bot) and help.on_bot.key?(:admin) and channel_type != :external and channel_type != :extended
|
149
166
|
txt += "===================================
|
150
167
|
*Admin commands:*\n\n" if descriptions
|
@@ -1,11 +1,31 @@
|
|
1
1
|
class SlackSmartBot
|
2
2
|
|
3
3
|
def get_repls(channel = @channel_id)
|
4
|
-
|
4
|
+
require 'yaml'
|
5
|
+
repl_file = "#{config.path}/repl/repls_#{channel}.yaml"
|
6
|
+
|
7
|
+
if File.exist?("#{config.path}/repl/repls_#{channel}.rb") #backwards compatible
|
5
8
|
file_conf = IO.readlines("#{config.path}/repl/repls_#{channel}.rb").join
|
6
|
-
|
9
|
+
if file_conf.to_s() == ""
|
10
|
+
@repls = {}
|
11
|
+
else
|
7
12
|
@repls = eval(file_conf)
|
8
13
|
end
|
14
|
+
File.open(repl_file, 'w') {|file| file.write(@repls.to_yaml) }
|
15
|
+
File.delete("#{config.path}/repl/repls_#{channel}.rb")
|
16
|
+
end
|
17
|
+
|
18
|
+
if File.exist?(repl_file)
|
19
|
+
repls = @repls
|
20
|
+
10.times do
|
21
|
+
repls = YAML.load(File.read(repl_file))
|
22
|
+
if repls.is_a?(Hash)
|
23
|
+
break
|
24
|
+
else
|
25
|
+
sleep (0.1*(rand(2)+1))
|
26
|
+
end
|
27
|
+
end
|
28
|
+
@repls = repls unless repls.is_a?(FalseClass)
|
9
29
|
end
|
10
30
|
end
|
11
31
|
end
|
@@ -1,11 +1,31 @@
|
|
1
1
|
class SlackSmartBot
|
2
2
|
|
3
3
|
def get_routines(channel = @channel_id)
|
4
|
-
|
4
|
+
require 'yaml'
|
5
|
+
routines_file = "#{config.path}/routines/routines_#{channel}.yaml"
|
6
|
+
|
7
|
+
if File.exist?("#{config.path}/routines/routines_#{channel}.rb") #backwards compatible
|
5
8
|
file_conf = IO.readlines("#{config.path}/routines/routines_#{channel}.rb").join
|
6
|
-
|
9
|
+
if file_conf.to_s() == ""
|
10
|
+
@routines = {}
|
11
|
+
else
|
7
12
|
@routines = eval(file_conf)
|
8
13
|
end
|
14
|
+
File.open(routines_file, 'w') {|file| file.write(@routines.to_yaml) }
|
15
|
+
File.delete("#{config.path}/routines/routines_#{channel}.rb")
|
16
|
+
end
|
17
|
+
|
18
|
+
if File.exist?(routines_file)
|
19
|
+
routines = @routines
|
20
|
+
10.times do
|
21
|
+
routines = YAML.load(File.read(routines_file))
|
22
|
+
if routines.is_a?(Hash)
|
23
|
+
break
|
24
|
+
else
|
25
|
+
sleep (0.1*(rand(2)+1))
|
26
|
+
end
|
27
|
+
end
|
28
|
+
@routines = routines unless routines.is_a?(FalseClass)
|
9
29
|
end
|
10
30
|
end
|
11
31
|
end
|
@@ -0,0 +1,22 @@
|
|
1
|
+
class SlackSmartBot
|
2
|
+
def get_teams
|
3
|
+
@teams ||= {}
|
4
|
+
teams_file = config.file_path.gsub(".rb", "_teams.yaml")
|
5
|
+
if File.exist?(teams_file)
|
6
|
+
if !defined?(@datetime_teams_file) or @datetime_teams_file != File.mtime(teams_file)
|
7
|
+
require 'yaml'
|
8
|
+
teams = @teams
|
9
|
+
10.times do
|
10
|
+
teams = YAML.load(File.read(teams_file))
|
11
|
+
if teams.is_a?(Hash)
|
12
|
+
break
|
13
|
+
else
|
14
|
+
sleep (0.1*(rand(2)+1))
|
15
|
+
end
|
16
|
+
end
|
17
|
+
@teams = teams unless teams.is_a?(FalseClass)
|
18
|
+
@datetime_teams_file = File.mtime(teams_file)
|
19
|
+
end
|
20
|
+
end
|
21
|
+
end
|
22
|
+
end
|
@@ -0,0 +1,22 @@
|
|
1
|
+
class SlackSmartBot
|
2
|
+
def get_vacations
|
3
|
+
@vacations ||= {}
|
4
|
+
vacations_file = config.file_path.gsub(".rb", "_vacations.yaml")
|
5
|
+
if File.exist?(vacations_file)
|
6
|
+
if !defined?(@datetime_vacations_file) or @datetime_vacations_file != File.mtime(vacations_file)
|
7
|
+
require 'yaml'
|
8
|
+
vacations = @vacations
|
9
|
+
10.times do
|
10
|
+
vacations = YAML.load(File.read(vacations_file))
|
11
|
+
if vacations.is_a?(Hash)
|
12
|
+
break
|
13
|
+
else
|
14
|
+
sleep (0.1*(rand(2)+1))
|
15
|
+
end
|
16
|
+
end
|
17
|
+
@vacations = vacations unless vacations.is_a?(FalseClass)
|
18
|
+
@datetime_vacations_file = File.mtime(vacations_file)
|
19
|
+
end
|
20
|
+
end
|
21
|
+
end
|
22
|
+
end
|
@@ -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,57 @@
|
|
1
1
|
class SlackSmartBot
|
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", "time_zone"]
|
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
|
2
29
|
|
3
|
-
|
4
|
-
|
5
|
-
|
6
|
-
|
7
|
-
|
8
|
-
|
9
|
-
|
10
|
-
|
11
|
-
|
12
|
-
|
13
|
-
|
14
|
-
|
15
|
-
|
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
|
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
|
+
user_info = @users.select { |u| u.id == user_id or (u.key?(:enterprise_user) and u.enterprise_user.id == user_id) }[-1]
|
38
|
+
if user_info.nil? or user_info.is_app_user or user_info.is_bot
|
39
|
+
time_zone = ''
|
40
|
+
else
|
41
|
+
time_zone = user_info.tz_label
|
42
|
+
end
|
29
43
|
|
30
|
-
|
31
|
-
|
32
|
-
|
33
|
-
|
34
|
-
|
35
|
-
|
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
|
43
|
-
end
|
44
|
+
CSV.open("#{config.stats_path}.#{Time.now.strftime("%Y-%m")}.log", "a+") do |csv|
|
45
|
+
csv << [Time.now, config.channel, @channel_id, @channels_name[data.dest], data.dest, data.typem, user_name, user_id, command_txt, method, data.files, time_zone]
|
46
|
+
end
|
47
|
+
rescue Exception => exception
|
48
|
+
@logger.fatal "There was a problem on the stats"
|
49
|
+
@logger.fatal exception
|
44
50
|
end
|
51
|
+
end
|
52
|
+
else
|
53
|
+
sleep 0.2
|
54
|
+
Thread.exit
|
45
55
|
end
|
46
|
-
|
47
|
-
end
|
56
|
+
end
|
57
|
+
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,27 +33,31 @@ 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
|
42
57
|
@last_status_change = Time.now
|
43
58
|
@last_notified_status_id = status_id
|
44
59
|
unless m == ''
|
45
|
-
respond m, config.status_channel
|
60
|
+
respond eval("\"" + m + "\""), config.status_channel
|
46
61
|
end
|
47
62
|
end
|
48
63
|
|
@@ -0,0 +1,25 @@
|
|
1
|
+
class SlackSmartBot
|
2
|
+
|
3
|
+
def update_admins_channels()
|
4
|
+
|
5
|
+
require 'yaml'
|
6
|
+
admins_file = "#{config.path}/rules/#{@channel_id}/admins_channels.yaml"
|
7
|
+
|
8
|
+
if File.exist?(admins_file.gsub(".yaml", ".rb")) #backwards compatible
|
9
|
+
file_conf = IO.readlines(admins_file.gsub(".yaml", ".rb")).join
|
10
|
+
if file_conf.to_s() == ""
|
11
|
+
@admins_channels = {}
|
12
|
+
else
|
13
|
+
@admins_channels = eval(file_conf)
|
14
|
+
end
|
15
|
+
File.open(admins_file, 'w') {|file| file.write(@admins_channels.to_yaml) }
|
16
|
+
File.delete(admins_file.gsub(".yaml", ".rb"))
|
17
|
+
end
|
18
|
+
|
19
|
+
File.open(admins_file, 'w') {|file|
|
20
|
+
file.flock(File::LOCK_EX)
|
21
|
+
file.write(@admins_channels.to_yaml)
|
22
|
+
file.flock(File::LOCK_UN)
|
23
|
+
}
|
24
|
+
end
|
25
|
+
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
|