slack-smart-bot 1.9.1 → 1.11.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 (121) hide show
  1. checksums.yaml +4 -4
  2. data/README.md +184 -16
  3. data/lib/slack/smart-bot/comm/ask.rb +55 -49
  4. data/lib/slack/smart-bot/comm/delete.rb +13 -0
  5. data/lib/slack/smart-bot/comm/dont_understand.rb +3 -3
  6. data/lib/slack/smart-bot/comm/event_hello.rb +8 -4
  7. data/lib/slack/smart-bot/comm/get_channel_members.rb +13 -4
  8. data/lib/slack/smart-bot/comm/get_channels.rb +31 -16
  9. data/lib/slack/smart-bot/comm/get_presence.rb +20 -0
  10. data/lib/slack/smart-bot/comm/get_user_info.rb +12 -8
  11. data/lib/slack/smart-bot/comm/get_users.rb +24 -0
  12. data/lib/slack/smart-bot/comm/react.rb +19 -2
  13. data/lib/slack/smart-bot/comm/respond.rb +224 -53
  14. data/lib/slack/smart-bot/comm/respond_direct.rb +2 -3
  15. data/lib/slack/smart-bot/comm/respond_thread.rb +5 -0
  16. data/lib/slack/smart-bot/comm/send_file.rb +38 -34
  17. data/lib/slack/smart-bot/comm/send_msg_channel.rb +27 -22
  18. data/lib/slack/smart-bot/comm/send_msg_user.rb +59 -33
  19. data/lib/slack/smart-bot/comm/unreact.rb +22 -18
  20. data/lib/slack/smart-bot/comm.rb +4 -0
  21. data/lib/slack/smart-bot/commands/general/add_admin.rb +51 -0
  22. data/lib/slack/smart-bot/commands/general/add_announcement.rb +32 -0
  23. data/lib/slack/smart-bot/commands/general/add_team.rb +80 -0
  24. data/lib/slack/smart-bot/commands/general/allow_access.rb +67 -0
  25. data/lib/slack/smart-bot/commands/general/bot_help.rb +69 -33
  26. data/lib/slack/smart-bot/commands/general/bye_bot.rb +0 -7
  27. data/lib/slack/smart-bot/commands/general/delete_announcement.rb +34 -0
  28. data/lib/slack/smart-bot/commands/general/delete_share.rb +34 -0
  29. data/lib/slack/smart-bot/commands/general/delete_team.rb +34 -0
  30. data/lib/slack/smart-bot/commands/general/deny_access.rb +36 -0
  31. data/lib/slack/smart-bot/commands/general/hi_bot.rb +16 -11
  32. data/lib/slack/smart-bot/commands/general/ping_team.rb +100 -0
  33. data/lib/slack/smart-bot/commands/general/poster.rb +116 -0
  34. data/lib/slack/smart-bot/commands/general/remove_admin.rb +58 -0
  35. data/lib/slack/smart-bot/commands/general/see_access.rb +24 -0
  36. data/lib/slack/smart-bot/commands/general/see_admins.rb +33 -0
  37. data/lib/slack/smart-bot/commands/general/see_announcements.rb +115 -0
  38. data/lib/slack/smart-bot/commands/general/see_command_ids.rb +29 -0
  39. data/lib/slack/smart-bot/commands/general/see_favorite_commands.rb +53 -0
  40. data/lib/slack/smart-bot/commands/general/see_shares.rb +41 -0
  41. data/lib/slack/smart-bot/commands/general/see_statuses.rb +91 -0
  42. data/lib/slack/smart-bot/commands/general/see_teams.rb +252 -0
  43. data/lib/slack/smart-bot/commands/general/share_messages.rb +58 -0
  44. data/lib/slack/smart-bot/commands/general/update_team.rb +109 -0
  45. data/lib/slack/smart-bot/commands/general_bot_commands.rb +504 -0
  46. data/lib/slack/smart-bot/commands/on_bot/add_shortcut.rb +4 -6
  47. data/lib/slack/smart-bot/commands/on_bot/admin/add_routine.rb +45 -14
  48. data/lib/slack/smart-bot/commands/on_bot/admin/extend_rules.rb +4 -1
  49. data/lib/slack/smart-bot/commands/on_bot/admin/pause_bot.rb +6 -3
  50. data/lib/slack/smart-bot/commands/on_bot/admin/pause_routine.rb +3 -1
  51. data/lib/slack/smart-bot/commands/on_bot/admin/remove_routine.rb +4 -4
  52. data/lib/slack/smart-bot/commands/on_bot/admin/run_routine.rb +8 -2
  53. data/lib/slack/smart-bot/commands/on_bot/admin/see_result_routine.rb +33 -0
  54. data/lib/slack/smart-bot/commands/on_bot/admin/see_routines.rb +13 -10
  55. data/lib/slack/smart-bot/commands/on_bot/admin/start_bot.rb +6 -3
  56. data/lib/slack/smart-bot/commands/on_bot/admin/start_routine.rb +3 -1
  57. data/lib/slack/smart-bot/commands/on_bot/admin/stop_using_rules_on.rb +4 -1
  58. data/lib/slack/smart-bot/commands/on_bot/admin_master/delete_message.rb +25 -0
  59. data/lib/slack/smart-bot/commands/on_bot/admin_master/get_bot_logs.rb +1 -0
  60. data/lib/slack/smart-bot/commands/on_bot/admin_master/react_to.rb +34 -0
  61. data/lib/slack/smart-bot/commands/on_bot/admin_master/send_message.rb +37 -0
  62. data/lib/slack/smart-bot/commands/on_bot/delete_repl.rb +4 -5
  63. data/lib/slack/smart-bot/commands/on_bot/delete_shortcut.rb +7 -8
  64. data/lib/slack/smart-bot/commands/on_bot/general/bot_stats.rb +400 -0
  65. data/lib/slack/smart-bot/commands/{general → on_bot/general}/bot_status.rb +3 -4
  66. data/lib/slack/smart-bot/commands/on_bot/general/leaderboard.rb +201 -0
  67. data/lib/slack/smart-bot/commands/{general → on_bot/general}/stop_using_rules.rb +12 -6
  68. data/lib/slack/smart-bot/commands/on_bot/general/suggest_command.rb +36 -0
  69. data/lib/slack/smart-bot/commands/{general → on_bot/general}/use_rules.rb +13 -11
  70. data/lib/slack/smart-bot/commands/{general → on_bot/general}/whats_new.rb +2 -1
  71. data/lib/slack/smart-bot/commands/on_bot/get_repl.rb +4 -5
  72. data/lib/slack/smart-bot/commands/on_bot/repl.rb +76 -21
  73. data/lib/slack/smart-bot/commands/on_bot/ruby_code.rb +3 -4
  74. data/lib/slack/smart-bot/commands/on_bot/run_repl.rb +15 -7
  75. data/lib/slack/smart-bot/commands/on_bot/see_repls.rb +5 -6
  76. data/lib/slack/smart-bot/commands/on_bot/see_shortcuts.rb +5 -6
  77. data/lib/slack/smart-bot/commands/on_extended/bot_rules.rb +45 -12
  78. data/lib/slack/smart-bot/commands/on_master/admin/kill_bot_on_channel.rb +7 -3
  79. data/lib/slack/smart-bot/commands/on_master/admin_master/exit_bot.rb +4 -1
  80. data/lib/slack/smart-bot/commands/on_master/admin_master/notify_message.rb +3 -1
  81. data/lib/slack/smart-bot/commands/on_master/admin_master/publish_announcements.rb +33 -0
  82. data/lib/slack/smart-bot/commands/on_master/admin_master/set_general_message.rb +39 -0
  83. data/lib/slack/smart-bot/commands/on_master/admin_master/set_maintenance.rb +10 -1
  84. data/lib/slack/smart-bot/commands/on_master/create_bot.rb +28 -14
  85. data/lib/slack/smart-bot/commands/on_master/where_smartbot.rb +41 -0
  86. data/lib/slack/smart-bot/commands.rb +36 -5
  87. data/lib/slack/smart-bot/listen.rb +31 -33
  88. data/lib/slack/smart-bot/process.rb +234 -73
  89. data/lib/slack/smart-bot/process_first.rb +119 -38
  90. data/lib/slack/smart-bot/treat_message.rb +310 -237
  91. data/lib/slack/smart-bot/utils/build_help.rb +2 -2
  92. data/lib/slack/smart-bot/utils/create_routine_thread.rb +81 -46
  93. data/lib/slack/smart-bot/utils/get_access_channels.rb +13 -0
  94. data/lib/slack/smart-bot/utils/get_admins_channels.rb +13 -0
  95. data/lib/slack/smart-bot/utils/get_bots_created.rb +28 -8
  96. data/lib/slack/smart-bot/utils/get_channels_name_and_id.rb +7 -2
  97. data/lib/slack/smart-bot/utils/get_command_ids.rb +84 -0
  98. data/lib/slack/smart-bot/utils/get_help.rb +79 -73
  99. data/lib/slack/smart-bot/utils/get_repls.rb +22 -2
  100. data/lib/slack/smart-bot/utils/get_routines.rb +22 -2
  101. data/lib/slack/smart-bot/utils/get_shares.rb +12 -0
  102. data/lib/slack/smart-bot/utils/get_teams.rb +22 -0
  103. data/lib/slack/smart-bot/utils/has_access.rb +28 -0
  104. data/lib/slack/smart-bot/utils/is_admin.rb +27 -0
  105. data/lib/slack/smart-bot/utils/save_stats.rb +46 -41
  106. data/lib/slack/smart-bot/utils/save_status.rb +67 -0
  107. data/lib/slack/smart-bot/utils/update_access_channels.rb +8 -0
  108. data/lib/slack/smart-bot/utils/update_admins_channels.rb +8 -0
  109. data/lib/slack/smart-bot/utils/update_bots_file.rb +28 -7
  110. data/lib/slack/smart-bot/utils/update_repls.rb +7 -4
  111. data/lib/slack/smart-bot/utils/update_routines.rb +9 -3
  112. data/lib/slack/smart-bot/utils/update_shortcuts_file.rb +13 -6
  113. data/lib/slack/smart-bot/utils/update_teams.rb +16 -0
  114. data/lib/slack/smart-bot/utils.rb +11 -0
  115. data/lib/slack-smart-bot.rb +72 -12
  116. data/lib/slack-smart-bot_general_commands.rb +61 -0
  117. data/lib/slack-smart-bot_general_rules.rb +5 -2
  118. data/lib/slack-smart-bot_rules.rb +43 -17
  119. data/whats_new.txt +20 -15
  120. metadata +76 -9
  121. data/lib/slack/smart-bot/commands/general/bot_stats.rb +0 -313
@@ -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
@@ -0,0 +1,115 @@
1
+ class SlackSmartBot
2
+
3
+ def see_announcements(user, type, channel, mention=false, publish=false)
4
+ save_stats(__method__)
5
+ typem = Thread.current[:typem]
6
+ general_message = ""
7
+ if channel == ''
8
+ if typem == :on_call
9
+ channel = Thread.current[:dchannel]
10
+ else
11
+ channel = Thread.current[:dest]
12
+ end
13
+ end
14
+ if publish
15
+ dest = channel
16
+ else
17
+ dest = Thread.current[:dest]
18
+ end
19
+
20
+ if type == 'all'
21
+ if config.masters.include?(user.name) and typem==:on_dm
22
+ channels = Dir.entries("#{config.path}/announcements/")
23
+ channels.select! {|i| i[/\.csv$/]}
24
+ else
25
+ channels = []
26
+ respond "Only master admins on a DM with the SmarBot can call this command.", dest
27
+ end
28
+ elsif typem == :on_dm and channel == Thread.current[:dest]
29
+ channels = [channel, @channel_id]
30
+ else
31
+ channels = [channel]
32
+ end
33
+ channels.each do |channel|
34
+ channel.gsub!('.csv','')
35
+ if channel[0]== 'D'
36
+ channel_id = channel
37
+ else
38
+ get_channels_name_and_id() unless @channels_name.keys.include?(channel) or @channels_id.keys.include?(channel)
39
+ channel_id = nil
40
+ if @channels_name.key?(channel) #it is an id
41
+ channel_id = channel
42
+ channel = @channels_name[channel_id]
43
+ elsif @channels_id.key?(channel) #it is a channel name
44
+ channel_id = @channels_id[channel]
45
+ end
46
+ end
47
+ if has_access?(__method__, user)
48
+ if (channel_id!=Thread.current[:dest] and config.masters.include?(user.name) and typem==:on_dm) or publish
49
+ see_announcements_on_demand = true
50
+ else
51
+ see_announcements_on_demand = false
52
+ end
53
+ if channel_id == Thread.current[:dest] or see_announcements_on_demand or publish #master admin user or publish_announcements
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
+ t = CSV.table("#{config.path}/announcements/#{channel_id}.csv", headers: ['message_id', 'user_deleted', 'user_created', 'date', 'time', 'type', 'message'])
56
+ @announcements[channel_id] = t
57
+ end
58
+ if @announcements.key?(channel_id)
59
+ message = []
60
+ @announcements[channel_id].each do |m|
61
+ if m[:user_deleted] == '' and (type == 'all' or type == '' or type==m[:type])
62
+ if m[:type].match?(/:\w+:/)
63
+ emoji = m[:type]
64
+ elsif m[:type] == 'white'
65
+ emoji = ':white_square:'
66
+ else
67
+ emoji = ":large_#{m[:type]}_square:"
68
+ end
69
+ if mention
70
+ user_created = "<@#{m[:user_created]}>"
71
+ else
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?
75
+ end
76
+ if type == 'all' and channel_id[0]=='D'
77
+ message << "\t#{m[:message_id]} #{emoji} *_#{m[:date]}_* #{m[:time]} *:* \t*private*"
78
+ else
79
+ message << "\t#{m[:message_id]} #{emoji} *_#{m[:date]}_* #{m[:time]} #{"#{user_created} " unless channel_id[0]=='D'}*:* \t#{m[:message]}"
80
+ end
81
+ end
82
+ end
83
+ if message.size > 0
84
+ if channel_id[0]=='D'
85
+ if type == 'all'
86
+ message.unshift("*Private messages stored on DM with the SmartBot and <@#{@announcements[channel_id][:user_created][0]}>*")
87
+ else
88
+ message.unshift("*Private messages stored on your DM with the SmartBot*")
89
+ end
90
+ else
91
+ message.unshift("*Announcements for channel <##{channel_id}>*")
92
+ end
93
+ message << general_message unless general_message.empty?
94
+ respond message.join("\n"), dest, unfurl_links: false, unfurl_media: false
95
+ else
96
+ if typem == :on_dm and channel_id[0]=='D'
97
+ respond("There are no #{type} announcements#{general_message}", dest) unless type == 'all'
98
+ else
99
+ respond("There are no #{type} announcements for <##{channel_id}>#{general_message}", dest) unless publish or type == 'all' or (typem==:on_dm and channel_id[0]!='D' and !see_announcements_on_demand)
100
+ end
101
+ end
102
+ else
103
+ if typem == :on_dm and channel_id[0]=='D'
104
+ respond("There are no announcements#{general_message}", dest) unless type == 'all'
105
+ else
106
+ respond("There are no announcements for <##{channel_id}>#{general_message}", dest) unless publish or type == 'all' or (typem==:on_dm and channel_id[0]!='D' and !see_announcements_on_demand)
107
+ end
108
+ end
109
+ else
110
+ respond "Go to <##{channel_id}> and call the command from there.", dest
111
+ end
112
+ end
113
+ end
114
+ end
115
+ end
@@ -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
@@ -0,0 +1,53 @@
1
+ class SlackSmartBot
2
+ def see_favorite_commands(user, only_mine)
3
+ save_stats(__method__)
4
+ if config.stats
5
+ if Thread.current[:typem] == :on_call
6
+ channel = Thread.current[:dchannel]
7
+ elsif Thread.current[:using_channel].to_s==''
8
+ channel = Thread.current[:dest]
9
+ else
10
+ channel = Thread.current[:using_channel]
11
+ end
12
+
13
+ files = Dir["#{config.stats_path}.*.log"].sort.reverse[0..1]
14
+ if files.empty?
15
+ respond "There is no data stored."
16
+ else
17
+ count_commands = {}
18
+
19
+ files.each do |file|
20
+ CSV.foreach(file, headers: true, header_converters: :symbol, converters: :numeric) do |row|
21
+ row[:dest_channel_id] = row[:bot_channel_id] if row[:dest_channel_id].to_s[0] == "D"
22
+ if ((only_mine and row[:user_name]==user.name) or (!only_mine and !config.masters.include?(row[:user_name]))) and
23
+ row[:dest_channel_id] == channel and !row[:user_name].include?('routine/') and
24
+ row[:command] != 'dont_understand'
25
+ row[:command] = 'bot_help' if row[:command] == 'bot_rules'
26
+ count_commands[row[:command]] ||= 0
27
+ count_commands[row[:command]] += 1
28
+ end
29
+ end
30
+ end
31
+ commands = []
32
+ count_commands.sort_by {|k,v| -v}.each do |command, num|
33
+ commands << command
34
+ end
35
+ if commands.empty?
36
+ respond "There is no data stored."
37
+ else
38
+ output = ""
39
+ i = 0
40
+ commands.each do |command|
41
+ unless output.match?(/^\s*command_id:\s+:#{command}\s*$/)
42
+ i+=1
43
+ output += bot_help(user, user.name, Thread.current[:dest], channel, false, command.gsub('_',' '), config.rules_file, savestats: false, strict: true)
44
+ break if i>=5
45
+ end
46
+ end
47
+ end
48
+ end
49
+ else
50
+ respond "Ask an admin to set stats to true to generate the stats when running the bot instance so you can get this command to work."
51
+ end
52
+ end
53
+ end
@@ -0,0 +1,41 @@
1
+ class SlackSmartBot
2
+
3
+ def see_shares()
4
+ save_stats(__method__)
5
+ typem = Thread.current[:typem]
6
+ dest = Thread.current[:dest]
7
+ if typem == :on_call
8
+ channel = Thread.current[:dchannel]
9
+ else
10
+ channel = Thread.current[:dest]
11
+ end
12
+
13
+ general_message = "\nRelated commands `share messages /RegExp/ on #CHANNEL`, `share messages \"TEXT\" on #CHANNEL`, `delete share ID`"
14
+ if File.exist?("#{config.path}/shares/#{@channels_name[channel]}.csv")
15
+ t = CSV.table("#{config.path}/shares/#{@channels_name[channel]}.csv", headers: ['share_id', 'user_deleted', 'user_created', 'date', 'time', 'type', 'to_channel', 'condition'])
16
+ message =[]
17
+ t.each do |m|
18
+ if m[:user_deleted] == ''
19
+ if m[:type]=='text'
20
+ emoji = ":abc:"
21
+ elsif m[:type] == 'regexp'
22
+ emoji = ":heavy_plus_sign:"
23
+ else
24
+ emoji = ':white_square:'
25
+ end
26
+ message << "\t#{m[:share_id]} #{emoji} *_#{m[:date]}_* #{m[:time]} *#{m[:user_created]}* <##{@channels_id[m[:to_channel]]}|#{m[:to_channel]}> : \t`#{m[:condition]}`"
27
+ end
28
+ end
29
+ if message.size == 0
30
+ message << "*There are no active shares right now.*"
31
+ else
32
+ message.unshift("*Shares from channel <##{channel}>*")
33
+ end
34
+ message << general_message
35
+ respond message.join("\n"), dest
36
+ else
37
+ respond "*There are no active shares right now.*#{general_message}"
38
+ end
39
+
40
+ end
41
+ end
@@ -0,0 +1,91 @@
1
+ class SlackSmartBot
2
+ def see_statuses(user, channel, types, dest, not_on)
3
+ save_stats(__method__)
4
+ react :runner
5
+ if channel == ""
6
+ if dest[0] == "D"
7
+ cdest = @channel_id
8
+ else
9
+ cdest = dest
10
+ end
11
+ else
12
+ get_channels_name_and_id() unless @channels_name.keys.include?(channel) or @channels_id.keys.include?(channel)
13
+ channel_id = nil
14
+ if @channels_name.key?(channel) #it is an id
15
+ channel_id = channel
16
+ channel = @channels_name[channel_id]
17
+ elsif @channels_id.key?(channel) #it is a channel name
18
+ channel_id = @channels_id[channel]
19
+ end
20
+ cdest = channel_id
21
+ end
22
+ members = get_channel_members(cdest)
23
+ if members.include?(user.id)
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
31
+ members.each do |member|
32
+ info = get_user_info(member)
33
+ text = info.user.profile.status_text
34
+ emoji = info.user.profile.status_emoji
35
+ exp = info.user.profile.expiration
36
+ unless (((!types.empty? and !types.include?(emoji)) or (emoji.to_s == "" and text.to_s == "" and exp.to_s == "")) and !not_on) or
37
+ (not_on and types.include?(emoji)) or info.user.deleted or info.user.is_bot or info.user.is_app_user
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
65
+ end
66
+ end
67
+ if list.size > 0
68
+ list.each do |emoji, users|
69
+ blocks = [
70
+ {
71
+ "type": "context",
72
+ elements: [
73
+ {
74
+ type: "mrkdwn",
75
+ text: "#{'*Available* ' if only_active}*Members* #{emoji} on <##{cdest}>",
76
+ },
77
+ ],
78
+ },
79
+ ]
80
+ users = users.sort_by { |hsh| hsh.elements[2].text }
81
+ respond blocks: (blocks+users)
82
+ end
83
+ else
84
+ respond "Nobody on <##{cdest}> with that status"
85
+ end
86
+ else
87
+ respond "You need to join <##{cdest}> to be able to see the statuses on that channel."
88
+ end
89
+ unreact :runner
90
+ end
91
+ end