slack-smart-bot 1.7.0 → 1.9.1

Sign up to get free protection for your applications and to get access to all the features.
Files changed (61) hide show
  1. checksums.yaml +4 -4
  2. data/README.md +24 -12
  3. data/lib/slack-smart-bot.rb +52 -43
  4. data/lib/slack-smart-bot_general_rules.rb +7 -4
  5. data/lib/slack-smart-bot_rules.rb +8 -6
  6. data/lib/slack/smart-bot/comm.rb +6 -1
  7. data/lib/slack/smart-bot/comm/ask.rb +12 -5
  8. data/lib/slack/smart-bot/comm/dont_understand.rb +1 -1
  9. data/lib/slack/smart-bot/comm/event_hello.rb +30 -0
  10. data/lib/slack/smart-bot/comm/get_channel_members.rb +8 -0
  11. data/lib/slack/smart-bot/comm/get_channels.rb +20 -0
  12. data/lib/slack/smart-bot/comm/get_user_info.rb +16 -0
  13. data/lib/slack/smart-bot/comm/react.rb +21 -8
  14. data/lib/slack/smart-bot/comm/respond.rb +11 -6
  15. data/lib/slack/smart-bot/comm/send_file.rb +1 -1
  16. data/lib/slack/smart-bot/comm/send_msg_channel.rb +2 -2
  17. data/lib/slack/smart-bot/comm/send_msg_user.rb +4 -4
  18. data/lib/slack/smart-bot/comm/unreact.rb +29 -0
  19. data/lib/slack/smart-bot/commands.rb +3 -1
  20. data/lib/slack/smart-bot/commands/general/bot_help.rb +16 -3
  21. data/lib/slack/smart-bot/commands/general/bot_stats.rb +313 -0
  22. data/lib/slack/smart-bot/commands/general/bot_status.rb +1 -1
  23. data/lib/slack/smart-bot/commands/general/bye_bot.rb +1 -1
  24. data/lib/slack/smart-bot/commands/general/hi_bot.rb +1 -1
  25. data/lib/slack/smart-bot/commands/general/use_rules.rb +2 -6
  26. data/lib/slack/smart-bot/commands/general/whats_new.rb +19 -0
  27. data/lib/slack/smart-bot/commands/on_bot/add_shortcut.rb +65 -33
  28. data/lib/slack/smart-bot/commands/on_bot/admin/add_routine.rb +33 -9
  29. data/lib/slack/smart-bot/commands/on_bot/admin/extend_rules.rb +3 -7
  30. data/lib/slack/smart-bot/commands/on_bot/admin/pause_bot.rb +1 -0
  31. data/lib/slack/smart-bot/commands/on_bot/admin/see_routines.rb +9 -2
  32. data/lib/slack/smart-bot/commands/on_bot/admin/start_bot.rb +1 -0
  33. data/lib/slack/smart-bot/commands/on_bot/delete_repl.rb +1 -1
  34. data/lib/slack/smart-bot/commands/on_bot/delete_shortcut.rb +52 -21
  35. data/lib/slack/smart-bot/commands/on_bot/get_repl.rb +5 -5
  36. data/lib/slack/smart-bot/commands/on_bot/repl.rb +50 -18
  37. data/lib/slack/smart-bot/commands/on_bot/ruby_code.rb +34 -9
  38. data/lib/slack/smart-bot/commands/on_bot/run_repl.rb +2 -3
  39. data/lib/slack/smart-bot/commands/on_bot/see_repls.rb +1 -1
  40. data/lib/slack/smart-bot/commands/on_bot/see_shortcuts.rb +27 -9
  41. data/lib/slack/smart-bot/commands/on_extended/bot_rules.rb +14 -1
  42. data/lib/slack/smart-bot/commands/on_master/admin_master/exit_bot.rb +3 -3
  43. data/lib/slack/smart-bot/commands/on_master/admin_master/notify_message.rb +1 -1
  44. data/lib/slack/smart-bot/commands/on_master/admin_master/set_maintenance.rb +41 -0
  45. data/lib/slack/smart-bot/commands/on_master/create_bot.rb +4 -8
  46. data/lib/slack/smart-bot/listen.rb +6 -5
  47. data/lib/slack/smart-bot/process.rb +227 -186
  48. data/lib/slack/smart-bot/process_first.rb +104 -87
  49. data/lib/slack/smart-bot/treat_message.rb +116 -52
  50. data/lib/slack/smart-bot/utils.rb +2 -0
  51. data/lib/slack/smart-bot/utils/answer.rb +18 -0
  52. data/lib/slack/smart-bot/utils/answer_delete.rb +15 -0
  53. data/lib/slack/smart-bot/utils/build_help.rb +57 -5
  54. data/lib/slack/smart-bot/utils/create_routine_thread.rb +48 -8
  55. data/lib/slack/smart-bot/utils/get_channels_name_and_id.rb +1 -7
  56. data/lib/slack/smart-bot/utils/get_help.rb +79 -17
  57. data/lib/slack/smart-bot/utils/save_stats.rb +21 -8
  58. data/lib/slack/smart-bot/utils/update_shortcuts_file.rb +6 -0
  59. data/whats_new.txt +18 -0
  60. metadata +22 -12
  61. data/lib/slack/smart-bot/commands/on_bot/admin_master/bot_stats.rb +0 -135
@@ -13,4 +13,6 @@ require_relative 'utils/update_shortcuts_file'
13
13
  require_relative 'utils/save_stats'
14
14
  require_relative 'utils/get_repls'
15
15
  require_relative 'utils/update_repls'
16
+ require_relative 'utils/answer'
17
+ require_relative 'utils/answer_delete'
16
18
 
@@ -0,0 +1,18 @@
1
+ class SlackSmartBot
2
+ def answer(from = Thread.current[:user].name, dest = Thread.current[:dest])
3
+ if @answer.key?(from)
4
+ if Thread.current[:on_thread]
5
+ dest = Thread.current[:thread_ts]
6
+ end
7
+ if @answer[from].key?(dest)
8
+ return @answer[from][dest]
9
+ else
10
+ return ''
11
+ end
12
+ else
13
+ return ''
14
+ end
15
+ end
16
+
17
+ end
18
+
@@ -0,0 +1,15 @@
1
+ class SlackSmartBot
2
+ def answer_delete(from = Thread.current[:user].name, dest = Thread.current[:dest])
3
+ if @answer.key?(from)
4
+ if Thread.current[:on_thread]
5
+ dest = Thread.current[:thread_ts]
6
+ end
7
+ if @answer[from].key?(dest)
8
+ @answer[from].delete(dest)
9
+ end
10
+ @questions.delete(from) # to be backwards compatible #todo: remove when 2.0
11
+ end
12
+ end
13
+
14
+ end
15
+
@@ -1,12 +1,64 @@
1
1
  class SlackSmartBot
2
2
 
3
- def build_help(path)
4
- help_message = {}
5
- Dir["#{path}/*"].each do |t|
3
+ def build_help(path, expanded)
4
+ help_message = {normal: {}, admin: {}, master: {}}
5
+ if Dir.exist?(path)
6
+ files = Dir["#{path}/*"]
7
+ elsif File.exist?(path)
8
+ files = [path]
9
+ else
10
+ return help_message
11
+ end
12
+
13
+ files.each do |t|
6
14
  if Dir.exist?(t)
7
- help_message[t.scan(/\/(\w+)$/).join.to_sym] = build_help(t)
15
+ res = build_help(t, expanded)
16
+ help_message[:master][t.scan(/\/(\w+)$/).join.to_sym] = res[:master]
17
+ help_message[:admin][t.scan(/\/(\w+)$/).join.to_sym] = res[:admin]
18
+ help_message[:normal][t.scan(/\/(\w+)$/).join.to_sym] = res[:normal]
8
19
  else
9
- help_message[t.scan(/\/(\w+)\.rb$/).join.to_sym] = IO.readlines(t).join.scan(/#\s*help\s*\w*:(.*)/).join("\n")
20
+ lines = IO.readlines(t)
21
+ data = {master:{}, admin:{}, normal:{}}
22
+ data.master = lines.join #normal user help
23
+ data.admin = lines.reject {|l| l.match?(/^\s*#\s*help\s*master\s*:.+$/i)}.join #not master help
24
+ data.normal = lines.reject {|l| l.match?(/^\s*#\s*help\s*(admin|master)\s*:.+$/i)}.join #not admin or master help
25
+ if expanded
26
+ help_message[:master][t.scan(/\/(\w+)\.rb$/).join.to_sym] = data.master.scan(/#\s*help\s*\w*:(.*)/i).join("\n")
27
+ help_message[:admin][t.scan(/\/(\w+)\.rb$/).join.to_sym] = data.admin.scan(/#\s*help\s*\w*:(.*)/i).join("\n")
28
+ help_message[:normal][t.scan(/\/(\w+)\.rb$/).join.to_sym] = data.normal.scan(/#\s*help\s*\w*:(.*)/i).join("\n")
29
+ else
30
+ data.keys.each do |key|
31
+ res = data[key].scan(/#\s*help\s*\w*:(.*)/i).join("\n")
32
+ resf = ""
33
+ command_done = false
34
+ explanation_done = false
35
+ example_done = false
36
+
37
+ res.split("\n").each do |line|
38
+ if line.match?(/^\s*======+$/)
39
+ command_done = true
40
+ explanation_done = true
41
+ example_done = true
42
+ elsif line.match?(/^\s*\-\-\-\-+\s*$/i)
43
+ resf += "\n#{line}"
44
+ command_done = false
45
+ explanation_done = false
46
+ example_done = false
47
+ elsif !command_done and line.match?(/^\s*`.+`\s*/i)
48
+ resf += "\n#{line}"
49
+ command_done = true
50
+ elsif !explanation_done and line.match?(/^\s+[^`].+\s*/i)
51
+ resf += "\n#{line}"
52
+ explanation_done = true
53
+ elsif !example_done and line.match?(/^\s*_.+_\s*/i)
54
+ resf += "\n Example: #{line}"
55
+ example_done = true
56
+ end
57
+ end
58
+ resf += "\n\n"
59
+ help_message[key][t.scan(/\/(\w+)\.rb$/).join.to_sym] = resf
60
+ end
61
+ end
10
62
  end
11
63
  end
12
64
  return help_message
@@ -13,18 +13,29 @@ class SlackSmartBot
13
13
  ruby = ""
14
14
  end
15
15
  @routines[@channel_id][name][:silent] = false if !@routines[@channel_id][name].key?(:silent)
16
-
17
16
  if @routines[@channel_id][name][:at] == "" or
18
17
  (@routines[@channel_id][name][:at] != "" and @routines[@channel_id][name][:running] and
19
18
  @routines[@channel_id][name][:next_run] != "" and Time.now.to_s >= @routines[@channel_id][name][:next_run])
20
19
  if @routines[@channel_id][name][:file_path] != ""
21
20
  process_to_run = "#{ruby}#{Dir.pwd}#{@routines[@channel_id][name][:file_path][1..-1]}"
22
21
  process_to_run = ("cd #{project_folder} &&" + process_to_run) if defined?(project_folder)
23
-
22
+ data = {
23
+ dest: @routines[@channel_id][name][:dest],
24
+ typem: 'routine_file',
25
+ user: {id: @routines[@channel_id][name][:creator_id], name: @routines[@channel_id][name][:creator]},
26
+ files: false,
27
+ command: @routines[@channel_id][name][:file_path],
28
+ routine: true
29
+ }
30
+ save_stats(name, data: data)
24
31
  stdout, stderr, status = Open3.capture3(process_to_run)
25
32
  if !@routines[@channel_id][name][:silent] or (@routines[@channel_id][name][:silent] and
26
33
  (!stderr.match?(/\A\s*\z/) or !stdout.match?(/\A\s*\z/)))
27
- respond "routine *`#{name}`*: #{@routines[@channel_id][name][:file_path]}", @routines[@channel_id][name][:dest]
34
+ if @routines[@channel_id][name][:dest]!=@channel_id
35
+ respond "routine from <##{@channel_id}> *`#{name}`*: #{@routines[@channel_id][name][:file_path]}", @routines[@channel_id][name][:dest]
36
+ else
37
+ respond "routine *`#{name}`*: #{@routines[@channel_id][name][:file_path]}", @routines[@channel_id][name][:dest]
38
+ end
28
39
  end
29
40
  if stderr == ""
30
41
  unless stdout.match?(/\A\s*\z/)
@@ -35,13 +46,19 @@ class SlackSmartBot
35
46
  end
36
47
  else #command
37
48
  if !@routines[@channel_id][name][:silent]
38
- respond "routine *`#{name}`*: #{@routines[@channel_id][name][:command]}", @routines[@channel_id][name][:dest]
49
+ if @routines[@channel_id][name][:dest]!=@channel_id
50
+ respond "routine from <##{@channel_id}> *`#{name}`*: #{@routines[@channel_id][name][:command]}", @routines[@channel_id][name][:dest]
51
+ else
52
+ respond "routine *`#{name}`*: #{@routines[@channel_id][name][:command]}", @routines[@channel_id][name][:dest]
53
+ end
39
54
  end
40
55
  started = Time.now
41
- data = { channel: @routines[@channel_id][name][:dest],
56
+ data = { channel: @channel_id,
57
+ dest: @routines[@channel_id][name][:dest],
42
58
  user: @routines[@channel_id][name][:creator_id],
43
59
  text: @routines[@channel_id][name][:command],
44
- files: nil }
60
+ files: nil,
61
+ routine: true }
45
62
  treat_message(data)
46
63
  end
47
64
  # in case the routine was deleted while running the process
@@ -55,11 +72,34 @@ class SlackSmartBot
55
72
  require "time"
56
73
  every_in_seconds = Time.parse(@routines[@channel_id][name][:next_run]) - Time.now
57
74
  elsif @routines[@channel_id][name][:at] != "" #coming from start after pause for 'at'
58
- if started.strftime("%H:%M:%S") < @routines[@channel_id][name][:at]
75
+ if @routines[@channel_id][name].key?(:dayweek) and @routines[@channel_id][name][:dayweek].to_s!=''
76
+ day = @routines[@channel_id][name][:dayweek]
77
+ days = ['sunday','monday','tuesday','wednesday','thursday','friday','saturday']
78
+ incr = days.index(day) - Time.now.wday
79
+ if incr < 0
80
+ incr = (7+incr)*24*60*60
81
+ else
82
+ incr = incr * 24 * 60 * 60
83
+ end
84
+ days = incr/(24*60*60)
85
+ weekly = true
86
+ else
87
+ days = 0
88
+ weekly = false
89
+ end
90
+
91
+ if started.strftime("%H:%M:%S") < @routines[@channel_id][name][:at] and days == 0
59
92
  nt = @routines[@channel_id][name][:at].split(":")
60
93
  next_run = Time.new(started.year, started.month, started.day, nt[0], nt[1], nt[2])
61
94
  else
62
- next_run = started + (24 * 60 * 60) # one more day
95
+ if days == 0 and started.strftime("%H:%M:%S") >= @routines[@channel_id][name][:at]
96
+ if weekly
97
+ days = 7
98
+ else
99
+ days = 1
100
+ end
101
+ end
102
+ next_run = started + (days * 24 * 60 * 60) # one more day/week
63
103
  nt = @routines[@channel_id][name][:at].split(":")
64
104
  next_run = Time.new(next_run.year, next_run.month, next_run.day, nt[0], nt[1], nt[2])
65
105
  end
@@ -1,13 +1,7 @@
1
1
  class SlackSmartBot
2
2
 
3
3
  def get_channels_name_and_id
4
- #todo: add pagination for case more than 1000 channels on the workspace
5
- channels = client.web_client.conversations_list(
6
- types: "private_channel,public_channel",
7
- limit: "1000",
8
- exclude_archived: "true",
9
- ).channels
10
-
4
+ channels = get_channels()
11
5
  @channels_id = Hash.new()
12
6
  @channels_name = Hash.new()
13
7
  channels.each do |ch|
@@ -1,18 +1,17 @@
1
1
  class SlackSmartBot
2
- def get_help(rules_file, dest, from, only_rules = false)
2
+ def get_help(rules_file, dest, from, only_rules, expanded)
3
3
  order = {
4
- general: [:hi_bot, :bye_bot, :bot_help, :bot_status, :use_rules, :stop_using_rules],
4
+ general: [:whats_new, :hi_bot, :bye_bot, :bot_help, :bot_status, :use_rules, :stop_using_rules, :bot_stats],
5
5
  on_bot: [:ruby_code, :repl, :get_repl, :run_repl, :delete_repl, :see_repls, :add_shortcut, :delete_shortcut, :see_shortcuts],
6
6
  on_bot_admin: [:extend_rules, :stop_using_rules_on, :start_bot, :pause_bot, :add_routine,
7
7
  :see_routines, :start_routine, :pause_routine, :remove_routine, :run_routine]
8
8
  }
9
- # user_type: :admin, :user, :admin_master
10
9
  if config.masters.include?(from)
11
- user_type = :admin_master
10
+ user_type = :master # master admin
12
11
  elsif config.admins.include?(from)
13
12
  user_type = :admin
14
13
  else
15
- user_type = :user
14
+ user_type = :normal #normal user
16
15
  end
17
16
  # channel_type: :bot, :master_bot, :direct, :extended, :external
18
17
  if dest[0] == "D"
@@ -25,27 +24,45 @@ class SlackSmartBot
25
24
  channel_type = :bot
26
25
  end
27
26
 
28
- @help_messages ||= build_help("#{__dir__}/../commands")
27
+ @help_messages_expanded ||= build_help("#{__dir__}/../commands", true)
28
+ @help_messages_not_expanded ||= build_help("#{__dir__}/../commands", false)
29
29
  if only_rules
30
30
  help = {}
31
+ elsif expanded
32
+ help = @help_messages_expanded.deep_copy[user_type]
31
33
  else
32
- help = @help_messages.deep_copy
34
+ help = @help_messages_not_expanded.deep_copy[user_type]
33
35
  end
36
+
34
37
  if rules_file != ""
35
- help[:rules_file] = ''
36
- help[:rules_file] += IO.readlines(config.path+rules_file).join.scan(/#\s*help\s*\w*:(.*)/i).join("\n") + "\n"
37
- if File.exist?(config.path+'/rules/general_rules.rb')
38
- help[:rules_file] += IO.readlines(config.path+'/rules/general_rules.rb').join.scan(/#\s*help\s*\w*:(.*)/i).join("\n")
38
+ help[:rules_file] = build_help(config.path+rules_file, expanded)[user_type].values.join("\n") + "\n"
39
+
40
+ # to get all the help from other rules files added to the main rules file by using require or load. For example general_rules.rb
41
+ res = IO.readlines(config.path+rules_file).join.scan(/$\s*(load|require)\s("|')(.+)("|')/)
42
+ rules_help = []
43
+ txt = ''
44
+ if res.size>0
45
+ res.each do |r|
46
+ begin
47
+ eval("txt = \"#{r[2]}\"")
48
+ rules_help << txt if File.exist?(txt)
49
+ rescue
50
+ end
51
+ end
52
+ end
53
+ rules_help.each do |rh|
54
+ rhelp = build_help(rh, expanded)
55
+ help[:rules_file] += rhelp[user_type].values.join("\n") + "\n"
39
56
  end
40
57
  end
41
- help = remove_hash_keys(help, :admin_master) unless user_type == :admin_master
42
- help = remove_hash_keys(help, :admin) unless user_type == :admin or user_type == :admin_master
58
+ help = remove_hash_keys(help, :admin_master) unless user_type == :master
59
+ help = remove_hash_keys(help, :admin) unless user_type == :admin or user_type == :master
43
60
  help = remove_hash_keys(help, :on_master) unless channel_type == :master_bot
44
61
  help = remove_hash_keys(help, :on_extended) unless channel_type == :extended
45
62
  help = remove_hash_keys(help, :on_dm) unless channel_type == :direct
46
63
  txt = ""
47
64
 
48
- if channel_type == :bot or channel_type == :master_bot
65
+ if (channel_type == :bot or channel_type == :master_bot) and expanded
49
66
  txt += "===================================
50
67
  For the Smart Bot start listening to you say *hi bot*
51
68
  To run a command on demand even when the Smart Bot is not listening to you:
@@ -56,11 +73,11 @@ class SlackSmartBot
56
73
  *^THE_COMMAND*
57
74
  *!!THE_COMMAND*\n"
58
75
  end
59
- if channel_type == :direct
76
+ if channel_type == :direct and expanded
60
77
  txt += "===================================
61
78
  When on a private conversation with the Smart Bot, I'm always listening to you.\n"
62
79
  end
63
- unless channel_type == :master_bot or channel_type == :extended
80
+ unless channel_type == :master_bot or channel_type == :extended or !expanded
64
81
  txt += "===================================
65
82
  *Commands from Channels without a bot:*
66
83
  ----------------------------------------------
@@ -121,7 +138,7 @@ class SlackSmartBot
121
138
 
122
139
  if help.key?(:on_master) and help.on_master.key?(:admin_master) and help.on_master.admin_master.size > 0
123
140
  txt += "===================================
124
- *Master Admin commands:*\n"
141
+ *Master Admin commands:*\n" unless txt.include?('*Master Admin commands*')
125
142
  help.on_master.admin_master.each do |k, v|
126
143
  txt += v if v.is_a?(String)
127
144
  end
@@ -133,6 +150,51 @@ class SlackSmartBot
133
150
  @logger.info help.rules_file if config.testing
134
151
  help.rules_file = help.rules_file.gsub(/^\s*\*These are specific commands.+NAME_OF_BOT THE_COMMAND`\s*$/im, "")
135
152
  end
153
+
154
+ unless expanded
155
+ resf = ''
156
+ help.rules_file.split(/^\s*\-+\s*$/).each do |rule|
157
+ command_done = false
158
+ explanation_done = false
159
+ example_done = false
160
+ if rule.match?(/These are specific commands for this/i)
161
+ resf += rule
162
+ resf += "-"*50
163
+ resf += "\n"
164
+ elsif rule.match?(/To run a command on demand and add the respond on a thread/i)
165
+ resf += rule
166
+ resf += "-"*50
167
+ resf += "\n"
168
+ else
169
+ rule.split("\n").each do |line|
170
+ if line.match?(/^\s*\-+\s*/i)
171
+ resf += line
172
+ elsif !command_done and line.match?(/^\s*`.+`\s*/i)
173
+ resf += "\n#{line}"
174
+ command_done = true
175
+ elsif !explanation_done and line.match?(/^\s+[^`].+\s*/i)
176
+ resf += "\n#{line}"
177
+ explanation_done = true
178
+ elsif !example_done and line.match?(/^\s*_.+_\s*/i)
179
+ resf += "\n Example: #{line}"
180
+ example_done = true
181
+ end
182
+ end
183
+ resf += "\n\n"
184
+ end
185
+ end
186
+ unless resf.match?(/These are specific commands for this bot on this Channel/i)
187
+ if resf.match?(/\A\s*[=\-]+$/)
188
+ pre = ''
189
+ post = ''
190
+ else
191
+ pre = ('='*50) + "\n"
192
+ post = ('-'*50) + "\n"
193
+ end
194
+ resf = "#{pre}*These are specific commands for this bot on this Channel:*\n#{post}" + resf
195
+ end
196
+ help.rules_file = resf
197
+ end
136
198
  txt += help.rules_file
137
199
  end
138
200
 
@@ -1,6 +1,6 @@
1
1
  class SlackSmartBot
2
2
 
3
- def save_stats(method)
3
+ def save_stats(method, data: {})
4
4
  if config.stats
5
5
  begin
6
6
  require 'csv'
@@ -9,18 +9,31 @@ class SlackSmartBot
9
9
  csv << ['date','bot_channel', 'bot_channel_id', 'dest_channel', 'dest_channel_id', 'type_message', 'user_name', 'user_id', 'text', 'command', 'files']
10
10
  end
11
11
  end
12
- dest = Thread.current[:dest]
13
- typem = Thread.current[:typem]
14
- user = Thread.current[:user]
15
- files = Thread.current[:files?]
16
- if method.to_s == 'ruby_code' and files
12
+ if data.empty?
13
+ data = {
14
+ dest: Thread.current[:dest],
15
+ typem: Thread.current[:typem],
16
+ user: Thread.current[:user],
17
+ files: Thread.current[:files?],
18
+ command: Thread.current[:command],
19
+ routine: Thread.current[:routine]
20
+ }
21
+ end
22
+ if method.to_s == 'ruby_code' and data.files
17
23
  command_txt = 'ruby'
18
24
  else
19
- command_txt = Thread.current[:command]
25
+ command_txt = data.command
20
26
  end
21
27
 
28
+ if data.routine
29
+ user_name = "routine/#{data.user.name}"
30
+ user_id = "routine/#{data.user.id}"
31
+ else
32
+ user_name = data.user.name
33
+ user_id = data.user.id
34
+ end
22
35
  CSV.open("#{config.stats_path}.#{Time.now.strftime("%Y-%m")}.log", "a+") do |csv|
23
- csv << [Time.now, config.channel, @channel_id, @channels_name[dest], dest, typem, user.name, user.id, command_txt, method, files]
36
+ csv << [Time.now, config.channel, @channel_id, @channels_name[data.dest], data.dest, data.typem, user_name, user_id, command_txt, method, data.files]
24
37
  end
25
38
  rescue Exception => exception
26
39
  @logger.fatal "There was a problem on the stats"
@@ -3,5 +3,11 @@ class SlackSmartBot
3
3
  file = File.open("#{config.path}/shortcuts/#{config.shortcuts_file}", "w")
4
4
  file.write @shortcuts.inspect
5
5
  file.close
6
+
7
+ if config.on_master_bot
8
+ file = File.open("#{config.path}/shortcuts/shortcuts_global.rb", "w")
9
+ file.write @shortcuts_global.inspect
10
+ file.close
11
+ end
6
12
  end
7
13
  end
data/whats_new.txt ADDED
@@ -0,0 +1,18 @@
1
+ *Version 1.9.1* Released 2021-Mar-18
2
+
3
+ *For General users*
4
+ - Added command `what's new` that will show this.
5
+ - `bot stats` will return detailed statistics using the SmartBot. If you call it from a DM with the SmartBot you will see all stats for all Bot channels.
6
+ - Possible to create 'global' shortcuts that will be available on any SmartBot Channel.
7
+ - Added option to start a `repl` without pre-executing '.smart-bot-repl' source code in case exists. Just add `clean` before the `repl` command. For example: `clean repl Example`
8
+ - When using `Ruby` command in case the process doesn't finish in 20 seconds will be aborted.
9
+ - When creating rules/commands and asking a question now you can use 'answer' instead of '@questions'. Take a look at README.md for an example.
10
+ - Using external calls, it is possible to send to more than one bot channel the same rule: `@smart-bot on #channel1 #channel2 #channel3 echo Lala`
11
+ - `bot help` and `bot rules` return by default a short version of the commands. Call `bot help expanded` or `bot rules expanded` to get a full desciption of the commands.
12
+ - It is possible to exclude routines from results when using `bot stats`
13
+ ------------------------------
14
+ *For Admin users*
15
+ - `Bot stats` now shows the top 10 users and attaches the full list of users and commands.
16
+ - Bot Stats. Now the routines are displayed as routine/USER
17
+ - When creating routines now it is possible to publish in a different channel: `add routine run_tests at 17:05 #thechannel !run api tests`
18
+ - `Turn maintenance on/off` command available