slack-smart-bot 1.9.1 → 1.11.0

Sign up to get free protection for your applications and to get access to all the features.
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
@@ -1,313 +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:
32
- def bot_stats(dest, from_user, typem, channel_id, from, to, user, st_command, exclude_masters, exclude_routines, exclude_command, monthly, all_data)
33
- require 'csv'
34
- if config.stats
35
- message = []
36
- else
37
- message = ["You need to set stats to true to generate the stats when running the bot instance."]
38
- end
39
- save_stats(__method__)
40
- 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'))
41
- on_dm_master = true #master admin user
42
- else
43
- on_dm_master = false
44
- end
45
- if on_dm_master or (from_user.id == user) # normal user can only see own stats
46
- if !File.exist?("#{config.stats_path}.#{Time.now.strftime("%Y-%m")}.log")
47
- message<<'No stats'
48
- else
49
- from = "#{Time.now.strftime("%Y-%m")}-01" if from == ''
50
- to = "#{Time.now.strftime("%Y-%m-%d")}" if to == ''
51
- from_short = from
52
- to_short = to
53
- from_file = from[0..3] + '-' + from[5..6]
54
- to_file = to[0..3] + '-' + to[5..6]
55
- from+= " 00:00:00 +0000"
56
- to+= " 23:59:59 +0000"
57
- rows = []
58
- rows_month = {}
59
- users_month = {}
60
- commands_month = {}
61
- users_id_name = {}
62
- users_name_id = {}
63
- count_users = {}
64
- count_channels_dest = {}
65
-
66
- # to translate global and enterprise users since sometimes was returning different names/ids
67
- if from[0..3]=='2020' # this was an issue only on that period
68
- Dir["#{config.stats_path}.*.log"].sort.each do |file|
69
- if file >= "#{config.stats_path}.#{from_file}.log" or file <= "#{config.stats_path}.#{to_file}.log"
70
- CSV.foreach(file, headers: true, header_converters: :symbol, converters: :numeric) do |row|
71
- unless users_id_name.key?(row[:user_id])
72
- users_id_name[row[:user_id]] = row[:user_name]
73
- end
74
- unless users_name_id.key?(row[:user_name])
75
- users_name_id[row[:user_name]] = row[:user_id]
76
- end
77
-
78
- end
79
- end
80
- end
81
- end
82
-
83
- if user!=''
84
- user_info = get_user_info(user)
85
- if users_id_name.key?(user_info.user.id)
86
- user_name = users_id_name[user_info.user.id]
87
- else
88
- user_name = user_info.user.name
89
- end
90
- if users_name_id.key?(user_info.user.name)
91
- user_id = users_name_id[user_info.user.name]
92
- else
93
- user_id = user_info.user.id
94
- end
95
- end
96
- master_admins = config.masters.dup
97
- if users_id_name.size > 0
98
- config.masters.each do |u|
99
- if users_id_name.key?(u)
100
- master_admins << users_id_name[u]
101
- elsif users_name_id.key?(u)
102
- master_admins << users_name_id[u]
103
- end
104
- end
105
- end
106
-
107
- Dir["#{config.stats_path}.*.log"].sort.each do |file|
108
- if file >= "#{config.stats_path}.#{from_file}.log" or file <= "#{config.stats_path}.#{to_file}.log"
109
- CSV.foreach(file, headers: true, header_converters: :symbol, converters: :numeric) do |row|
110
- row[:date] = row[:date].to_s
111
- if row[:dest_channel_id].to_s[0]=='D'
112
- row[:dest_channel] = 'DM'
113
- elsif row[:dest_channel].to_s == ''
114
- row[:dest_channel] = row[:dest_channel_id]
115
- end
116
- if users_name_id.size > 0
117
- row[:user_name] = users_id_name[row[:user_id]]
118
- row[:user_id] = users_name_id[row[:user_name]]
119
- else
120
- users_id_name[row[:user_id]] ||= row[:user_name]
121
- end
122
- if !exclude_masters or (exclude_masters and !master_admins.include?(row[:user_name]) and
123
- !master_admins.include?(row[:user_id]) and
124
- !@master_admin_users_id.include?(row[:user_id]))
125
- if !exclude_routines or (exclude_routines and !row[:user_name].match?(/^routine\//) )
126
- if exclude_command == '' or (exclude_command!='' and row[:command]!=exclude_command)
127
- if st_command == '' or (st_command != '' and row[:command] == st_command)
128
- if row[:bot_channel_id] == channel_id or channel_id == ''
129
- if row[:date] >= from and row[:date] <= to
130
- count_users[row[:user_id]] ||= 0
131
- count_users[row[:user_id]] += 1
132
- if user=='' or (user!='' and row[:user_name] == user_name) or (user!='' and row[:user_id] == user_id)
133
- rows << row.to_h
134
- count_channels_dest[row[:dest_channel]] ||= 0
135
- count_channels_dest[row[:dest_channel]] += 1
136
- if monthly
137
- rows_month[row[:date][0..6]] = 0 unless rows_month.key?(row[:date][0..6])
138
- users_month[row[:date][0..6]] = [] unless users_month.key?(row[:date][0..6])
139
- commands_month[row[:date][0..6]] = [] unless commands_month.key?(row[:date][0..6])
140
- rows_month[row[:date][0..6]] += 1
141
- users_month[row[:date][0..6]] << row[:user_id]
142
- commands_month[row[:date][0..6]] << row[:command]
143
- end
144
- end
145
- end
146
- end
147
- end
148
- end
149
- end
150
- end
151
- end
152
- end
153
- end
154
- total = rows.size
155
- if exclude_masters
156
- message << 'Excluding master admins'
157
- end
158
- if exclude_routines
159
- message << 'Excluding routines'
160
- end
161
- if exclude_command != ''
162
- message << "Excluding command #{exclude_command}"
163
- end
164
- if st_command != ''
165
- message << "Including only command #{st_command}"
166
- end
167
- if user!=''
168
- if user==from_user.id
169
- message << "Bot stats for <@#{user}>"
170
- else
171
- message << "Showing only user <@#{user}>"
172
- end
173
- end
174
- if channel_id == ''
175
- message << "*Total calls*: #{total} from #{from_short} to #{to_short}"
176
- else
177
- message << "*Total calls <##{channel_id}>*: #{total} from #{from_short} to #{to_short}"
178
- end
179
- unless count_users.size == 0 or total == 0 or user == ''
180
- my_place = (count_users.sort_by(&:last).reverse.to_h.keys.index(user_id)+1)
181
- message <<"\tYou are the *\# #{my_place}* of *#{count_users.size}* users"
182
- end
183
- if total > 0
184
- if monthly
185
- if on_dm_master
186
- message << '*Totals by month / commands / users (%new)*'
187
- else
188
- message << '*Totals by month / commands*'
189
- end
190
-
191
- all_users = []
192
- new_users = []
193
- rows_month.each do |k,v|
194
- if all_users.empty?
195
- message_new_users = ''
196
- else
197
- new_users = (users_month[k]-all_users).uniq
198
- message_new_users = "(#{new_users.size*100/users_month[k].uniq.size}%)"
199
- end
200
- all_users += users_month[k]
201
- if on_dm_master
202
- message << "\t#{k}: #{v} (#{(v.to_f*100/total).round(2)}%) / #{commands_month[k].uniq.size} / #{users_month[k].uniq.size} #{message_new_users}"
203
- else
204
- message << "\t#{k}: #{v} (#{(v.to_f*100/total).round(2)}%) / #{commands_month[k].uniq.size}"
205
- end
206
- end
207
- end
208
-
209
- if channel_id == ''
210
- message << "*SmartBots*"
211
- channels = rows.bot_channel.uniq.sort
212
- channels.each do |channel|
213
- count = rows.count {|h| h.bot_channel==channel}
214
- message << "\t#{channel}: #{count} (#{(count.to_f*100/total).round(2)}%)"
215
- end
216
- end
217
- channels_dest_attachment = []
218
- count_channels_dest = count_channels_dest.sort_by(&:last).reverse.to_h
219
- if count_channels_dest.size > 10
220
- message << "*From Channel* - #{count_channels_dest.size} (Top 10)"
221
- else
222
- message << "*From Channel* - #{count_channels_dest.size}"
223
- end
224
-
225
- count_channels_dest.keys[0..9].each do |ch|
226
- message << "\t#{ch}: #{count_channels_dest[ch]} (#{(count_channels_dest[ch].to_f*100/total).round(2)}%)"
227
- end
228
- if count_channels_dest.size > 10 and all_data
229
- count_channels_dest.each do |ch, value|
230
- channels_dest_attachment << "\t#{ch}: #{value} (#{(value.to_f*100/total).round(2)}%)"
231
- end
232
- end
233
-
234
-
235
- users_attachment = []
236
- if user==''
237
- users = rows.user_id.uniq.sort
238
- if users.size > 10
239
- message << "*Users* - #{users.size} (Top 10)"
240
- else
241
- message << "*Users* - #{users.size}"
242
- end
243
- count_user = {}
244
- users.each do |user|
245
- count = rows.count {|h| h.user_id==user}
246
- count_user[user] = count
247
- end
248
- i = 0
249
- count_user.sort_by {|k,v| -v}.each do |user, count|
250
- i+=1
251
- if i <= 10
252
- message << "\t#{users_id_name[user]}: #{count} (#{(count.to_f*100/total).round(2)}%)"
253
- end
254
- if users.size > 10 and all_data
255
- users_attachment << "\t#{users_id_name[user]}: #{count} (#{(count.to_f*100/total).round(2)}%)"
256
- end
257
- end
258
- end
259
- commands_attachment = []
260
-
261
- if st_command == ''
262
- commands = rows.command.uniq.sort
263
- count_command = {}
264
- commands.each do |command|
265
- count = rows.count {|h| h.command==command}
266
- count_command[command] = count
267
- end
268
-
269
- if commands.size > 10
270
- message << "*Commands* - #{commands.size} (Top 10)"
271
- else
272
- message << "*Commands* - #{commands.size}"
273
- end
274
-
275
- i = 0
276
- count_command.sort_by {|k,v| -v}.each do |command, count|
277
- i+=1
278
- if i <= 10
279
- message << "\t#{command}: #{count} (#{(count.to_f*100/total).round(2)}%)"
280
- end
281
- if commands.size > 10 and all_data
282
- commands_attachment << "\t#{command}: #{count} (#{(count.to_f*100/total).round(2)}%)"
283
- end
284
- end
285
- end
286
-
287
- message << "*Message type*"
288
- types = rows.type_message.uniq.sort
289
- types.each do |type|
290
- count = rows.count {|h| h.type_message==type}
291
- message << "\t#{type}: #{count} (#{(count.to_f*100/total).round(2)}%)"
292
- end
293
-
294
- if on_dm_master
295
- message << "*Last activity*: #{rows[-1].date} #{rows[-1].bot_channel} #{rows[-1].type_message} #{rows[-1].user_name} #{rows[-1].command}"
296
- end
297
- if users_attachment.size>0
298
- send_file(dest, "", 'users.txt', "", 'text/plain', "text", content: users_attachment.join("\n"))
299
- end
300
- if commands_attachment.size>0
301
- send_file(dest, "", 'commands.txt', "", 'text/plain', "text", content: commands_attachment.join("\n"))
302
- end
303
- if channels_dest_attachment.size>0
304
- send_file(dest, "", 'channels_dest.txt', "", 'text/plain', "text", content: channels_dest_attachment.join("\n"))
305
- end
306
- end
307
- end
308
- else
309
- message<<"Only Master admin users on a private conversation with the bot can see this kind of bot stats."
310
- end
311
- respond "#{message.join("\n")}", dest
312
- end
313
- end