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