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,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
|