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,117 @@
|
|
1
|
+
class SlackSmartBot
|
2
|
+
def add_memo_team(user, privacy, team_name, topic, type, message)
|
3
|
+
save_stats(__method__)
|
4
|
+
|
5
|
+
get_teams()
|
6
|
+
if @teams.key?(team_name.to_sym)
|
7
|
+
assigned_members = @teams[team_name.to_sym].members.values.flatten
|
8
|
+
assigned_members.uniq!
|
9
|
+
all_team_members = assigned_members.dup
|
10
|
+
team_members = []
|
11
|
+
if @teams[team_name.to_sym].channels.key?("members")
|
12
|
+
@teams[team_name.to_sym].channels["members"].each do |ch|
|
13
|
+
get_channels_name_and_id() unless @channels_id.key?(ch)
|
14
|
+
tm = get_channel_members(@channels_id[ch])
|
15
|
+
tm.each do |m|
|
16
|
+
user_info = @users.select { |u| u.id == m or (u.key?(:enterprise_user) and u.enterprise_user.id == m) }[-1]
|
17
|
+
team_members << user_info.name unless user_info.is_app_user or user_info.is_bot
|
18
|
+
end
|
19
|
+
end
|
20
|
+
end
|
21
|
+
team_members.flatten!
|
22
|
+
team_members.uniq!
|
23
|
+
all_team_members += team_members
|
24
|
+
all_team_members.uniq!
|
25
|
+
end
|
26
|
+
if type == "jira"
|
27
|
+
able_to_connect_jira = false
|
28
|
+
begin
|
29
|
+
http = NiceHttp.new(config.jira.host)
|
30
|
+
http.headers.authorization = NiceHttpUtils.basic_authentication(user: config.jira.user, password: config.jira.password)
|
31
|
+
message.gsub!(/^\s*</, "")
|
32
|
+
message.gsub!(/\>$/, "")
|
33
|
+
message.gsub!(/\|.+$/, "")
|
34
|
+
message.gsub!(/^#{config.jira.host}/, "")
|
35
|
+
if message.include?("/browse/")
|
36
|
+
message = message.scan(/\/browse\/(.+)/).join
|
37
|
+
resp = http.get("/rest/api/latest/issue/#{message}")
|
38
|
+
else
|
39
|
+
message.gsub!(/^\/issues\/\?jql=/, "")
|
40
|
+
message.gsub!(" ", "%20")
|
41
|
+
resp = http.get("/rest/api/latest/search/?jql=#{message}")
|
42
|
+
end
|
43
|
+
if resp.code == 200
|
44
|
+
able_to_connect_jira = true
|
45
|
+
else
|
46
|
+
error_code = resp.code
|
47
|
+
if resp.code == 400
|
48
|
+
error_message = resp.data.json(:errorMessages)[-1]
|
49
|
+
else
|
50
|
+
error_message = ""
|
51
|
+
end
|
52
|
+
end
|
53
|
+
http.close
|
54
|
+
rescue => exception
|
55
|
+
@logger.fatal exception
|
56
|
+
end
|
57
|
+
elsif type == "github"
|
58
|
+
able_to_connect_github = false
|
59
|
+
begin
|
60
|
+
http = NiceHttp.new(config.github.host)
|
61
|
+
http.headers.authorization = "token #{config.github.token}"
|
62
|
+
message.gsub!(/^\s*</, "")
|
63
|
+
message.gsub!(/\>$/, "")
|
64
|
+
message.gsub!(/\|.+$/, "")
|
65
|
+
message.gsub!(/^#{config.github.host}/, "")
|
66
|
+
message.gsub!("https://github.com", "")
|
67
|
+
message.slice!(0) if message[0] == "/"
|
68
|
+
resp = http.get("/repos#{message}")
|
69
|
+
if resp.code == 200
|
70
|
+
able_to_connect_github = true
|
71
|
+
else
|
72
|
+
error_code = resp.code
|
73
|
+
if resp.code == 401
|
74
|
+
error_message = resp.data.json(:message)[-1]
|
75
|
+
else
|
76
|
+
error_message = ""
|
77
|
+
end
|
78
|
+
end
|
79
|
+
http.close
|
80
|
+
rescue => exception
|
81
|
+
@logger.fatal exception
|
82
|
+
end
|
83
|
+
end
|
84
|
+
|
85
|
+
if !@teams.key?(team_name.to_sym)
|
86
|
+
respond "It seems like the team *#{team_name}* doesn't exist\nRelated commands `add team TEAM_NAME PROPERTIES`, `see team TEAM_NAME`, `see teams`"
|
87
|
+
elsif !(all_team_members + config.masters).flatten.include?(user.name)
|
88
|
+
respond "You have to be a member of the team or a Master admin to be able to add a memo to the team."
|
89
|
+
elsif type == "jira" and !able_to_connect_jira
|
90
|
+
if error_message == ""
|
91
|
+
respond "You need to supply the correct credentials for JIRA on the SmartBot settings: `jira: { host: HOST, user: USER, password: PASSWORD }` and a correct JQL string or JQL url"
|
92
|
+
else
|
93
|
+
respond "You need to supply a correct JQL string or JQL url: #{error_message}"
|
94
|
+
end
|
95
|
+
else
|
96
|
+
topic = :no_topic if topic == ""
|
97
|
+
@teams[team_name.to_sym][:memos] ||= []
|
98
|
+
if @teams[team_name.to_sym][:memos].empty?
|
99
|
+
memo_id = 1
|
100
|
+
else
|
101
|
+
memo_id = @teams[team_name.to_sym][:memos].memo_id.flatten.max + 1
|
102
|
+
end
|
103
|
+
@teams[team_name.to_sym][:memos] << {
|
104
|
+
memo_id: memo_id,
|
105
|
+
topic: topic,
|
106
|
+
type: type,
|
107
|
+
privacy: privacy,
|
108
|
+
user: user.name,
|
109
|
+
date: Time.now.strftime("%Y-%m-%dT%H:%M:%S.000Z")[0..18],
|
110
|
+
message: message,
|
111
|
+
status: ':new: '
|
112
|
+
}
|
113
|
+
update_teams()
|
114
|
+
respond "The memo has been added to *#{team_name}* team."
|
115
|
+
end
|
116
|
+
end
|
117
|
+
end
|
@@ -0,0 +1,80 @@
|
|
1
|
+
class SlackSmartBot
|
2
|
+
def add_team(user, name, options, info)
|
3
|
+
save_stats(__method__)
|
4
|
+
|
5
|
+
get_teams()
|
6
|
+
if @teams.key?(name.to_sym)
|
7
|
+
respond "It seems like the team *#{name}* already exists.\nRelated commands `update team TEAM_NAME PROPERTIES`, `delete team TEAM_NAME`, `see team TEAM_NAME`, `see teams`"
|
8
|
+
else
|
9
|
+
wrong = false
|
10
|
+
team = { members: {}, channels: {} }
|
11
|
+
last_type = nil
|
12
|
+
type_detected = false
|
13
|
+
options.split(/\s+/).each do |opt|
|
14
|
+
type_detected = false
|
15
|
+
if opt.match?(/^\s*$/)
|
16
|
+
#blank
|
17
|
+
elsif opt.match?(/^[\w\-]+$/i)
|
18
|
+
last_type = opt
|
19
|
+
type_detected = true
|
20
|
+
elsif opt.match(/<@(\w+)>/i)
|
21
|
+
team[:members][last_type] ||= []
|
22
|
+
if last_type.nil?
|
23
|
+
wrong = true
|
24
|
+
respond "You need to specify the TYPE for the member."
|
25
|
+
break
|
26
|
+
else
|
27
|
+
member_id = $1
|
28
|
+
member_info = @users.select { |u| u.id == member_id or (u.key?(:enterprise_user) and u.enterprise_user.id == member_id) }[-1]
|
29
|
+
if member_info.nil?
|
30
|
+
@users = get_users()
|
31
|
+
member_info = @users.select { |u| u.id == member_id or (u.key?(:enterprise_user) and u.enterprise_user.id == member_id) }[-1]
|
32
|
+
end
|
33
|
+
team[:members][last_type] << member_info.name
|
34
|
+
end
|
35
|
+
elsif opt.match(/<#(\w+)\|[^>]*>/i)
|
36
|
+
team[:channels][last_type] ||= []
|
37
|
+
if last_type.nil?
|
38
|
+
wrong = true
|
39
|
+
respond "You need to specify the TYPE for the channel."
|
40
|
+
break
|
41
|
+
else
|
42
|
+
channel_id = $1
|
43
|
+
get_channels_name_and_id() unless @channels_name.keys.include?(channel_id)
|
44
|
+
channel = @channels_name[channel_id]
|
45
|
+
channel_members = get_channel_members(channel_id) unless channel.nil?
|
46
|
+
if channel.nil? or !channel_members.include?(config.nick_id)
|
47
|
+
respond ":exclamation: Add the Smart Bot to *<##{channel_id}>* channel first."
|
48
|
+
wrong = true
|
49
|
+
break
|
50
|
+
else
|
51
|
+
team[:channels][last_type] << channel
|
52
|
+
end
|
53
|
+
end
|
54
|
+
else
|
55
|
+
respond "It seems like the members or channel list is not correct. Please double check."
|
56
|
+
wrong = true
|
57
|
+
break
|
58
|
+
end
|
59
|
+
end
|
60
|
+
if type_detected #type added but not added a channel or user
|
61
|
+
respond "It seems like the parameters supplied are not correct. Please double check."
|
62
|
+
wrong = true
|
63
|
+
end
|
64
|
+
|
65
|
+
unless wrong
|
66
|
+
get_teams()
|
67
|
+
team[:info] = info
|
68
|
+
team[:status] = :added
|
69
|
+
team[:user] = user.name
|
70
|
+
team[:creator] = user.name
|
71
|
+
team[:date] = Time.now.strftime("%Y-%m-%dT%H:%M:%S.000Z")[0..18]
|
72
|
+
new_team = {}
|
73
|
+
new_team[name.to_sym] = team
|
74
|
+
update_teams(new_team)
|
75
|
+
respond "The *#{name}* team has been added."
|
76
|
+
see_teams(user, name, add_stats: false)
|
77
|
+
end
|
78
|
+
end
|
79
|
+
end
|
80
|
+
end
|
@@ -0,0 +1,51 @@
|
|
1
|
+
class SlackSmartBot
|
2
|
+
|
3
|
+
def add_vacation(user, type, from, to)
|
4
|
+
save_stats(__method__)
|
5
|
+
get_vacations()
|
6
|
+
from.gsub!('-','/')
|
7
|
+
to.gsub!('-','/')
|
8
|
+
if type.match?(/sick\s+baby/i) or type.match?(/sick\s+child/i)
|
9
|
+
type = 'sick child'
|
10
|
+
end
|
11
|
+
|
12
|
+
if from=='today'
|
13
|
+
from = Date.today.strftime("%Y/%m/%d")
|
14
|
+
elsif from =='tomorrow'
|
15
|
+
from = (Date.today+1).strftime("%Y/%m/%d")
|
16
|
+
elsif from.match?(/next\s+week/)
|
17
|
+
from = Date.today + ((1 - Date.today.wday) % 7)
|
18
|
+
to = (from + 6).strftime("%Y/%m/%d")
|
19
|
+
from = from.strftime("%Y/%m/%d")
|
20
|
+
end
|
21
|
+
|
22
|
+
to = from if to.empty?
|
23
|
+
wrong = false
|
24
|
+
begin
|
25
|
+
from_date = Date.parse(from)
|
26
|
+
to_date = Date.parse(to)
|
27
|
+
rescue
|
28
|
+
wrong = true
|
29
|
+
respond "It seems like the date is not in the correct format: YYYY/MM/DD or is a wrong date."
|
30
|
+
end
|
31
|
+
unless wrong
|
32
|
+
if Date.parse(from).strftime("%Y/%m/%d") != from
|
33
|
+
respond "It seems like the date #{from} is not in the correct format: YYYY/MM/DD or is a wrong date."
|
34
|
+
elsif Date.parse(to).strftime("%Y/%m/%d") != to
|
35
|
+
respond "It seems like the date #{to} is not in the correct format: YYYY/MM/DD or is a wrong date."
|
36
|
+
else
|
37
|
+
vacations = @vacations.deep_copy
|
38
|
+
vacations[user.name] ||= { user_id: user.id, periods: [] }
|
39
|
+
if vacations[user.name].periods.empty?
|
40
|
+
vacation_id = 1
|
41
|
+
else
|
42
|
+
vacation_id = vacations[user.name].periods[-1].vacation_id + 1
|
43
|
+
end
|
44
|
+
vacations[user.name].periods << { vacation_id: vacation_id, type: type.downcase, from: from, to: to }
|
45
|
+
update_vacations({user.name => vacations[user.name]})
|
46
|
+
respond "Period has been added ##{vacation_id}"
|
47
|
+
check_vacations(date: Date.today, user: user.name, set_status: true, only_first_day: false)
|
48
|
+
end
|
49
|
+
end
|
50
|
+
end
|
51
|
+
end
|
@@ -0,0 +1,67 @@
|
|
1
|
+
class SlackSmartBot
|
2
|
+
def allow_access(user, command_id, opt)
|
3
|
+
save_stats(__method__)
|
4
|
+
not_allowed = ["hi_bot", "bye_bot", "allow_access", "deny_access", "get_bot_logs", "add_routine", "pause_bot", "pause_routine", "remove_routine", "run_routine", "start_bot",
|
5
|
+
"start_routine", "delete_message", "send_message", "kill_bot_on_channel", "exit_bot", "notify_message", "publish_announcements", "set_general_message",
|
6
|
+
"set_maintenance", "bot_help", "bot_rules"]
|
7
|
+
if !is_admin?(user.name)
|
8
|
+
respond "Only admins of this channel can use this command. Take a look who is an admin of this channel by calling `see admins`"
|
9
|
+
elsif Thread.current[:dest][0] == "D"
|
10
|
+
respond "This command cannot be called from a DM"
|
11
|
+
elsif not_allowed.include?(command_id)
|
12
|
+
respond "Sorry but the access for `#{command_id}` cannot be changed."
|
13
|
+
else
|
14
|
+
if Thread.current[:typem] == :on_call
|
15
|
+
channel = Thread.current[:dchannel]
|
16
|
+
elsif Thread.current[:using_channel].to_s == ""
|
17
|
+
channel = Thread.current[:dest]
|
18
|
+
else
|
19
|
+
channel = Thread.current[:using_channel]
|
20
|
+
end
|
21
|
+
command_ids = get_command_ids()
|
22
|
+
if command_ids.values.flatten.include?(command_id)
|
23
|
+
wrong_user = false
|
24
|
+
access_users = []
|
25
|
+
opt.each do |o|
|
26
|
+
if o.match(/\A\s*<@([^>]+)>\s*\z/)
|
27
|
+
access_users << $1
|
28
|
+
else
|
29
|
+
respond "Hmm, I've done some research on this and it looks like #{o} is not a valid Slack user.\nMake sure you are writing @USER and it is recognized by *Slack*\n"
|
30
|
+
wrong_user = true
|
31
|
+
break
|
32
|
+
end
|
33
|
+
end
|
34
|
+
unless wrong_user
|
35
|
+
if !@access_channels.key?(channel)
|
36
|
+
@access_channels[channel] = {}
|
37
|
+
end
|
38
|
+
|
39
|
+
if access_users.empty? # all users will be able to access
|
40
|
+
@access_channels[channel].delete(command_id)
|
41
|
+
else
|
42
|
+
if @access_channels.key?(channel) and !@access_channels[channel].key?(command_id)
|
43
|
+
@access_channels[channel][command_id] = []
|
44
|
+
end
|
45
|
+
access_users_names = []
|
46
|
+
access_users.each do |us|
|
47
|
+
user_info = @users.select { |u| u.id == us or (u.key?(:enterprise_user) and u.enterprise_user.id == us) }[-1]
|
48
|
+
access_users_names << user_info.name unless user_info.nil?
|
49
|
+
end
|
50
|
+
@access_channels[channel][command_id] += access_users_names
|
51
|
+
@access_channels[channel][command_id].flatten!
|
52
|
+
@access_channels[channel][command_id].uniq!
|
53
|
+
@access_channels[channel][command_id].delete(nil)
|
54
|
+
end
|
55
|
+
update_access_channels()
|
56
|
+
if !@access_channels[channel].key?(command_id)
|
57
|
+
respond "All users will have access to this command on this channel."
|
58
|
+
else
|
59
|
+
respond "These users will have access to this command on this channel: <@#{@access_channels[channel][command_id].join(">, <@")}>"
|
60
|
+
end
|
61
|
+
end
|
62
|
+
else
|
63
|
+
respond "It seems like #{command_id} is not valid. Please be sure that exists by calling `see command ids`"
|
64
|
+
end
|
65
|
+
end
|
66
|
+
end
|
67
|
+
end
|
@@ -1,6 +1,6 @@
|
|
1
1
|
class SlackSmartBot
|
2
2
|
|
3
|
-
def bot_help(user, from, dest, dchannel, specific, help_command, rules_file, savestats
|
3
|
+
def bot_help(user, from, dest, dchannel, specific, help_command, rules_file, savestats: true, strict: false)
|
4
4
|
save_stats(__method__) if savestats
|
5
5
|
output = []
|
6
6
|
if has_access?(__method__, user)
|
@@ -21,16 +21,25 @@ class SlackSmartBot
|
|
21
21
|
commands_search = []
|
22
22
|
if help_command.to_s != ""
|
23
23
|
help_message.gsub(/====+/,'-'*30).split(/^\s*-------*$/).each do |h|
|
24
|
-
if
|
25
|
-
|
26
|
-
|
27
|
-
|
28
|
-
|
29
|
-
|
30
|
-
|
31
|
-
|
32
|
-
|
33
|
-
|
24
|
+
if strict
|
25
|
+
if h.match?(/`#{help_command}`/i) or h.match?(/^\s*command_id:\s+:#{help_command.gsub(' ', '_')}\s*$/)
|
26
|
+
output << h
|
27
|
+
help_found = true
|
28
|
+
commands << h
|
29
|
+
break
|
30
|
+
end
|
31
|
+
else
|
32
|
+
if h.match?(/[`_]#{help_command}/i) or h.match?(/^\s*command_id:\s+:#{help_command.gsub(' ', '_')}\s*$/)
|
33
|
+
output << h
|
34
|
+
help_found = true
|
35
|
+
commands << h
|
36
|
+
elsif !h.match?(/\A\s*\*/) and !h.match?(/\A\s*=+/) #to avoid general messages for bot help *General commands...*
|
37
|
+
all_found = true
|
38
|
+
help_command.to_s.split(' ') do |hc|
|
39
|
+
unless hc.match?(/^\s*\z/)
|
40
|
+
if !h.match?(/#{hc}/i)
|
41
|
+
all_found = false
|
42
|
+
end
|
34
43
|
end
|
35
44
|
end
|
36
45
|
end
|
@@ -8,7 +8,7 @@ class SlackSmartBot
|
|
8
8
|
else
|
9
9
|
channel = Thread.current[:dest]
|
10
10
|
end
|
11
|
-
if File.
|
11
|
+
if File.exist?("#{config.path}/announcements/#{channel}.csv") and !@announcements.key?(channel)
|
12
12
|
t = CSV.table("#{config.path}/announcements/#{channel}.csv", headers: ['message_id', 'user_deleted', 'user_created', 'date', 'time', 'type', 'message'])
|
13
13
|
@announcements[channel] = t
|
14
14
|
end
|
@@ -0,0 +1,69 @@
|
|
1
|
+
class SlackSmartBot
|
2
|
+
def delete_memo_team(user, team_name, memo_id)
|
3
|
+
save_stats(__method__) if answer.empty?
|
4
|
+
|
5
|
+
get_teams()
|
6
|
+
if @teams.key?(team_name.to_sym)
|
7
|
+
assigned_members = @teams[team_name.to_sym].members.values.flatten
|
8
|
+
assigned_members.uniq!
|
9
|
+
all_team_members = assigned_members.dup
|
10
|
+
team_members = []
|
11
|
+
if @teams[team_name.to_sym].channels.key?("members")
|
12
|
+
@teams[team_name.to_sym].channels["members"].each do |ch|
|
13
|
+
get_channels_name_and_id() unless @channels_id.key?(ch)
|
14
|
+
tm = get_channel_members(@channels_id[ch])
|
15
|
+
tm.each do |m|
|
16
|
+
user_info = @users.select { |u| u.id == m or (u.key?(:enterprise_user) and u.enterprise_user.id == m) }[-1]
|
17
|
+
team_members << user_info.name unless user_info.is_app_user or user_info.is_bot
|
18
|
+
end
|
19
|
+
end
|
20
|
+
end
|
21
|
+
team_members.flatten!
|
22
|
+
team_members.uniq!
|
23
|
+
all_team_members += team_members
|
24
|
+
all_team_members.uniq!
|
25
|
+
end
|
26
|
+
|
27
|
+
if !@teams.key?(team_name.to_sym)
|
28
|
+
respond "It seems like the team *#{team_name}* doesn't exist.\nRelated commands `add team TEAM_NAME PROPERTIES`, `see team TEAM_NAME`, `see teams`"
|
29
|
+
elsif !(all_team_members + config.masters).flatten.include?(user.name)
|
30
|
+
respond "You have to be a member of the team or a Master admin to be able to delete a memo of the team."
|
31
|
+
elsif !@teams[team_name.to_sym].key?(:memos) or @teams[team_name.to_sym][:memos].empty? or !@teams[team_name.to_sym][:memos].memo_id.include?(memo_id.to_i)
|
32
|
+
respond "It seems like there is no memo with id #{memo_id}"
|
33
|
+
elsif @teams[team_name.to_sym][:memos].memo_id.include?(memo_id.to_i)
|
34
|
+
memo_selected = @teams[team_name.to_sym][:memos].select { |m| m.memo_id == memo_id.to_i }[-1]
|
35
|
+
if memo_selected.privacy == 'personal' and memo_selected.user != user.name
|
36
|
+
respond "Only the creator can delete a personal memo."
|
37
|
+
else
|
38
|
+
if answer.empty?
|
39
|
+
message = @teams[team_name.to_sym][:memos].select { |memo| memo.memo_id == memo_id.to_i }.message.join
|
40
|
+
ask "do you really want to delete the memo #{memo_id} (#{message}) from #{team_name} team? (yes/no)"
|
41
|
+
else
|
42
|
+
case answer
|
43
|
+
when /yes/i, /yep/i, /sure/i
|
44
|
+
answer_delete
|
45
|
+
memos = []
|
46
|
+
message = ""
|
47
|
+
get_teams()
|
48
|
+
@teams[team_name.to_sym][:memos].each do |memo|
|
49
|
+
if memo.memo_id != memo_id.to_i
|
50
|
+
memos << memo
|
51
|
+
else
|
52
|
+
message = memo.message
|
53
|
+
end
|
54
|
+
end
|
55
|
+
@teams[team_name.to_sym][:memos] = memos
|
56
|
+
update_teams()
|
57
|
+
respond "The memo has been deleted from team #{team_name}: #{message}"
|
58
|
+
when /no/i, /nope/i, /cancel/i
|
59
|
+
answer_delete
|
60
|
+
respond "Ok, the memo was not deleted"
|
61
|
+
else
|
62
|
+
respond "I don't understand"
|
63
|
+
ask "do you really want to delete the memo from #{team_name} team? (yes/no)"
|
64
|
+
end
|
65
|
+
end
|
66
|
+
end
|
67
|
+
end
|
68
|
+
end
|
69
|
+
end
|
@@ -8,7 +8,7 @@ class SlackSmartBot
|
|
8
8
|
else
|
9
9
|
channel = Thread.current[:dest]
|
10
10
|
end
|
11
|
-
if File.
|
11
|
+
if File.exist?("#{config.path}/shares/#{@channels_name[channel]}.csv") and !@shares.key?(@channels_name[channel])
|
12
12
|
t = CSV.table("#{config.path}/shares/#{@channels_name[channel]}.csv", headers: ['share_id', 'user_deleted', 'user_created', 'date', 'time', 'type', 'to_channel', 'condition'])
|
13
13
|
@shares[@channels_name[channel]] = t
|
14
14
|
end
|
@@ -0,0 +1,54 @@
|
|
1
|
+
class SlackSmartBot
|
2
|
+
def delete_team(user, team_name)
|
3
|
+
save_stats(__method__) if answer.empty?
|
4
|
+
|
5
|
+
if Thread.current[:dest][0] == "D"
|
6
|
+
respond "This command cannot be called from a DM"
|
7
|
+
else
|
8
|
+
get_teams()
|
9
|
+
if @teams.key?(team_name.to_sym)
|
10
|
+
assigned_members = @teams[team_name.to_sym].members.values.flatten
|
11
|
+
assigned_members.uniq!
|
12
|
+
all_team_members = assigned_members.dup
|
13
|
+
team_members = []
|
14
|
+
if @teams[team_name.to_sym].channels.key?("members")
|
15
|
+
@teams[team_name.to_sym].channels["members"].each do |ch|
|
16
|
+
get_channels_name_and_id() unless @channels_id.key?(ch)
|
17
|
+
tm = get_channel_members(@channels_id[ch])
|
18
|
+
tm.each do |m|
|
19
|
+
user_info = @users.select { |u| u.id == m or (u.key?(:enterprise_user) and u.enterprise_user.id == m) }[-1]
|
20
|
+
team_members << user_info.name unless user_info.is_app_user or user_info.is_bot
|
21
|
+
end
|
22
|
+
end
|
23
|
+
end
|
24
|
+
team_members.flatten!
|
25
|
+
team_members.uniq!
|
26
|
+
all_team_members += team_members
|
27
|
+
all_team_members.uniq!
|
28
|
+
end
|
29
|
+
if !@teams.key?(team_name.to_sym)
|
30
|
+
respond "It seems like the team *#{team_name}* doesn't exist.\nRelated commands `add team TEAM_NAME PROPERTIES`, `see team TEAM_NAME`, `see teams`"
|
31
|
+
elsif !(all_team_members + [@teams[team_name.to_sym].creator] + config.masters).flatten.include?(user.name)
|
32
|
+
respond "You have to be a member of the team, the creator or a Master admin to be able to delete this team."
|
33
|
+
else
|
34
|
+
if answer.empty?
|
35
|
+
ask "do you really want to delete the #{team_name} team? (yes/no)"
|
36
|
+
else
|
37
|
+
case answer
|
38
|
+
when /yes/i, /yep/i, /sure/i
|
39
|
+
answer_delete
|
40
|
+
@teams.delete(team_name.to_sym)
|
41
|
+
update_teams()
|
42
|
+
respond "The team #{team_name} has been deleted."
|
43
|
+
when /no/i, /nope/i, /cancel/i
|
44
|
+
answer_delete
|
45
|
+
respond "Ok, the team was not deleted"
|
46
|
+
else
|
47
|
+
respond "I don't understand"
|
48
|
+
ask "do you really want to delete the #{team_name} team? (yes/no)"
|
49
|
+
end
|
50
|
+
end
|
51
|
+
end
|
52
|
+
end
|
53
|
+
end
|
54
|
+
end
|
@@ -0,0 +1,36 @@
|
|
1
|
+
class SlackSmartBot
|
2
|
+
def deny_access(user, command_id)
|
3
|
+
save_stats(__method__)
|
4
|
+
not_allowed = ['hi_bot', 'bye_bot', "allow_access", "deny_access", "get_bot_logs", "add_routine", "pause_bot", "pause_routine", "remove_routine", "run_routine", "start_bot",
|
5
|
+
"start_routine", "delete_message", "send_message", "kill_bot_on_channel", "exit_bot", "notify_message", "publish_announcements", "set_general_message",
|
6
|
+
"set_maintenance", 'bot_help', 'bot_rules']
|
7
|
+
if !is_admin?(user.name)
|
8
|
+
respond "Only admins of this channel can use this command. Take a look who is an admin of this channel by calling `see admins`"
|
9
|
+
elsif Thread.current[:dest][0] == "D"
|
10
|
+
respond "This command cannot be called from a DM"
|
11
|
+
elsif not_allowed.include?(command_id)
|
12
|
+
respond "Sorry but the access for `#{command_id}` cannot be changed."
|
13
|
+
else
|
14
|
+
if Thread.current[:typem] == :on_call
|
15
|
+
channel = Thread.current[:dchannel]
|
16
|
+
elsif Thread.current[:using_channel].to_s == ""
|
17
|
+
channel = Thread.current[:dest]
|
18
|
+
else
|
19
|
+
channel = Thread.current[:using_channel]
|
20
|
+
end
|
21
|
+
command_ids = get_command_ids()
|
22
|
+
if command_ids.values.flatten.include?(command_id)
|
23
|
+
if !@access_channels.key?(channel)
|
24
|
+
@access_channels[channel] = {}
|
25
|
+
end
|
26
|
+
|
27
|
+
@access_channels[channel][command_id] = []
|
28
|
+
|
29
|
+
update_access_channels()
|
30
|
+
respond "The command `#{command_id}` won't be available in this channel. Call `allow access #{command_id}` if you want it back."
|
31
|
+
else
|
32
|
+
respond "It seems like #{command_id} is not valid. Please be sure that exists by calling `see command ids`"
|
33
|
+
end
|
34
|
+
end
|
35
|
+
end
|
36
|
+
end
|
@@ -0,0 +1,100 @@
|
|
1
|
+
class SlackSmartBot
|
2
|
+
def ping_team(user, type, team_name, member_type, message)
|
3
|
+
if type == :ping
|
4
|
+
save_stats(:ping_team)
|
5
|
+
icon = ':large_green_circle:'
|
6
|
+
else
|
7
|
+
save_stats(:contact_team)
|
8
|
+
icon = ':email:'
|
9
|
+
end
|
10
|
+
if Thread.current[:dest][0] == "D"
|
11
|
+
respond "This command cannot be called from a DM"
|
12
|
+
else
|
13
|
+
get_teams()
|
14
|
+
if !@teams.key?(team_name.to_sym)
|
15
|
+
respond "It seems like the team *#{team_name}* doesn't exist.\nRelated commands `add team TEAM_NAME PROPERTIES`, `see team TEAM_NAME`, `see teams`"
|
16
|
+
else
|
17
|
+
team = @teams[team_name.to_sym].deep_copy
|
18
|
+
|
19
|
+
assigned_members = team.members.values.flatten
|
20
|
+
assigned_members.uniq!
|
21
|
+
assigned_members.dup.each do |m|
|
22
|
+
user_info = @users.select { |u| u.id == m or (u.key?(:enterprise_user) and u.enterprise_user.id == m) or u.name == m or (u.key?(:enterprise_user) and u.enterprise_user.name == m) }[-1]
|
23
|
+
assigned_members.delete(m) if user_info.nil? or user_info.deleted
|
24
|
+
end
|
25
|
+
unassigned_members = []
|
26
|
+
not_on_team_channel = []
|
27
|
+
|
28
|
+
if ((!team.members.key?(member_type) or member_type == 'all') and team.channels.key?("members"))
|
29
|
+
team_members = []
|
30
|
+
team.channels["members"].each do |ch|
|
31
|
+
get_channels_name_and_id() unless @channels_id.key?(ch)
|
32
|
+
tm = get_channel_members(@channels_id[ch])
|
33
|
+
tm.each do |m|
|
34
|
+
user_info = @users.select { |u| u.id == m or (u.key?(:enterprise_user) and u.enterprise_user.id == m) }[-1]
|
35
|
+
team_members << user_info.name unless user_info.nil? or user_info.is_app_user or user_info.is_bot or user_info.deleted
|
36
|
+
end
|
37
|
+
end
|
38
|
+
team_members.flatten!
|
39
|
+
team_members.uniq!
|
40
|
+
unassigned_members = team_members - assigned_members
|
41
|
+
unassigned_members.delete(config.nick)
|
42
|
+
|
43
|
+
unless unassigned_members.empty?
|
44
|
+
um = unassigned_members.dup
|
45
|
+
um.each do |m|
|
46
|
+
user_info = @users.select { |u| u.name == m or (u.key?(:enterprise_user) and u.enterprise_user.name == m) }[-1]
|
47
|
+
unless user_info.nil? or user_info.profile.title.to_s=='' or user_info.deleted
|
48
|
+
team.members[user_info.profile.title.to_snake_case] ||= []
|
49
|
+
team.members[user_info.profile.title.to_snake_case] << m
|
50
|
+
unassigned_members.delete(m)
|
51
|
+
end
|
52
|
+
end
|
53
|
+
unless unassigned_members.empty?
|
54
|
+
team.members["unassigned"] ||= []
|
55
|
+
team.members["unassigned"] += unassigned_members
|
56
|
+
team.members["unassigned"].sort!
|
57
|
+
end
|
58
|
+
end
|
59
|
+
end
|
60
|
+
|
61
|
+
if team.members.key?(member_type) or member_type=='all'
|
62
|
+
if member_type == 'all'
|
63
|
+
members_list = team.members.values.flatten.uniq.shuffle
|
64
|
+
else
|
65
|
+
members_list = team.members[member_type].shuffle
|
66
|
+
end
|
67
|
+
if type == :ping
|
68
|
+
active_members = []
|
69
|
+
members_list.each do |member|
|
70
|
+
member_info = @users.select { |u| u.name == member }[-1]
|
71
|
+
unless member_info.nil? or member_info.deleted
|
72
|
+
active = (get_presence(member_info.id).presence.to_s == "active")
|
73
|
+
active_members << member if active
|
74
|
+
end
|
75
|
+
end
|
76
|
+
members = active_members
|
77
|
+
else
|
78
|
+
members = members_list
|
79
|
+
end
|
80
|
+
members.dup.each do |m|
|
81
|
+
user_info = @users.select { |u| u.id == m or (u.key?(:enterprise_user) and u.enterprise_user.id == m) or u.name == m or (u.key?(:enterprise_user) and u.enterprise_user.name == m) }[-1]
|
82
|
+
members.delete(m) if user_info.nil? or user_info.deleted
|
83
|
+
end
|
84
|
+
|
85
|
+
if members.size > 0
|
86
|
+
respond "#{icon} *#{type} #{team_name} team #{member_type}*\nfrom <@#{user.name}>\nto <@#{members[0..9].join('>, <@')}>#{", #{members[10..-1].join(', ')}" if members.size > 10} \n> #{message.split("\n").join("\n> ")}"
|
87
|
+
elsif type == :ping
|
88
|
+
respond "It seems like there are no available #{member_type} members on #{team_name} team. Please call `see team #{team_name}`"
|
89
|
+
else
|
90
|
+
respond "It seems like there are no #{member_type} members on #{team_name} team. Please call `see team #{team_name}`"
|
91
|
+
end
|
92
|
+
else
|
93
|
+
respond "The member type #{member_type} doesn't exist, please call `see team #{team_name}`"
|
94
|
+
end
|
95
|
+
|
96
|
+
|
97
|
+
end
|
98
|
+
end
|
99
|
+
end
|
100
|
+
end
|