slack-smart-bot 1.10.0 → 1.11.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (104) hide show
  1. checksums.yaml +4 -4
  2. data/README.md +91 -21
  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 +18 -13
  9. data/lib/slack/smart-bot/comm/send_msg_user.rb +12 -11
  10. data/lib/slack/smart-bot/comm.rb +2 -0
  11. data/lib/slack/smart-bot/commands/general/add_admin.rb +51 -0
  12. data/lib/slack/smart-bot/commands/general/add_announcement.rb +1 -1
  13. data/lib/slack/smart-bot/commands/general/add_team.rb +80 -0
  14. data/lib/slack/smart-bot/commands/general/allow_access.rb +67 -0
  15. data/lib/slack/smart-bot/commands/general/bot_help.rb +20 -11
  16. data/lib/slack/smart-bot/commands/general/delete_announcement.rb +1 -1
  17. data/lib/slack/smart-bot/commands/general/delete_share.rb +1 -1
  18. data/lib/slack/smart-bot/commands/general/delete_team.rb +34 -0
  19. data/lib/slack/smart-bot/commands/general/deny_access.rb +36 -0
  20. data/lib/slack/smart-bot/commands/general/ping_team.rb +100 -0
  21. data/lib/slack/smart-bot/commands/general/poster.rb +116 -0
  22. data/lib/slack/smart-bot/commands/general/remove_admin.rb +58 -0
  23. data/lib/slack/smart-bot/commands/general/see_access.rb +24 -0
  24. data/lib/slack/smart-bot/commands/general/see_admins.rb +33 -0
  25. data/lib/slack/smart-bot/commands/general/see_announcements.rb +6 -4
  26. data/lib/slack/smart-bot/commands/general/see_command_ids.rb +29 -0
  27. data/lib/slack/smart-bot/commands/general/see_favorite_commands.rb +3 -4
  28. data/lib/slack/smart-bot/commands/general/see_statuses.rb +34 -21
  29. data/lib/slack/smart-bot/commands/general/see_teams.rb +252 -0
  30. data/lib/slack/smart-bot/commands/general/share_messages.rb +1 -1
  31. data/lib/slack/smart-bot/commands/general/update_team.rb +109 -0
  32. data/lib/slack/smart-bot/commands/general_bot_commands.rb +271 -10
  33. data/lib/slack/smart-bot/commands/on_bot/add_shortcut.rb +2 -1
  34. data/lib/slack/smart-bot/commands/on_bot/admin/add_routine.rb +2 -1
  35. data/lib/slack/smart-bot/commands/on_bot/admin/extend_rules.rb +2 -1
  36. data/lib/slack/smart-bot/commands/on_bot/admin/pause_bot.rb +2 -1
  37. data/lib/slack/smart-bot/commands/on_bot/admin/pause_routine.rb +2 -1
  38. data/lib/slack/smart-bot/commands/on_bot/admin/remove_routine.rb +2 -1
  39. data/lib/slack/smart-bot/commands/on_bot/admin/run_routine.rb +3 -2
  40. data/lib/slack/smart-bot/commands/on_bot/admin/see_result_routine.rb +2 -1
  41. data/lib/slack/smart-bot/commands/on_bot/admin/see_routines.rb +10 -9
  42. data/lib/slack/smart-bot/commands/on_bot/admin/start_bot.rb +2 -1
  43. data/lib/slack/smart-bot/commands/on_bot/admin/start_routine.rb +2 -1
  44. data/lib/slack/smart-bot/commands/on_bot/admin/stop_using_rules_on.rb +2 -1
  45. data/lib/slack/smart-bot/commands/on_bot/admin_master/delete_message.rb +25 -0
  46. data/lib/slack/smart-bot/commands/on_bot/admin_master/get_bot_logs.rb +1 -0
  47. data/lib/slack/smart-bot/commands/on_bot/admin_master/react_to.rb +3 -1
  48. data/lib/slack/smart-bot/commands/on_bot/admin_master/send_message.rb +15 -2
  49. data/lib/slack/smart-bot/commands/on_bot/delete_repl.rb +2 -1
  50. data/lib/slack/smart-bot/commands/on_bot/delete_shortcut.rb +5 -4
  51. data/lib/slack/smart-bot/commands/on_bot/general/bot_stats.rb +400 -0
  52. data/lib/slack/smart-bot/commands/{general → on_bot/general}/bot_status.rb +1 -0
  53. data/lib/slack/smart-bot/commands/{general → on_bot/general}/leaderboard.rb +1 -0
  54. data/lib/slack/smart-bot/commands/{general → on_bot/general}/stop_using_rules.rb +1 -0
  55. data/lib/slack/smart-bot/commands/{general → on_bot/general}/suggest_command.rb +6 -0
  56. data/lib/slack/smart-bot/commands/{general → on_bot/general}/use_rules.rb +1 -0
  57. data/lib/slack/smart-bot/commands/{general → on_bot/general}/whats_new.rb +2 -1
  58. data/lib/slack/smart-bot/commands/on_bot/get_repl.rb +2 -1
  59. data/lib/slack/smart-bot/commands/on_bot/repl.rb +72 -15
  60. data/lib/slack/smart-bot/commands/on_bot/ruby_code.rb +1 -0
  61. data/lib/slack/smart-bot/commands/on_bot/run_repl.rb +11 -2
  62. data/lib/slack/smart-bot/commands/on_bot/see_repls.rb +2 -1
  63. data/lib/slack/smart-bot/commands/on_bot/see_shortcuts.rb +3 -2
  64. data/lib/slack/smart-bot/commands/on_master/admin/kill_bot_on_channel.rb +5 -4
  65. data/lib/slack/smart-bot/commands/on_master/admin_master/exit_bot.rb +3 -2
  66. data/lib/slack/smart-bot/commands/on_master/admin_master/notify_message.rb +2 -1
  67. data/lib/slack/smart-bot/commands/on_master/admin_master/publish_announcements.rb +3 -2
  68. data/lib/slack/smart-bot/commands/on_master/admin_master/set_general_message.rb +2 -1
  69. data/lib/slack/smart-bot/commands/on_master/admin_master/set_maintenance.rb +2 -1
  70. data/lib/slack/smart-bot/commands/on_master/create_bot.rb +1 -0
  71. data/lib/slack/smart-bot/commands/on_master/where_smartbot.rb +41 -0
  72. data/lib/slack/smart-bot/commands.rb +22 -7
  73. data/lib/slack/smart-bot/listen.rb +30 -30
  74. data/lib/slack/smart-bot/process.rb +38 -18
  75. data/lib/slack/smart-bot/process_first.rb +2 -2
  76. data/lib/slack/smart-bot/treat_message.rb +13 -17
  77. data/lib/slack/smart-bot/utils/build_help.rb +1 -1
  78. data/lib/slack/smart-bot/utils/create_routine_thread.rb +1 -1
  79. data/lib/slack/smart-bot/utils/get_access_channels.rb +13 -0
  80. data/lib/slack/smart-bot/utils/get_admins_channels.rb +13 -0
  81. data/lib/slack/smart-bot/utils/get_bots_created.rb +27 -10
  82. data/lib/slack/smart-bot/utils/get_channels_name_and_id.rb +7 -2
  83. data/lib/slack/smart-bot/utils/get_command_ids.rb +84 -0
  84. data/lib/slack/smart-bot/utils/get_help.rb +34 -18
  85. data/lib/slack/smart-bot/utils/get_repls.rb +22 -2
  86. data/lib/slack/smart-bot/utils/get_routines.rb +22 -2
  87. data/lib/slack/smart-bot/utils/get_teams.rb +22 -0
  88. data/lib/slack/smart-bot/utils/has_access.rb +25 -9
  89. data/lib/slack/smart-bot/utils/is_admin.rb +27 -0
  90. data/lib/slack/smart-bot/utils/save_stats.rb +46 -43
  91. data/lib/slack/smart-bot/utils/save_status.rb +21 -6
  92. data/lib/slack/smart-bot/utils/update_access_channels.rb +8 -0
  93. data/lib/slack/smart-bot/utils/update_admins_channels.rb +8 -0
  94. data/lib/slack/smart-bot/utils/update_bots_file.rb +28 -7
  95. data/lib/slack/smart-bot/utils/update_repls.rb +7 -4
  96. data/lib/slack/smart-bot/utils/update_routines.rb +9 -3
  97. data/lib/slack/smart-bot/utils/update_shortcuts_file.rb +13 -6
  98. data/lib/slack/smart-bot/utils/update_teams.rb +16 -0
  99. data/lib/slack/smart-bot/utils.rb +8 -0
  100. data/lib/slack-smart-bot.rb +28 -10
  101. data/lib/slack-smart-bot_general_commands.rb +16 -1
  102. data/whats_new.txt +16 -29
  103. metadata +64 -19
  104. data/lib/slack/smart-bot/commands/general/bot_stats.rb +0 -314
@@ -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
@@ -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,34 @@
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
+ respond "It seems like the team *#{team_name}* doesn't exist.\nRelated commands `add team TEAM_NAME PROPERTIES`, `see team TEAM_NAME`, `see teams`"
11
+ elsif !(@teams[team_name.to_sym].members.values + [@teams[team_name.to_sym].creator] + config.masters).flatten.include?(user.name)
12
+ respond "You have to be a member of the team, the creator or a Master admin to be able to delete this team."
13
+ else
14
+ if answer.empty?
15
+ ask "do you really want to delete the #{team_name} team? (yes/no)"
16
+ else
17
+ case answer
18
+ when /yes/i, /yep/i, /sure/i
19
+ answer_delete
20
+ @teams.delete(team_name.to_sym)
21
+ update_teams()
22
+ respond "The team #{team_name} has been deleted."
23
+ when /no/i, /nope/i, /cancel/i
24
+ answer_delete
25
+ respond "Ok, the team was not deleted"
26
+ else
27
+ respond "I don't understand"
28
+ ask "do you really want to delete the #{team_name} team? (yes/no)"
29
+ end
30
+ end
31
+ end
32
+ end
33
+ end
34
+ 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
@@ -0,0 +1,116 @@
1
+ def poster(permanent, emoticon_text, emoticon_bg, string, minutes)
2
+ chars = { a: ["0000", "1111", "1001", "1111", "1001", "1001", "0000"],
3
+ b: ["0000", "1111", "1001", "1110", "1001", "1111", "0000"],
4
+ c: ["0000", "0111", "1000", "1000", "1000", "0111", "0000"],
5
+ d: ["0000", "1110", "1001", "1001", "1001", "1110", "0000"],
6
+ e: ["0000", "1111", "1000", "1110", "1000", "1111", "0000"],
7
+ f: ["0000", "1111", "1000", "1110", "1000", "1000", "0000"],
8
+ g: ["0000", "1111", "1000", "1011", "1001", "1111", "0000"],
9
+ h: ["0000", "1001", "1001", "1111", "1001", "1001", "0000"],
10
+ i: ["000", "111", "010", "010", "010", "111", "000"],
11
+ j: ["0000", "0111", "0010", "0010", "1010", "0110", "0000"],
12
+ k: ["0000", "1001", "1010", "1100", "1010", "1001", "0000"],
13
+ l: ["000", "100", "100", "100", "100", "111", "000"],
14
+ m: ["00000", "10001", "11011", "10101", "10001", "10001", "00000"],
15
+ n: ["00000", "10001", "11001", "10101", "10011", "10001", "00000"],
16
+ o: ["0000", "0110", "1001", "1001", "1001", "0110", "0000"],
17
+ p: ["0000", "1110", "1001", "1110", "1000", "1000", "0000"],
18
+ q: ["00000", "01100", "10010", "10010", "10010", "01111", "00000"],
19
+ r: ["0000", "1110", "1001", "1110", "1010", "1001", "0000"],
20
+ s: ["0000", "0111", "1000", "0110", "0001", "1110", "0000"],
21
+ t: ["00000", "11111", "00100", "00100", "00100", "00100", "00000"],
22
+ u: ["00000", "10001", "10001", "10001", "10001", "01110", "00000"],
23
+ v: ["00000", "10001", "10001", "10001", "01010", "00100", "00000"],
24
+ w: ["0000000", "1000001", "1000001", "1001001", "1010101", "0100010", "0000000"],
25
+ x: ["00000", "10001", "01010", "00100", "01010", "10001", "00000"],
26
+ y: ["00000", "10001", "01010", "00100", "00100", "00100", "00000"],
27
+ z: ["00000", "11111", "00010", "00100", "01000", "11111", "00000"],
28
+ '!': ["0", "1", "1", "1", "0", "1", "0"],
29
+ '+': ["000", "000", "010", "111", "010", "000", "000"],
30
+ '-': ["000", "000", "000", "111", "000", "000", "000"],
31
+ '=': ["000", "000", "111", "000", "111", "000", "000"],
32
+ '?': ["000", "111", "001", "010", "000", "010", "000"],
33
+ '0': ["000", "111", "101", "101", "101", "111", "000"],
34
+ '1': ["00", "01", "11", "01", "01", "01", "00"],
35
+ '2': ["000", "111", "001", "010", "100", "111", "000"],
36
+ '3': ["000", "111", "001", "111", "001", "111", "000"],
37
+ '4': ["000", "101", "101", "111", "001", "001", "000"],
38
+ '5': ["000", "111", "100", "111", "001", "111", "000"],
39
+ '6': ["000", "111", "100", "111", "101", "111", "000"],
40
+ '7': ["000", "111", "001", "010", "100", "100", "000"],
41
+ '8': ["000", "111", "101", "111", "101", "111", "000"],
42
+ '9': ["000", "111", "101", "111", "001", "111", "000"],
43
+ ' ': ["0", "0", "0", "0", "0", "0", "0"] }
44
+
45
+ emoticon_bg = ":white_square:" if emoticon_bg.to_s == ""
46
+ emoticon_text = ":black_square:" if emoticon_text.to_s == ""
47
+ string.downcase!
48
+ messages = []
49
+
50
+ string = string.strip.split(" ").join(" ")
51
+ lines = [""]
52
+ string.split(" ").each do |t|
53
+ if ("#{lines[-1]}#{t}").size <= 6
54
+ lines[-1] = "#{lines[-1]}#{t} "
55
+ else
56
+ lines[-1].strip!
57
+ lines.pop if lines[-1] == ""
58
+ if t.size > 6
59
+ t.chars.each_slice(6).map(&:join).each do |tt|
60
+ lines << tt.strip
61
+ end
62
+ lines[-1] += " " if lines[-1].size < 6
63
+ else
64
+ lines << t.strip + " "
65
+ end
66
+ end
67
+ end
68
+ lines[-1].strip!
69
+ messages = []
70
+ lines.each do |line|
71
+ results = []
72
+ all_spaces = true
73
+ line.each_char do |char|
74
+ if chars.key?(char.to_sym)
75
+ results << chars[char.to_sym]
76
+ all_spaces = false
77
+ else
78
+ results << chars[:' ']
79
+ end
80
+ end
81
+ unless all_spaces
82
+ rtxt = ""
83
+ 7.times do |n|
84
+ results.size.times do |i|
85
+ rtxt += "0#{results[i][n]}0"
86
+ end
87
+ rtxt += "\n"
88
+ end
89
+ rtxt.gsub!("1", emoticon_text)
90
+ rtxt.gsub!("0", emoticon_bg)
91
+ txt = ""
92
+ msgs = []
93
+ rtxt.split("\n").each do |m|
94
+ if (m + txt).size > 4000
95
+ msgs << txt unless txt == ""
96
+ txt = ""
97
+ end
98
+ txt += (m + "\n")
99
+ end
100
+ msgs << txt
101
+ msgs.flatten!
102
+ msgs.each do |msg|
103
+ messages << respond(msg, return_message: true)
104
+ end
105
+ end
106
+ end
107
+ unless permanent
108
+ react :heavy_check_mark
109
+ sleep (minutes.to_i * 60)
110
+ messages.delete(nil)
111
+ messages.each do |message|
112
+ delete(message.channel, message.ts)
113
+ end
114
+ react :heavy_minus_sign
115
+ end
116
+ end
@@ -0,0 +1,58 @@
1
+ class SlackSmartBot
2
+ def remove_admin(user, admin_user)
3
+ save_stats(__method__)
4
+ if Thread.current[:dest][0]=='D'
5
+ respond "This command cannot be called from a DM"
6
+ else
7
+
8
+ if Thread.current[:typem] == :on_call
9
+ channel = Thread.current[:dchannel]
10
+ elsif Thread.current[:using_channel].to_s==''
11
+ channel = Thread.current[:dest]
12
+ else
13
+ channel = Thread.current[:using_channel]
14
+ end
15
+ messages = []
16
+ admins = config.masters.dup
17
+ channels = get_channels()
18
+ channel_found = channels.detect { |c| c.id == channel }
19
+ if !channel_found.nil? and channel_found.creator.to_s != ''
20
+ creator_info = @users.select{|u| u.id == channel_found.creator or (u.key?(:enterprise_user) and u.enterprise_user.id == channel_found.creator)}[-1]
21
+ admins << creator_info.name
22
+ end
23
+ if Thread.current[:typem] == :on_bot or Thread.current[:typem] == :on_master
24
+ admins << config.admins.dup
25
+ end
26
+ if @admins_channels.key?(channel) and @admins_channels[channel].size > 0
27
+ admins << @admins_channels[channel]
28
+ end
29
+ admins.flatten!
30
+ admins.uniq!
31
+ admins.delete(nil)
32
+ if admins.include?(user.name)
33
+ admin_info = @users.select{|u| u.id == admin_user or (u.key?(:enterprise_user) and u.enterprise_user.id == admin_user)}[-1]
34
+ if creator_info.name == admin_info.name
35
+ messages << "This user created the channel and cannot be removed as an admin."
36
+ elsif config.masters.include?(admin_info.name) or config.masters.include?(admin_user)
37
+ messages << "Master admins cannot be removed as admins of this channel."
38
+ elsif config.admins.include?(admin_info.name) or config.admins.include?(admin_user)
39
+ messages << "This user is a defaulted admin for this channel and cannot be removed using this command."
40
+ elsif !admins.include?(admin_info.name)
41
+ messages << "This user is not an admin of this channel."
42
+ else
43
+ @admins_channels[channel] ||= []
44
+ @admins_channels[channel].delete(admin_info.name)
45
+ update_admins_channels()
46
+ messages << "The user is not an admin of this channel from now on."
47
+ admins.delete(admin_info.name)
48
+ end
49
+ messages << "*Admins*: <@#{admins.join('>, <@')}>"
50
+ else
51
+ messages << "Only the creator of the channel, Master admins or admins can remove an admin of this channel."
52
+ messages << "*Admins*: <@#{admins.join('>, <@')}>"
53
+ end
54
+
55
+ respond messages.join("\n")
56
+ end
57
+ end
58
+ end
@@ -0,0 +1,24 @@
1
+ class SlackSmartBot
2
+ def see_access(command_id)
3
+ save_stats(__method__)
4
+ if Thread.current[:typem] == :on_call
5
+ channel = Thread.current[:dchannel]
6
+ elsif Thread.current[:using_channel].to_s == ""
7
+ channel = Thread.current[:dest]
8
+ else
9
+ channel = Thread.current[:using_channel]
10
+ end
11
+ command_ids = get_command_ids()
12
+ if command_ids.values.flatten.include?(command_id)
13
+ if @access_channels.key?(channel) and @access_channels[channel].key?(command_id) and @access_channels[channel][command_id].size > 0
14
+ respond "Only these users have access to `#{command_id}` in this channel: <@#{@access_channels[channel][command_id].join(">, <@")}>"
15
+ elsif @access_channels.key?(channel) and @access_channels[channel].key?(command_id) and @access_channels[channel][command_id].empty?
16
+ respond "`#{command_id}` is not possible to be used in this channel. Please contact an admin if you want to use it."
17
+ else
18
+ respond "`#{command_id}` seems to be available in this channel."
19
+ end
20
+ else
21
+ respond "It seems like #{command_id} is not valid. Please be sure that exists by calling `see command ids`"
22
+ end
23
+ end
24
+ end
@@ -0,0 +1,33 @@
1
+ class SlackSmartBot
2
+ def see_admins()
3
+ save_stats(__method__)
4
+ if Thread.current[:typem] == :on_call
5
+ channel = Thread.current[:dchannel]
6
+ elsif Thread.current[:using_channel].to_s==''
7
+ channel = Thread.current[:dest]
8
+ else
9
+ channel = Thread.current[:using_channel]
10
+ end
11
+
12
+ messages = []
13
+ admins = []
14
+ channels = get_channels()
15
+ channel_found = channels.detect { |c| c.id == channel }
16
+ if !channel_found.nil? and channel_found.creator.to_s != ''
17
+ messages << "*Channel creator*: <@#{channel_found.creator}>"
18
+ creator_info = @users.select{|u| u.id == channel_found.creator or (u.key?(:enterprise_user) and u.enterprise_user.id == channel_found.creator)}[-1]
19
+ else
20
+ creator_info = {name: []}
21
+ end
22
+ messages << "*Master admins*: <@#{config.masters.join('>, <@')}>"
23
+ if Thread.current[:typem] == :on_bot or Thread.current[:typem] == :on_master
24
+ admins = config.admins.dup
25
+ end
26
+ if @admins_channels.key?(channel) and @admins_channels[channel].size > 0
27
+ admins = (@admins_channels[channel] + admins).uniq
28
+ end
29
+ admins = admins - config.masters - [creator_info.name]
30
+ messages << "*Admins*: <@#{admins.join('>, <@')}>" unless admins.empty?
31
+ respond messages.join("\n")
32
+ end
33
+ end
@@ -3,7 +3,7 @@ class SlackSmartBot
3
3
  def see_announcements(user, type, channel, mention=false, publish=false)
4
4
  save_stats(__method__)
5
5
  typem = Thread.current[:typem]
6
- general_message = "\nRelated commands `add announcement MESSAGE`, `delete announcement ID`"
6
+ general_message = ""
7
7
  if channel == ''
8
8
  if typem == :on_call
9
9
  channel = Thread.current[:dchannel]
@@ -51,7 +51,7 @@ class SlackSmartBot
51
51
  see_announcements_on_demand = false
52
52
  end
53
53
  if channel_id == Thread.current[:dest] or see_announcements_on_demand or publish #master admin user or publish_announcements
54
- if File.exists?("#{config.path}/announcements/#{channel_id}.csv") and (!@announcements.key?(channel_id) or see_announcements_on_demand) # to force to have the last version that maybe was updated by other SmartBot in case of demand
54
+ if File.exist?("#{config.path}/announcements/#{channel_id}.csv") and (!@announcements.key?(channel_id) or see_announcements_on_demand) # to force to have the last version that maybe was updated by other SmartBot in case of demand
55
55
  t = CSV.table("#{config.path}/announcements/#{channel_id}.csv", headers: ['message_id', 'user_deleted', 'user_created', 'date', 'time', 'type', 'message'])
56
56
  @announcements[channel_id] = t
57
57
  end
@@ -70,6 +70,8 @@ class SlackSmartBot
70
70
  user_created = "<@#{m[:user_created]}>"
71
71
  else
72
72
  user_created = m[:user_created]
73
+ user_info = @users.select { |u| u.name == user_created or (u.key?(:enterprise_user) and u.enterprise_user.name == user_created) }[-1]
74
+ user_created = user_info.profile.display_name unless user_info.nil?
73
75
  end
74
76
  if type == 'all' and channel_id[0]=='D'
75
77
  message << "\t#{m[:message_id]} #{emoji} *_#{m[:date]}_* #{m[:time]} *:* \t*private*"
@@ -88,8 +90,8 @@ class SlackSmartBot
88
90
  else
89
91
  message.unshift("*Announcements for channel <##{channel_id}>*")
90
92
  end
91
- message << general_message
92
- respond message.join("\n"), dest
93
+ message << general_message unless general_message.empty?
94
+ respond message.join("\n"), dest, unfurl_links: false, unfurl_media: false
93
95
  else
94
96
  if typem == :on_dm and channel_id[0]=='D'
95
97
  respond("There are no #{type} announcements#{general_message}", dest) unless type == 'all'
@@ -0,0 +1,29 @@
1
+ class SlackSmartBot
2
+ def see_command_ids()
3
+ save_stats(__method__)
4
+ commands = get_command_ids()
5
+
6
+ respond "*General Commands*: #{(commands[:general]+commands[:general_commands]).sort.join(' / ')}" unless commands[:general].empty?
7
+
8
+ respond "*On Bot general*: #{commands[:on_bot_general].sort.join(' / ')}" unless commands[:on_bot_general].empty?
9
+
10
+ respond "*On Bot on demand*: #{commands[:on_bot_on_demand].sort.join(' / ')}" unless commands[:on_bot_on_demand].empty?
11
+
12
+ respond "*On Bot admin*: #{commands[:on_bot_admin].sort.join(' / ')}" unless commands[:on_bot_admin].empty?
13
+
14
+ respond "*On Bot master admin*: #{commands[:on_bot_master_admin].sort.join(' / ')}" unless commands[:on_bot_master_admin].empty?
15
+
16
+ respond "*On extended*: #{commands[:on_extended].sort.join(' / ')}" unless commands[:on_extended].empty?
17
+
18
+ respond "*On Master*: #{commands[:on_master].sort.join(' / ')}" unless commands[:on_master].empty?
19
+
20
+ respond "*On Master admin*: #{commands[:on_master_admin].sort.join(' / ')}" unless commands[:on_master_admin].empty?
21
+
22
+ respond "*On Master master admin*: #{commands[:on_master_master_admin].sort.join(' / ')}" unless commands[:on_master_master_admin].empty?
23
+
24
+ respond "*General Rules*: #{commands[:general_rules].sort.join(' / ')}" unless commands[:general_rules].empty?
25
+
26
+ respond "*Rules*: #{commands[:rules].sort.join(' / ')}" unless commands[:rules].empty?
27
+
28
+ end
29
+ end
@@ -15,14 +15,13 @@ class SlackSmartBot
15
15
  respond "There is no data stored."
16
16
  else
17
17
  count_commands = {}
18
+
18
19
  files.each do |file|
19
20
  CSV.foreach(file, headers: true, header_converters: :symbol, converters: :numeric) do |row|
20
21
  row[:dest_channel_id] = row[:bot_channel_id] if row[:dest_channel_id].to_s[0] == "D"
21
-
22
- if ((only_mine and row[:user_name]==user.name) or (!only_mine and !config.admins.include?(row[:user_name]))) and
22
+ if ((only_mine and row[:user_name]==user.name) or (!only_mine and !config.masters.include?(row[:user_name]))) and
23
23
  row[:dest_channel_id] == channel and !row[:user_name].include?('routine/') and
24
24
  row[:command] != 'dont_understand'
25
-
26
25
  row[:command] = 'bot_help' if row[:command] == 'bot_rules'
27
26
  count_commands[row[:command]] ||= 0
28
27
  count_commands[row[:command]] += 1
@@ -41,7 +40,7 @@ class SlackSmartBot
41
40
  commands.each do |command|
42
41
  unless output.match?(/^\s*command_id:\s+:#{command}\s*$/)
43
42
  i+=1
44
- output += bot_help(user, user.name, Thread.current[:dest], channel, false, command.gsub('_',' '), config.rules_file, false)
43
+ output += bot_help(user, user.name, Thread.current[:dest], channel, false, command.gsub('_',' '), config.rules_file, savestats: false, strict: true)
45
44
  break if i>=5
46
45
  end
47
46
  end
@@ -22,6 +22,12 @@ class SlackSmartBot
22
22
  members = get_channel_members(cdest)
23
23
  if members.include?(user.id)
24
24
  list = {}
25
+ only_active = false
26
+ if types == ['available']
27
+ only_active = true
28
+ not_on = true
29
+ types = [':palm_tree:', ':spiral_calendar_pad:', ':face_with_thermometer:']
30
+ end
25
31
  members.each do |member|
26
32
  info = get_user_info(member)
27
33
  text = info.user.profile.status_text
@@ -29,26 +35,33 @@ class SlackSmartBot
29
35
  exp = info.user.profile.expiration
30
36
  unless (((!types.empty? and !types.include?(emoji)) or (emoji.to_s == "" and text.to_s == "" and exp.to_s == "")) and !not_on) or
31
37
  (not_on and types.include?(emoji)) or info.user.deleted or info.user.is_bot or info.user.is_app_user
32
- emoji = ":white_square:" if emoji.to_s == ""
33
- list[emoji] ||= []
34
- list[emoji] << {
35
- type: "context",
36
- elements: [
37
- {
38
- type: "plain_text",
39
- text: "\t\t",
40
- },
41
- {
42
- type: "image",
43
- image_url: info.user.profile.image_24,
44
- alt_text: info.user.name,
45
- },
46
- {
47
- type: "mrkdwn",
48
- text: " *#{info.user.profile.real_name}* (#{info.user.name}) #{text} #{exp}",
49
- },
50
- ],
51
- }
38
+ if only_active
39
+ active = (get_presence(member).presence.to_s == 'active')
40
+ else
41
+ active = false
42
+ end
43
+ if !only_active or (only_active and active)
44
+ emoji = ":white_square:" if emoji.to_s == ""
45
+ list[emoji] ||= []
46
+ list[emoji] << {
47
+ type: "context",
48
+ elements: [
49
+ {
50
+ type: "plain_text",
51
+ text: "\t\t",
52
+ },
53
+ {
54
+ type: "image",
55
+ image_url: info.user.profile.image_24,
56
+ alt_text: info.user.name,
57
+ },
58
+ {
59
+ type: "mrkdwn",
60
+ text: " *#{info.user.profile.real_name}* (#{info.user.name}) #{text} #{exp}",
61
+ },
62
+ ],
63
+ }
64
+ end
52
65
  end
53
66
  end
54
67
  if list.size > 0
@@ -59,7 +72,7 @@ class SlackSmartBot
59
72
  elements: [
60
73
  {
61
74
  type: "mrkdwn",
62
- text: "*Users* #{emoji} on <##{cdest}>",
75
+ text: "#{'*Available* ' if only_active}*Members* #{emoji} on <##{cdest}>",
63
76
  },
64
77
  ],
65
78
  },