slack-smart-bot 1.10.0 → 1.12.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (116) hide show
  1. checksums.yaml +4 -4
  2. data/README.md +134 -23
  3. data/lib/slack/smart-bot/comm/delete.rb +13 -0
  4. data/lib/slack/smart-bot/comm/dont_understand.rb +2 -2
  5. data/lib/slack/smart-bot/comm/get_channel_members.rb +7 -3
  6. data/lib/slack/smart-bot/comm/get_presence.rb +20 -0
  7. data/lib/slack/smart-bot/comm/get_users.rb +1 -1
  8. data/lib/slack/smart-bot/comm/respond.rb +24 -13
  9. data/lib/slack/smart-bot/comm/send_msg_user.rb +12 -11
  10. data/lib/slack/smart-bot/comm/set_status.rb +21 -0
  11. data/lib/slack/smart-bot/comm.rb +3 -0
  12. data/lib/slack/smart-bot/commands/general/add_admin.rb +51 -0
  13. data/lib/slack/smart-bot/commands/general/add_announcement.rb +1 -1
  14. data/lib/slack/smart-bot/commands/general/add_memo_team.rb +117 -0
  15. data/lib/slack/smart-bot/commands/general/add_team.rb +80 -0
  16. data/lib/slack/smart-bot/commands/general/add_vacation.rb +51 -0
  17. data/lib/slack/smart-bot/commands/general/allow_access.rb +67 -0
  18. data/lib/slack/smart-bot/commands/general/bot_help.rb +20 -11
  19. data/lib/slack/smart-bot/commands/general/delete_announcement.rb +1 -1
  20. data/lib/slack/smart-bot/commands/general/delete_memo_team.rb +69 -0
  21. data/lib/slack/smart-bot/commands/general/delete_share.rb +1 -1
  22. data/lib/slack/smart-bot/commands/general/delete_team.rb +54 -0
  23. data/lib/slack/smart-bot/commands/general/deny_access.rb +36 -0
  24. data/lib/slack/smart-bot/commands/general/ping_team.rb +100 -0
  25. data/lib/slack/smart-bot/commands/general/poster.rb +116 -0
  26. data/lib/slack/smart-bot/commands/general/remove_admin.rb +58 -0
  27. data/lib/slack/smart-bot/commands/general/remove_vacation.rb +27 -0
  28. data/lib/slack/smart-bot/commands/general/see_access.rb +24 -0
  29. data/lib/slack/smart-bot/commands/general/see_admins.rb +33 -0
  30. data/lib/slack/smart-bot/commands/general/see_announcements.rb +7 -5
  31. data/lib/slack/smart-bot/commands/general/see_command_ids.rb +29 -0
  32. data/lib/slack/smart-bot/commands/general/see_favorite_commands.rb +3 -4
  33. data/lib/slack/smart-bot/commands/general/see_statuses.rb +34 -21
  34. data/lib/slack/smart-bot/commands/general/see_teams.rb +402 -0
  35. data/lib/slack/smart-bot/commands/general/see_vacations.rb +58 -0
  36. data/lib/slack/smart-bot/commands/general/see_vacations_team.rb +136 -0
  37. data/lib/slack/smart-bot/commands/general/set_memo_status.rb +58 -0
  38. data/lib/slack/smart-bot/commands/general/share_messages.rb +1 -1
  39. data/lib/slack/smart-bot/commands/general/update_team.rb +130 -0
  40. data/lib/slack/smart-bot/commands/general_bot_commands.rb +442 -13
  41. data/lib/slack/smart-bot/commands/on_bot/add_shortcut.rb +2 -1
  42. data/lib/slack/smart-bot/commands/on_bot/admin/add_routine.rb +2 -1
  43. data/lib/slack/smart-bot/commands/on_bot/admin/extend_rules.rb +2 -1
  44. data/lib/slack/smart-bot/commands/on_bot/admin/pause_bot.rb +2 -1
  45. data/lib/slack/smart-bot/commands/on_bot/admin/pause_routine.rb +2 -1
  46. data/lib/slack/smart-bot/commands/on_bot/admin/remove_routine.rb +2 -1
  47. data/lib/slack/smart-bot/commands/on_bot/admin/run_routine.rb +3 -2
  48. data/lib/slack/smart-bot/commands/on_bot/admin/see_result_routine.rb +2 -1
  49. data/lib/slack/smart-bot/commands/on_bot/admin/see_routines.rb +10 -9
  50. data/lib/slack/smart-bot/commands/on_bot/admin/start_bot.rb +2 -1
  51. data/lib/slack/smart-bot/commands/on_bot/admin/start_routine.rb +2 -1
  52. data/lib/slack/smart-bot/commands/on_bot/admin/stop_using_rules_on.rb +2 -1
  53. data/lib/slack/smart-bot/commands/on_bot/admin_master/delete_message.rb +25 -0
  54. data/lib/slack/smart-bot/commands/on_bot/admin_master/get_bot_logs.rb +1 -0
  55. data/lib/slack/smart-bot/commands/on_bot/admin_master/react_to.rb +3 -1
  56. data/lib/slack/smart-bot/commands/on_bot/admin_master/send_message.rb +15 -2
  57. data/lib/slack/smart-bot/commands/on_bot/delete_repl.rb +2 -1
  58. data/lib/slack/smart-bot/commands/on_bot/delete_shortcut.rb +5 -4
  59. data/lib/slack/smart-bot/commands/on_bot/general/bot_stats.rb +416 -0
  60. data/lib/slack/smart-bot/commands/{general → on_bot/general}/bot_status.rb +1 -0
  61. data/lib/slack/smart-bot/commands/{general → on_bot/general}/leaderboard.rb +1 -0
  62. data/lib/slack/smart-bot/commands/{general → on_bot/general}/stop_using_rules.rb +1 -0
  63. data/lib/slack/smart-bot/commands/{general → on_bot/general}/suggest_command.rb +6 -0
  64. data/lib/slack/smart-bot/commands/{general → on_bot/general}/use_rules.rb +1 -0
  65. data/lib/slack/smart-bot/commands/{general → on_bot/general}/whats_new.rb +2 -1
  66. data/lib/slack/smart-bot/commands/on_bot/get_repl.rb +2 -1
  67. data/lib/slack/smart-bot/commands/on_bot/kill_repl.rb +32 -0
  68. data/lib/slack/smart-bot/commands/on_bot/repl.rb +73 -15
  69. data/lib/slack/smart-bot/commands/on_bot/ruby_code.rb +1 -0
  70. data/lib/slack/smart-bot/commands/on_bot/run_repl.rb +117 -28
  71. data/lib/slack/smart-bot/commands/on_bot/see_repls.rb +2 -1
  72. data/lib/slack/smart-bot/commands/on_bot/see_shortcuts.rb +3 -2
  73. data/lib/slack/smart-bot/commands/on_master/admin/kill_bot_on_channel.rb +5 -4
  74. data/lib/slack/smart-bot/commands/on_master/admin_master/exit_bot.rb +3 -2
  75. data/lib/slack/smart-bot/commands/on_master/admin_master/notify_message.rb +2 -1
  76. data/lib/slack/smart-bot/commands/on_master/admin_master/publish_announcements.rb +6 -3
  77. data/lib/slack/smart-bot/commands/on_master/admin_master/set_general_message.rb +2 -1
  78. data/lib/slack/smart-bot/commands/on_master/admin_master/set_maintenance.rb +2 -1
  79. data/lib/slack/smart-bot/commands/on_master/create_bot.rb +1 -0
  80. data/lib/slack/smart-bot/commands/on_master/where_smartbot.rb +41 -0
  81. data/lib/slack/smart-bot/commands.rb +30 -7
  82. data/lib/slack/smart-bot/listen.rb +30 -30
  83. data/lib/slack/smart-bot/process.rb +53 -23
  84. data/lib/slack/smart-bot/process_first.rb +2 -2
  85. data/lib/slack/smart-bot/treat_message.rb +23 -17
  86. data/lib/slack/smart-bot/utils/build_help.rb +1 -1
  87. data/lib/slack/smart-bot/utils/check_vacations.rb +43 -0
  88. data/lib/slack/smart-bot/utils/create_routine_thread.rb +1 -1
  89. data/lib/slack/smart-bot/utils/get_access_channels.rb +13 -0
  90. data/lib/slack/smart-bot/utils/get_admins_channels.rb +33 -0
  91. data/lib/slack/smart-bot/utils/get_bots_created.rb +27 -10
  92. data/lib/slack/smart-bot/utils/get_channels_name_and_id.rb +7 -2
  93. data/lib/slack/smart-bot/utils/get_command_ids.rb +84 -0
  94. data/lib/slack/smart-bot/utils/get_help.rb +36 -19
  95. data/lib/slack/smart-bot/utils/get_repls.rb +22 -2
  96. data/lib/slack/smart-bot/utils/get_routines.rb +22 -2
  97. data/lib/slack/smart-bot/utils/get_teams.rb +22 -0
  98. data/lib/slack/smart-bot/utils/get_vacations.rb +22 -0
  99. data/lib/slack/smart-bot/utils/has_access.rb +25 -9
  100. data/lib/slack/smart-bot/utils/is_admin.rb +27 -0
  101. data/lib/slack/smart-bot/utils/save_stats.rb +52 -42
  102. data/lib/slack/smart-bot/utils/save_status.rb +22 -7
  103. data/lib/slack/smart-bot/utils/update_access_channels.rb +8 -0
  104. data/lib/slack/smart-bot/utils/update_admins_channels.rb +25 -0
  105. data/lib/slack/smart-bot/utils/update_bots_file.rb +28 -7
  106. data/lib/slack/smart-bot/utils/update_repls.rb +7 -4
  107. data/lib/slack/smart-bot/utils/update_routines.rb +9 -3
  108. data/lib/slack/smart-bot/utils/update_shortcuts_file.rb +13 -6
  109. data/lib/slack/smart-bot/utils/update_teams.rb +16 -0
  110. data/lib/slack/smart-bot/utils/update_vacations.rb +16 -0
  111. data/lib/slack/smart-bot/utils.rb +11 -0
  112. data/lib/slack-smart-bot.rb +50 -12
  113. data/lib/slack-smart-bot_general_commands.rb +16 -1
  114. data/whats_new.txt +12 -30
  115. metadata +78 -21
  116. data/lib/slack/smart-bot/commands/general/bot_stats.rb +0 -314
@@ -1,314 +0,0 @@
1
- class SlackSmartBot
2
- # help: ----------------------------------------------
3
- # help: `bot stats`
4
- # helpmaster: `bot stats USER_NAME`
5
- # help: `bot stats exclude masters`
6
- # help: `bot stats exclude routines`
7
- # help: `bot stats from YYYY/MM/DD`
8
- # help: `bot stats from YYYY/MM/DD to YYYY/MM/DD`
9
- # help: `bot stats CHANNEL`
10
- # help: `bot stats CHANNEL from YYYY/MM/DD`
11
- # help: `bot stats CHANNEL from YYYY/MM/DD to YYYY/MM/DD`
12
- # help: `bot stats command COMMAND`
13
- # helpmaster: `bot stats USER_NAME from YYYY/MM/DD to YYYY/MM/DD`
14
- # helpmaster: `bot stats CHANNEL USER_NAME from YYYY/MM/DD to YYYY/MM/DD`
15
- # help: `bot stats CHANNEL exclude masters from YYYY/MM/DD to YYYY/MM/DD`
16
- # help: `bot stats today`
17
- # help: `bot stats exclude COMMAND_ID`
18
- # help: `bot stats monthly`
19
- # help: `bot stats alldata`
20
- # help: To see the bot stats
21
- # helpmaster: You can use this command only if you are a Master admin user and if you are in a private conversation with the bot
22
- # helpmaster: You need to set stats to true to generate the stats when running the bot instance.
23
- # help: If alldata option supplied then it will be attached files including all data and not only the top 10.
24
- # help: Examples:
25
- # help: _bot stats #sales_
26
- # helpmaster: _bot stats @peter.wind_
27
- # help: _bot stats #sales from 2019/12/15 to 2019/12/31_
28
- # help: _bot stats #sales today_
29
- # help: _bot stats #sales from 2020-01-01 monthly_
30
- # help: _bot stats exclude routines masters from 2021/01/01 monthly_
31
- # help: <https://github.com/MarioRuiz/slack-smart-bot#bot-management|more info>
32
- # help:
33
- def bot_stats(dest, from_user, typem, channel_id, from, to, user, st_command, exclude_masters, exclude_routines, exclude_command, monthly, all_data)
34
- require 'csv'
35
- if config.stats
36
- message = []
37
- else
38
- message = ["You need to set stats to true to generate the stats when running the bot instance."]
39
- end
40
- save_stats(__method__)
41
- if (from_user.id != user and (config.masters.include?(from_user.name) or @master_admin_users_id.include?(from_user.id)) and (typem==:on_dm or dest[0]=='D'))
42
- on_dm_master = true #master admin user
43
- else
44
- on_dm_master = false
45
- end
46
- if on_dm_master or (from_user.id == user) # normal user can only see own stats
47
- if !File.exist?("#{config.stats_path}.#{Time.now.strftime("%Y-%m")}.log")
48
- message<<'No stats'
49
- else
50
- from = "#{Time.now.strftime("%Y-%m")}-01" if from == ''
51
- to = "#{Time.now.strftime("%Y-%m-%d")}" if to == ''
52
- from_short = from
53
- to_short = to
54
- from_file = from[0..3] + '-' + from[5..6]
55
- to_file = to[0..3] + '-' + to[5..6]
56
- from+= " 00:00:00 +0000"
57
- to+= " 23:59:59 +0000"
58
- rows = []
59
- rows_month = {}
60
- users_month = {}
61
- commands_month = {}
62
- users_id_name = {}
63
- users_name_id = {}
64
- count_users = {}
65
- count_channels_dest = {}
66
-
67
- # to translate global and enterprise users since sometimes was returning different names/ids
68
- if from[0..3]=='2020' # this was an issue only on that period
69
- Dir["#{config.stats_path}.*.log"].sort.each do |file|
70
- if file >= "#{config.stats_path}.#{from_file}.log" or file <= "#{config.stats_path}.#{to_file}.log"
71
- CSV.foreach(file, headers: true, header_converters: :symbol, converters: :numeric) do |row|
72
- unless users_id_name.key?(row[:user_id])
73
- users_id_name[row[:user_id]] = row[:user_name]
74
- end
75
- unless users_name_id.key?(row[:user_name])
76
- users_name_id[row[:user_name]] = row[:user_id]
77
- end
78
-
79
- end
80
- end
81
- end
82
- end
83
-
84
- if user!=''
85
- user_info = @users.select{|u| u.id == user or (u.key?(:enterprise_user) and u.enterprise_user.id == user)}[-1]
86
- if users_id_name.key?(user_info.id)
87
- user_name = users_id_name[user_info.id]
88
- else
89
- user_name = user_info.name
90
- end
91
- if users_name_id.key?(user_info.name)
92
- user_id = users_name_id[user_info.name]
93
- else
94
- user_id = user_info.id
95
- end
96
- end
97
- master_admins = config.masters.dup
98
- if users_id_name.size > 0
99
- config.masters.each do |u|
100
- if users_id_name.key?(u)
101
- master_admins << users_id_name[u]
102
- elsif users_name_id.key?(u)
103
- master_admins << users_name_id[u]
104
- end
105
- end
106
- end
107
-
108
- Dir["#{config.stats_path}.*.log"].sort.each do |file|
109
- if file >= "#{config.stats_path}.#{from_file}.log" and file <= "#{config.stats_path}.#{to_file}.log"
110
- CSV.foreach(file, headers: true, header_converters: :symbol, converters: :numeric) do |row|
111
- row[:date] = row[:date].to_s
112
- if row[:dest_channel_id].to_s[0]=='D'
113
- row[:dest_channel] = 'DM'
114
- elsif row[:dest_channel].to_s == ''
115
- row[:dest_channel] = row[:dest_channel_id]
116
- end
117
- if users_name_id.size > 0
118
- row[:user_name] = users_id_name[row[:user_id]]
119
- row[:user_id] = users_name_id[row[:user_name]]
120
- else
121
- users_id_name[row[:user_id]] ||= row[:user_name]
122
- end
123
- if !exclude_masters or (exclude_masters and !master_admins.include?(row[:user_name]) and
124
- !master_admins.include?(row[:user_id]) and
125
- !@master_admin_users_id.include?(row[:user_id]))
126
- if !exclude_routines or (exclude_routines and !row[:user_name].match?(/^routine\//) )
127
- if exclude_command == '' or (exclude_command!='' and row[:command]!=exclude_command)
128
- if st_command == '' or (st_command != '' and row[:command] == st_command)
129
- if row[:bot_channel_id] == channel_id or channel_id == '' or row[:dest_channel_id] == channel_id
130
- if row[:date] >= from and row[:date] <= to
131
- count_users[row[:user_id]] ||= 0
132
- count_users[row[:user_id]] += 1
133
- if user=='' or (user!='' and row[:user_name] == user_name) or (user!='' and row[:user_id] == user_id)
134
- rows << row.to_h
135
- count_channels_dest[row[:dest_channel]] ||= 0
136
- count_channels_dest[row[:dest_channel]] += 1
137
- if monthly
138
- rows_month[row[:date][0..6]] = 0 unless rows_month.key?(row[:date][0..6])
139
- users_month[row[:date][0..6]] = [] unless users_month.key?(row[:date][0..6])
140
- commands_month[row[:date][0..6]] = [] unless commands_month.key?(row[:date][0..6])
141
- rows_month[row[:date][0..6]] += 1
142
- users_month[row[:date][0..6]] << row[:user_id]
143
- commands_month[row[:date][0..6]] << row[:command]
144
- end
145
- end
146
- end
147
- end
148
- end
149
- end
150
- end
151
- end
152
- end
153
- end
154
- end
155
- total = rows.size
156
- if exclude_masters
157
- message << 'Excluding master admins'
158
- end
159
- if exclude_routines
160
- message << 'Excluding routines'
161
- end
162
- if exclude_command != ''
163
- message << "Excluding command #{exclude_command}"
164
- end
165
- if st_command != ''
166
- message << "Including only command #{st_command}"
167
- end
168
- if user!=''
169
- if user==from_user.id
170
- message << "Bot stats for <@#{user}>"
171
- else
172
- message << "Showing only user <@#{user}>"
173
- end
174
- end
175
- if channel_id == ''
176
- message << "*Total calls*: #{total} from #{from_short} to #{to_short}"
177
- else
178
- message << "*Total calls <##{channel_id}>*: #{total} from #{from_short} to #{to_short}"
179
- end
180
- unless count_users.size == 0 or total == 0 or user == ''
181
- my_place = (count_users.sort_by(&:last).reverse.to_h.keys.index(user_id)+1)
182
- message <<"\tYou are the *\# #{my_place}* of *#{count_users.size}* users"
183
- end
184
- if total > 0
185
- if monthly
186
- if on_dm_master
187
- message << '*Totals by month / commands / users (%new)*'
188
- else
189
- message << '*Totals by month / commands*'
190
- end
191
-
192
- all_users = []
193
- new_users = []
194
- rows_month.each do |k,v|
195
- if all_users.empty?
196
- message_new_users = ''
197
- else
198
- new_users = (users_month[k]-all_users).uniq
199
- message_new_users = "(#{new_users.size*100/users_month[k].uniq.size}%)"
200
- end
201
- all_users += users_month[k]
202
- if on_dm_master
203
- message << "\t#{k}: #{v} (#{(v.to_f*100/total).round(2)}%) / #{commands_month[k].uniq.size} / #{users_month[k].uniq.size} #{message_new_users}"
204
- else
205
- message << "\t#{k}: #{v} (#{(v.to_f*100/total).round(2)}%) / #{commands_month[k].uniq.size}"
206
- end
207
- end
208
- end
209
-
210
- if channel_id == ''
211
- message << "*SmartBots*"
212
- channels = rows.bot_channel.uniq.sort
213
- channels.each do |channel|
214
- count = rows.count {|h| h.bot_channel==channel}
215
- message << "\t#{channel}: #{count} (#{(count.to_f*100/total).round(2)}%)"
216
- end
217
- end
218
- channels_dest_attachment = []
219
- count_channels_dest = count_channels_dest.sort_by(&:last).reverse.to_h
220
- if count_channels_dest.size > 10
221
- message << "*From Channel* - #{count_channels_dest.size} (Top 10)"
222
- else
223
- message << "*From Channel* - #{count_channels_dest.size}"
224
- end
225
-
226
- count_channels_dest.keys[0..9].each do |ch|
227
- message << "\t#{ch}: #{count_channels_dest[ch]} (#{(count_channels_dest[ch].to_f*100/total).round(2)}%)"
228
- end
229
- if count_channels_dest.size > 10 and all_data
230
- count_channels_dest.each do |ch, value|
231
- channels_dest_attachment << "\t#{ch}: #{value} (#{(value.to_f*100/total).round(2)}%)"
232
- end
233
- end
234
-
235
-
236
- users_attachment = []
237
- if user==''
238
- users = rows.user_id.uniq.sort
239
- if users.size > 10
240
- message << "*Users* - #{users.size} (Top 10)"
241
- else
242
- message << "*Users* - #{users.size}"
243
- end
244
- count_user = {}
245
- users.each do |user|
246
- count = rows.count {|h| h.user_id==user}
247
- count_user[user] = count
248
- end
249
- i = 0
250
- count_user.sort_by {|k,v| -v}.each do |user, count|
251
- i+=1
252
- if i <= 10
253
- message << "\t#{users_id_name[user]}: #{count} (#{(count.to_f*100/total).round(2)}%)"
254
- end
255
- if users.size > 10 and all_data
256
- users_attachment << "\t#{users_id_name[user]}: #{count} (#{(count.to_f*100/total).round(2)}%)"
257
- end
258
- end
259
- end
260
- commands_attachment = []
261
-
262
- if st_command == ''
263
- commands = rows.command.uniq.sort
264
- count_command = {}
265
- commands.each do |command|
266
- count = rows.count {|h| h.command==command}
267
- count_command[command] = count
268
- end
269
-
270
- if commands.size > 10
271
- message << "*Commands* - #{commands.size} (Top 10)"
272
- else
273
- message << "*Commands* - #{commands.size}"
274
- end
275
-
276
- i = 0
277
- count_command.sort_by {|k,v| -v}.each do |command, count|
278
- i+=1
279
- if i <= 10
280
- message << "\t#{command}: #{count} (#{(count.to_f*100/total).round(2)}%)"
281
- end
282
- if commands.size > 10 and all_data
283
- commands_attachment << "\t#{command}: #{count} (#{(count.to_f*100/total).round(2)}%)"
284
- end
285
- end
286
- end
287
-
288
- message << "*Message type*"
289
- types = rows.type_message.uniq.sort
290
- types.each do |type|
291
- count = rows.count {|h| h.type_message==type}
292
- message << "\t#{type}: #{count} (#{(count.to_f*100/total).round(2)}%)"
293
- end
294
-
295
- if on_dm_master
296
- message << "*Last activity*: #{rows[-1].date} #{rows[-1].bot_channel} #{rows[-1].type_message} #{rows[-1].user_name} #{rows[-1].command}"
297
- end
298
- if users_attachment.size>0
299
- send_file(dest, "", 'users.txt', "", 'text/plain', "text", content: users_attachment.join("\n"))
300
- end
301
- if commands_attachment.size>0
302
- send_file(dest, "", 'commands.txt', "", 'text/plain', "text", content: commands_attachment.join("\n"))
303
- end
304
- if channels_dest_attachment.size>0
305
- send_file(dest, "", 'channels_dest.txt', "", 'text/plain', "text", content: channels_dest_attachment.join("\n"))
306
- end
307
- end
308
- end
309
- else
310
- message<<"Only Master admin users on a private conversation with the bot can see this kind of bot stats."
311
- end
312
- respond "#{message.join("\n")}", dest
313
- end
314
- end