slack-smart-bot 1.10.0 → 1.12.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 +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
|