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.
Files changed (116) hide show
  1. checksums.yaml +4 -4
  2. data/README.md +134 -23
  3. data/lib/slack/smart-bot/comm/delete.rb +13 -0
  4. data/lib/slack/smart-bot/comm/dont_understand.rb +2 -2
  5. data/lib/slack/smart-bot/comm/get_channel_members.rb +7 -3
  6. data/lib/slack/smart-bot/comm/get_presence.rb +20 -0
  7. data/lib/slack/smart-bot/comm/get_users.rb +1 -1
  8. data/lib/slack/smart-bot/comm/respond.rb +24 -13
  9. data/lib/slack/smart-bot/comm/send_msg_user.rb +12 -11
  10. data/lib/slack/smart-bot/comm/set_status.rb +21 -0
  11. data/lib/slack/smart-bot/comm.rb +3 -0
  12. data/lib/slack/smart-bot/commands/general/add_admin.rb +51 -0
  13. data/lib/slack/smart-bot/commands/general/add_announcement.rb +1 -1
  14. data/lib/slack/smart-bot/commands/general/add_memo_team.rb +117 -0
  15. data/lib/slack/smart-bot/commands/general/add_team.rb +80 -0
  16. data/lib/slack/smart-bot/commands/general/add_vacation.rb +51 -0
  17. data/lib/slack/smart-bot/commands/general/allow_access.rb +67 -0
  18. data/lib/slack/smart-bot/commands/general/bot_help.rb +20 -11
  19. data/lib/slack/smart-bot/commands/general/delete_announcement.rb +1 -1
  20. data/lib/slack/smart-bot/commands/general/delete_memo_team.rb +69 -0
  21. data/lib/slack/smart-bot/commands/general/delete_share.rb +1 -1
  22. data/lib/slack/smart-bot/commands/general/delete_team.rb +54 -0
  23. data/lib/slack/smart-bot/commands/general/deny_access.rb +36 -0
  24. data/lib/slack/smart-bot/commands/general/ping_team.rb +100 -0
  25. data/lib/slack/smart-bot/commands/general/poster.rb +116 -0
  26. data/lib/slack/smart-bot/commands/general/remove_admin.rb +58 -0
  27. data/lib/slack/smart-bot/commands/general/remove_vacation.rb +27 -0
  28. data/lib/slack/smart-bot/commands/general/see_access.rb +24 -0
  29. data/lib/slack/smart-bot/commands/general/see_admins.rb +33 -0
  30. data/lib/slack/smart-bot/commands/general/see_announcements.rb +7 -5
  31. data/lib/slack/smart-bot/commands/general/see_command_ids.rb +29 -0
  32. data/lib/slack/smart-bot/commands/general/see_favorite_commands.rb +3 -4
  33. data/lib/slack/smart-bot/commands/general/see_statuses.rb +34 -21
  34. data/lib/slack/smart-bot/commands/general/see_teams.rb +402 -0
  35. data/lib/slack/smart-bot/commands/general/see_vacations.rb +58 -0
  36. data/lib/slack/smart-bot/commands/general/see_vacations_team.rb +136 -0
  37. data/lib/slack/smart-bot/commands/general/set_memo_status.rb +58 -0
  38. data/lib/slack/smart-bot/commands/general/share_messages.rb +1 -1
  39. data/lib/slack/smart-bot/commands/general/update_team.rb +130 -0
  40. data/lib/slack/smart-bot/commands/general_bot_commands.rb +442 -13
  41. data/lib/slack/smart-bot/commands/on_bot/add_shortcut.rb +2 -1
  42. data/lib/slack/smart-bot/commands/on_bot/admin/add_routine.rb +2 -1
  43. data/lib/slack/smart-bot/commands/on_bot/admin/extend_rules.rb +2 -1
  44. data/lib/slack/smart-bot/commands/on_bot/admin/pause_bot.rb +2 -1
  45. data/lib/slack/smart-bot/commands/on_bot/admin/pause_routine.rb +2 -1
  46. data/lib/slack/smart-bot/commands/on_bot/admin/remove_routine.rb +2 -1
  47. data/lib/slack/smart-bot/commands/on_bot/admin/run_routine.rb +3 -2
  48. data/lib/slack/smart-bot/commands/on_bot/admin/see_result_routine.rb +2 -1
  49. data/lib/slack/smart-bot/commands/on_bot/admin/see_routines.rb +10 -9
  50. data/lib/slack/smart-bot/commands/on_bot/admin/start_bot.rb +2 -1
  51. data/lib/slack/smart-bot/commands/on_bot/admin/start_routine.rb +2 -1
  52. data/lib/slack/smart-bot/commands/on_bot/admin/stop_using_rules_on.rb +2 -1
  53. data/lib/slack/smart-bot/commands/on_bot/admin_master/delete_message.rb +25 -0
  54. data/lib/slack/smart-bot/commands/on_bot/admin_master/get_bot_logs.rb +1 -0
  55. data/lib/slack/smart-bot/commands/on_bot/admin_master/react_to.rb +3 -1
  56. data/lib/slack/smart-bot/commands/on_bot/admin_master/send_message.rb +15 -2
  57. data/lib/slack/smart-bot/commands/on_bot/delete_repl.rb +2 -1
  58. data/lib/slack/smart-bot/commands/on_bot/delete_shortcut.rb +5 -4
  59. data/lib/slack/smart-bot/commands/on_bot/general/bot_stats.rb +416 -0
  60. data/lib/slack/smart-bot/commands/{general → on_bot/general}/bot_status.rb +1 -0
  61. data/lib/slack/smart-bot/commands/{general → on_bot/general}/leaderboard.rb +1 -0
  62. data/lib/slack/smart-bot/commands/{general → on_bot/general}/stop_using_rules.rb +1 -0
  63. data/lib/slack/smart-bot/commands/{general → on_bot/general}/suggest_command.rb +6 -0
  64. data/lib/slack/smart-bot/commands/{general → on_bot/general}/use_rules.rb +1 -0
  65. data/lib/slack/smart-bot/commands/{general → on_bot/general}/whats_new.rb +2 -1
  66. data/lib/slack/smart-bot/commands/on_bot/get_repl.rb +2 -1
  67. data/lib/slack/smart-bot/commands/on_bot/kill_repl.rb +32 -0
  68. data/lib/slack/smart-bot/commands/on_bot/repl.rb +73 -15
  69. data/lib/slack/smart-bot/commands/on_bot/ruby_code.rb +1 -0
  70. data/lib/slack/smart-bot/commands/on_bot/run_repl.rb +117 -28
  71. data/lib/slack/smart-bot/commands/on_bot/see_repls.rb +2 -1
  72. data/lib/slack/smart-bot/commands/on_bot/see_shortcuts.rb +3 -2
  73. data/lib/slack/smart-bot/commands/on_master/admin/kill_bot_on_channel.rb +5 -4
  74. data/lib/slack/smart-bot/commands/on_master/admin_master/exit_bot.rb +3 -2
  75. data/lib/slack/smart-bot/commands/on_master/admin_master/notify_message.rb +2 -1
  76. data/lib/slack/smart-bot/commands/on_master/admin_master/publish_announcements.rb +6 -3
  77. data/lib/slack/smart-bot/commands/on_master/admin_master/set_general_message.rb +2 -1
  78. data/lib/slack/smart-bot/commands/on_master/admin_master/set_maintenance.rb +2 -1
  79. data/lib/slack/smart-bot/commands/on_master/create_bot.rb +1 -0
  80. data/lib/slack/smart-bot/commands/on_master/where_smartbot.rb +41 -0
  81. data/lib/slack/smart-bot/commands.rb +30 -7
  82. data/lib/slack/smart-bot/listen.rb +30 -30
  83. data/lib/slack/smart-bot/process.rb +53 -23
  84. data/lib/slack/smart-bot/process_first.rb +2 -2
  85. data/lib/slack/smart-bot/treat_message.rb +23 -17
  86. data/lib/slack/smart-bot/utils/build_help.rb +1 -1
  87. data/lib/slack/smart-bot/utils/check_vacations.rb +43 -0
  88. data/lib/slack/smart-bot/utils/create_routine_thread.rb +1 -1
  89. data/lib/slack/smart-bot/utils/get_access_channels.rb +13 -0
  90. data/lib/slack/smart-bot/utils/get_admins_channels.rb +33 -0
  91. data/lib/slack/smart-bot/utils/get_bots_created.rb +27 -10
  92. data/lib/slack/smart-bot/utils/get_channels_name_and_id.rb +7 -2
  93. data/lib/slack/smart-bot/utils/get_command_ids.rb +84 -0
  94. data/lib/slack/smart-bot/utils/get_help.rb +36 -19
  95. data/lib/slack/smart-bot/utils/get_repls.rb +22 -2
  96. data/lib/slack/smart-bot/utils/get_routines.rb +22 -2
  97. data/lib/slack/smart-bot/utils/get_teams.rb +22 -0
  98. data/lib/slack/smart-bot/utils/get_vacations.rb +22 -0
  99. data/lib/slack/smart-bot/utils/has_access.rb +25 -9
  100. data/lib/slack/smart-bot/utils/is_admin.rb +27 -0
  101. data/lib/slack/smart-bot/utils/save_stats.rb +52 -42
  102. data/lib/slack/smart-bot/utils/save_status.rb +22 -7
  103. data/lib/slack/smart-bot/utils/update_access_channels.rb +8 -0
  104. data/lib/slack/smart-bot/utils/update_admins_channels.rb +25 -0
  105. data/lib/slack/smart-bot/utils/update_bots_file.rb +28 -7
  106. data/lib/slack/smart-bot/utils/update_repls.rb +7 -4
  107. data/lib/slack/smart-bot/utils/update_routines.rb +9 -3
  108. data/lib/slack/smart-bot/utils/update_shortcuts_file.rb +13 -6
  109. data/lib/slack/smart-bot/utils/update_teams.rb +16 -0
  110. data/lib/slack/smart-bot/utils/update_vacations.rb +16 -0
  111. data/lib/slack/smart-bot/utils.rb +11 -0
  112. data/lib/slack-smart-bot.rb +50 -12
  113. data/lib/slack-smart-bot_general_commands.rb +16 -1
  114. data/whats_new.txt +12 -30
  115. metadata +78 -21
  116. 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=true)
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 h.match?(/[`_]#{help_command}/i) or h.match?(/^\s*command_id:\s+:#{help_command.gsub(' ', '_')}\s*$/)
25
- output << h
26
- help_found = true
27
- commands << h
28
- elsif !h.match?(/\A\s*\*/) and !h.match?(/\A\s*=+/) #to avoid general messages for bot help *General commands...*
29
- all_found = true
30
- help_command.to_s.split(' ') do |hc|
31
- unless hc.match?(/^\s*\z/)
32
- if !h.match?(/#{hc}/i)
33
- all_found = false
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.exists?("#{config.path}/announcements/#{channel}.csv") and !@announcements.key?(channel)
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.exists?("#{config.path}/shares/#{@channels_name[channel]}.csv") and !@shares.key?(@channels_name[channel])
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