slack-smart-bot 0.9.6 → 1.0.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (37) hide show
  1. checksums.yaml +4 -4
  2. data/.yardopts +5 -1
  3. data/README.md +80 -175
  4. data/lib/slack-smart-bot.rb +95 -1276
  5. data/lib/slack-smart-bot_rules.rb +50 -69
  6. data/lib/slack/smart-bot/comm.rb +197 -0
  7. data/lib/slack/smart-bot/commands/general/bot_help.rb +74 -0
  8. data/lib/slack/smart-bot/commands/general/bot_status.rb +41 -0
  9. data/lib/slack/smart-bot/commands/general/bye_bot.rb +17 -0
  10. data/lib/slack/smart-bot/commands/general/hi_bot.rb +24 -0
  11. data/lib/slack/smart-bot/commands/general/stop_using_rules.rb +44 -0
  12. data/lib/slack/smart-bot/commands/general/use_rules.rb +48 -0
  13. data/lib/slack/smart-bot/commands/on_bot/add_shortcut.rb +64 -0
  14. data/lib/slack/smart-bot/commands/on_bot/admin/add_routine.rb +87 -0
  15. data/lib/slack/smart-bot/commands/on_bot/admin/extend_rules.rb +63 -0
  16. data/lib/slack/smart-bot/commands/on_bot/admin/pause_bot.rb +21 -0
  17. data/lib/slack/smart-bot/commands/on_bot/admin/pause_routine.rb +26 -0
  18. data/lib/slack/smart-bot/commands/on_bot/admin/remove_routine.rb +28 -0
  19. data/lib/slack/smart-bot/commands/on_bot/admin/run_routine.rb +53 -0
  20. data/lib/slack/smart-bot/commands/on_bot/admin/see_routines.rb +57 -0
  21. data/lib/slack/smart-bot/commands/on_bot/admin/start_bot.rb +20 -0
  22. data/lib/slack/smart-bot/commands/on_bot/admin/start_routine.rb +27 -0
  23. data/lib/slack/smart-bot/commands/on_bot/admin/stop_using_rules_on.rb +30 -0
  24. data/lib/slack/smart-bot/commands/on_bot/delete_shortcut.rb +41 -0
  25. data/lib/slack/smart-bot/commands/on_bot/ruby_code.rb +48 -0
  26. data/lib/slack/smart-bot/commands/on_bot/see_shortcuts.rb +32 -0
  27. data/lib/slack/smart-bot/commands/on_extended/bot_rules.rb +37 -0
  28. data/lib/slack/smart-bot/commands/on_master/admin/kill_bot_on_channel.rb +38 -0
  29. data/lib/slack/smart-bot/commands/on_master/admin_master/exit_bot.rb +42 -0
  30. data/lib/slack/smart-bot/commands/on_master/admin_master/notify_message.rb +35 -0
  31. data/lib/slack/smart-bot/commands/on_master/create_bot.rb +94 -0
  32. data/lib/slack/smart-bot/listen.rb +36 -0
  33. data/lib/slack/smart-bot/process.rb +169 -0
  34. data/lib/slack/smart-bot/process_first.rb +201 -0
  35. data/lib/slack/smart-bot/treat_message.rb +139 -0
  36. data/lib/slack/smart-bot/utils.rb +299 -0
  37. metadata +71 -5
@@ -0,0 +1,139 @@
1
+ class SlackSmartBot
2
+ def treat_message(data)
3
+ if config[:testing] and ON_MASTER_BOT
4
+ open("./buffer.log", "a") { |f|
5
+ f.puts "|#{data.channel}|#{data.user}|#{data.text}"
6
+ }
7
+ end
8
+ if data.channel[0] == "D" or data.channel[0] == "C" or data.channel[0] == "G" #Direct message or Channel or Private Channel
9
+ dest = data.channel
10
+ else # not treated
11
+ dest = nil
12
+ end
13
+ #todo: sometimes data.user is nil, check the problem.
14
+ @logger.warn "!dest is nil. user: #{data.user}, channel: #{data.channel}, message: #{data.text}" if dest.nil?
15
+ if !data.files.nil? and data.files.size == 1 and data.text.to_s == "" and data.files[0].filetype == "ruby"
16
+ data.text = "ruby"
17
+ end
18
+ if !dest.nil? and ON_MASTER_BOT and !data.text.nil? and data.text.match(/^ping from (.+)\s*$/) and data.user == config[:nick_id]
19
+ @pings << $1
20
+ end
21
+ typem = :dont_treat
22
+ if !dest.nil? and !data.text.nil? and !data.text.to_s.match?(/^\s*$/)
23
+ if data.text.match(/^<@#{config[:nick_id]}>\s(on\s)?<#(\w+)\|([^>]+)>\s*:?\s*(.*)/im)
24
+ channel_rules = $2
25
+ channel_rules_name = $3
26
+ # to be treated only on the bot of the requested channel
27
+ if @channel_id == channel_rules
28
+ data.text = $4
29
+ typem = :on_call
30
+ end
31
+ elsif dest == @master_bot_id
32
+ if ON_MASTER_BOT #only to be treated on master mot channel
33
+ typem = :on_master
34
+ end
35
+ elsif @bots_created.key?(dest)
36
+ if @channel_id == dest #only to be treated by the bot on the channel
37
+ typem = :on_bot
38
+ end
39
+ elsif dest[0] == "D" #Direct message
40
+ if ON_MASTER_BOT #only to be treated by master bot
41
+ typem = :on_dm
42
+ end
43
+ elsif dest[0] == "C" or dest[0] == "G"
44
+ #only to be treated on the channel of the bot. excluding running ruby
45
+ if !ON_MASTER_BOT and @bots_created[@channel_id][:extended].include?(@channels_name[dest]) and
46
+ !data.text.match?(/^!?\s*(ruby|code)\s+/)
47
+ typem = :on_extended
48
+ elsif ON_MASTER_BOT and data.text.match?(/^!?\s*(ruby|code)\s+/) #or in case of running ruby, the master bot
49
+ @bots_created.each do |k, v|
50
+ if v.key?(:extended) and v[:extended].include?(@channels_name[dest])
51
+ typem = :on_extended
52
+ break
53
+ end
54
+ end
55
+ end
56
+ if dest[0] == "G" and ON_MASTER_BOT and typem != :on_extended #private group
57
+ typem = :on_pg
58
+ end
59
+ end
60
+ end
61
+
62
+ unless typem == :dont_treat
63
+ begin
64
+ #todo: when changed @questions user_id then move user_info inside the ifs to avoid calling it when not necessary
65
+ user_info = client.web_client.users_info(user: data.user)
66
+
67
+ if @questions.key?(user_info.user.name)
68
+ if data.text.match?(/^\s*(Bye|Bæ|Good\sBye|Adiós|Ciao|Bless|Bless\sBless|Adeu)\s(#{@salutations.join("|")})\s*$/i)
69
+ @questions.delete(user_info.user.name)
70
+ command = data.text
71
+ else
72
+ command = @questions[user_info.user.name]
73
+ @questions[user_info.user.name] = data.text
74
+ end
75
+ else
76
+ command = data.text
77
+ end
78
+
79
+ #when added special characters on the message
80
+ if command.size >= 2 and
81
+ ((command[0] == "`" and command[-1] == "`") or (command[0] == "*" and command[-1] == "*") or (command[0] == "_" and command[-1] == "_"))
82
+ command = command[1..-2]
83
+ end
84
+
85
+ #ruby file attached
86
+ if !data.files.nil? and data.files.size == 1 and
87
+ (command.match?(/^(ruby|code)\s*$/) or (command.match?(/^\s*$/) and data.files[0].filetype == "ruby") or
88
+ (typem == :on_call and data.files[0].filetype == "ruby"))
89
+ res = Faraday.new("https://files.slack.com", headers: { "Authorization" => "Bearer #{config[:token]}" }).get(data.files[0].url_private)
90
+ command += " ruby" if command != "ruby"
91
+ command = "#{command} #{res.body.to_s.force_encoding("UTF-8")}"
92
+ end
93
+
94
+ if typem == :on_call
95
+ command = "!" + command unless command[0] == "!" or command.match?(/^\s*$/)
96
+
97
+ #todo: add pagination for case more than 1000 channels on the workspace
98
+ channels = client.web_client.conversations_list(
99
+ types: "private_channel,public_channel",
100
+ limit: "1000",
101
+ exclude_archived: "true",
102
+ ).channels
103
+ channel_found = channels.detect { |c| c.name == channel_rules_name }
104
+ members = client.web_client.conversations_members(channel: @channels_id[channel_rules_name]).members unless channel_found.nil?
105
+ if channel_found.nil?
106
+ @logger.fatal "Not possible to find the channel #{channel_rules_name}"
107
+ elsif channel_found.name == MASTER_CHANNEL
108
+ respond "You cannot use the rules from Master Channel on any other channel.", dest
109
+ elsif @status != :on
110
+ respond "The bot in that channel is not :on", dest
111
+ elsif data.user == channel_found.creator or members.include?(data.user)
112
+ res = process_first(user_info.user, command, dest, channel_rules, typem, data.files)
113
+ else
114
+ respond "You need to join the channel <##{channel_found.id}> to be able to use the rules.", dest
115
+ end
116
+ elsif ON_MASTER_BOT and typem == :on_extended and
117
+ command.size > 0 and command[0] != "-"
118
+ # to run ruby only from the master bot for the case more than one extended
119
+ res = process_first(user_info.user, command, dest, @channel_id, typem, data.files)
120
+ elsif !ON_MASTER_BOT and @bots_created[@channel_id].key?(:extended) and
121
+ @bots_created[@channel_id][:extended].include?(@channels_name[data.channel]) and
122
+ command.size > 0 and command[0] != "-"
123
+ res = process_first(user_info.user, command, dest, @channel_id, typem, data.files)
124
+ elsif (dest[0] == "D" or @channel_id == data.channel or data.user == config[:nick_id]) and
125
+ command.size > 0 and command[0] != "-"
126
+ res = process_first(user_info.user, command, dest, data.channel, typem, data.files)
127
+ # if @botname on #channel_rules: do something
128
+ end
129
+ rescue Exception => stack
130
+ @logger.fatal stack
131
+ end
132
+ else
133
+ if !ON_MASTER_BOT and (dest == @master_bot_id or dest[0] == "D") and
134
+ data.text.match?(/^\s*bot\s+status\s*$/i) and @admin_users_id.include?(data.user)
135
+ respond "ping from #{CHANNEL}", dest
136
+ end
137
+ end
138
+ end
139
+ end
@@ -0,0 +1,299 @@
1
+ class SlackSmartBot
2
+ def update_bots_file
3
+ file = File.open($0.gsub(".rb", "_bots.rb"), "w")
4
+ bots_created = @bots_created.dup
5
+ bots_created.each { |k, v| v[:thread] = "" }
6
+ file.write bots_created.inspect
7
+ file.close
8
+ end
9
+
10
+ def get_bots_created
11
+ if File.exist?($0.gsub(".rb", "_bots.rb"))
12
+ if !defined?(@datetime_bots_created) or @datetime_bots_created != File.mtime($0.gsub(".rb", "_bots.rb"))
13
+ file_conf = IO.readlines($0.gsub(".rb", "_bots.rb")).join
14
+ if file_conf.to_s() == ""
15
+ @bots_created = {}
16
+ else
17
+ @bots_created = eval(file_conf)
18
+ end
19
+ @datetime_bots_created = File.mtime($0.gsub(".rb", "_bots.rb"))
20
+ @bots_created.each do |k, v| # to be compatible with old versions
21
+ v[:extended] = [] unless v.key?(:extended)
22
+ end
23
+ end
24
+ end
25
+ end
26
+
27
+ def update_shortcuts_file
28
+ file = File.open("./shortcuts/#{SHORTCUTS_FILE}", "w")
29
+ file.write @shortcuts.inspect
30
+ file.close
31
+ end
32
+
33
+ def update_rules_imported
34
+ file = File.open("./rules/rules_imported.rb", "w")
35
+ file.write @rules_imported.inspect
36
+ file.close
37
+ end
38
+
39
+ def get_channels_name_and_id
40
+ #todo: add pagination for case more than 1000 channels on the workspace
41
+ channels = client.web_client.conversations_list(
42
+ types: "private_channel,public_channel",
43
+ limit: "1000",
44
+ exclude_archived: "true",
45
+ ).channels
46
+
47
+ @channels_id = Hash.new()
48
+ @channels_name = Hash.new()
49
+ channels.each do |ch|
50
+ unless ch.is_archived
51
+ @channels_id[ch.name] = ch.id
52
+ @channels_name[ch.id] = ch.name
53
+ end
54
+ end
55
+ end
56
+
57
+ def get_routines(channel = @channel_id)
58
+ if File.exist?("./routines/routines_#{channel}.rb")
59
+ file_conf = IO.readlines("./routines/routines_#{channel}.rb").join
60
+ unless file_conf.to_s() == ""
61
+ @routines = eval(file_conf)
62
+ end
63
+ end
64
+ end
65
+
66
+ def update_routines(channel = @channel_id)
67
+ file = File.open("./routines/routines_#{channel}.rb", "w")
68
+ file.write (@routines.inspect)
69
+ file.close
70
+ end
71
+
72
+ def create_routine_thread(name)
73
+ t = Thread.new do
74
+ while @routines.key?(@channel_id) and @routines[@channel_id].key?(name)
75
+ started = Time.now
76
+ if @status == :on and @routines[@channel_id][name][:status] == :on
77
+ if @routines[@channel_id][name][:file_path].match?(/\.rb$/i)
78
+ ruby = "ruby "
79
+ else
80
+ ruby = ""
81
+ end
82
+ if @routines[@channel_id][name][:at] == "" or
83
+ (@routines[@channel_id][name][:at] != "" and @routines[@channel_id][name][:running] and
84
+ @routines[@channel_id][name][:next_run] != "" and Time.now.to_s >= @routines[@channel_id][name][:next_run])
85
+ if @routines[@channel_id][name][:file_path] != ""
86
+ process_to_run = "#{ruby}#{Dir.pwd}#{@routines[@channel_id][name][:file_path][1..-1]}"
87
+ process_to_run = ("cd #{project_folder} &&" + process_to_run) if defined?(project_folder)
88
+
89
+ stdout, stderr, status = Open3.capture3(process_to_run)
90
+ if stderr == ""
91
+ unless stdout.match?(/\A\s*\z/)
92
+ respond "routine *`#{name}`*: #{stdout}", @routines[@channel_id][name][:dest]
93
+ end
94
+ else
95
+ respond "routine *`#{name}`*: #{stdout} #{stderr}", @routines[@channel_id][name][:dest]
96
+ end
97
+ else #command
98
+ respond "routine *`#{name}`*: #{@routines[@channel_id][name][:command]}", @routines[@channel_id][name][:dest]
99
+ started = Time.now
100
+ treat_message({ channel: @routines[@channel_id][name][:dest],
101
+ user: @routines[@channel_id][name][:creator_id],
102
+ text: @routines[@channel_id][name][:command],
103
+ files: nil })
104
+ end
105
+ # in case the routine was deleted while running the process
106
+ if !@routines.key?(@channel_id) or !@routines[@channel_id].key?(name)
107
+ Thread.exit
108
+ end
109
+ @routines[@channel_id][name][:last_run] = started.to_s
110
+ end
111
+ if @routines[@channel_id][name][:last_run] == "" and @routines[@channel_id][name][:next_run] != "" #for the first create_routine of one routine with at
112
+ elapsed = 0
113
+ require "time"
114
+ every_in_seconds = Time.parse(@routines[@channel_id][name][:next_run]) - Time.now
115
+ elsif @routines[@channel_id][name][:next_run] == "" and @routines[@channel_id][name][:at] != "" #coming from start after pause for 'at'
116
+ if started.strftime("%k:%M:%S") < @routines[@channel_id][name][:at]
117
+ nt = @routines[@channel_id][name][:at].split(":")
118
+ next_run = Time.new(started.year, started.month, started.day, nt[0], nt[1], nt[2])
119
+ else
120
+ next_run = started + (24 * 60 * 60) # one more day
121
+ nt = @routines[@channel_id][name][:at].split(":")
122
+ next_run = Time.new(next_run.year, next_run.month, next_run.day, nt[0], nt[1], nt[2])
123
+ end
124
+ @routines[@channel_id][name][:next_run] = next_run.to_s
125
+ elapsed = 0
126
+ every_in_seconds = next_run - started
127
+ else
128
+ every_in_seconds = @routines[@channel_id][name][:every_in_seconds]
129
+ elapsed = Time.now - started
130
+ @routines[@channel_id][name][:last_elapsed] = elapsed
131
+ @routines[@channel_id][name][:next_run] = (started + every_in_seconds).to_s
132
+ end
133
+ @routines[@channel_id][name][:running] = true
134
+ @routines[@channel_id][name][:sleeping] = every_in_seconds - elapsed
135
+ update_routines()
136
+ sleep(every_in_seconds - elapsed) unless elapsed > every_in_seconds
137
+ else
138
+ sleep 30
139
+ end
140
+ end
141
+ end
142
+ end
143
+
144
+ def build_help(path)
145
+ help_message = {}
146
+ Dir["#{path}/*"].each do |t|
147
+ if Dir.exist?(t)
148
+ help_message[t.scan(/\/(\w+)$/).join.to_sym] = build_help(t)
149
+ else
150
+ help_message[t.scan(/\/(\w+)\.rb$/).join.to_sym] = IO.readlines(t).join.scan(/#\s*help\s*\w*:(.*)/).join("\n")
151
+ end
152
+ end
153
+ return help_message
154
+ end
155
+
156
+ def remove_hash_keys(hash, key)
157
+ newh = Hash.new
158
+ hash.each do |k, v|
159
+ unless k == key
160
+ if v.is_a?(String)
161
+ newh[k] = v
162
+ else
163
+ newh[k] = remove_hash_keys(v, key)
164
+ end
165
+ end
166
+ end
167
+ return newh
168
+ end
169
+
170
+ def get_help(rules_file, dest, from, only_rules = false)
171
+ order = {
172
+ general: [:hi_bot, :bye_bot, :bot_help, :bot_status, :use_rules, :stop_using_rules],
173
+ on_bot: [:ruby_code, :add_shortcut, :delete_shortcut, :see_shortcuts],
174
+ on_bot_admin: [:extend_rules, :stop_using_rules_on, :start_bot, :pause_bot, :add_routine,
175
+ :see_routines, :start_routine, :pause_routine, :remove_routine, :run_routine],
176
+ }
177
+ # user_type: :admin, :user, :admin_master
178
+ if MASTER_USERS.include?(from)
179
+ user_type = :admin_master
180
+ elsif ADMIN_USERS.include?(from)
181
+ user_type = :admin
182
+ else
183
+ user_type = :user
184
+ end
185
+ # channel_type: :bot, :master_bot, :direct, :extended, :external
186
+ if dest[0] == "D"
187
+ channel_type = :direct
188
+ elsif ON_MASTER_BOT
189
+ channel_type = :master_bot
190
+ elsif @channel_id != dest
191
+ channel_type = :extended
192
+ else
193
+ channel_type = :bot
194
+ end
195
+
196
+ @help_messages ||= build_help("#{__dir__}/commands")
197
+ if only_rules
198
+ help = {}
199
+ else
200
+ help = @help_messages.deep_copy
201
+ end
202
+ if rules_file != ""
203
+ help[:rules_file] = IO.readlines(rules_file).join.scan(/#\s*help\s*\w*:(.*)/i).join("\n")
204
+ end
205
+
206
+ help = remove_hash_keys(help, :admin_master) unless user_type == :admin_master
207
+ help = remove_hash_keys(help, :admin) unless user_type == :admin or user_type == :admin_master
208
+ help = remove_hash_keys(help, :on_master) unless channel_type == :master_bot
209
+ help = remove_hash_keys(help, :on_extended) unless channel_type == :extended
210
+ help = remove_hash_keys(help, :on_dm) unless channel_type == :direct
211
+ txt = ""
212
+ if channel_type == :bot or channel_type == :master_bot
213
+ txt += "===================================
214
+ For the Smart Bot start listening to you say *hi bot*
215
+ To run a command on demand even when the Smart Bot is not listening to you:
216
+ *!THE_COMMAND*
217
+ *@NAME_OF_BOT THE_COMMAND*
218
+ *NAME_OF_BOT THE_COMMAND*\n"
219
+ end
220
+ if channel_type == :direct
221
+ txt += "===================================
222
+ When on a private conversation with the Smart Bot, I'm always listening to you.\n"
223
+ end
224
+ unless channel_type == :master_bot or channel_type == :extended
225
+ txt += "===================================
226
+ *Commands from Channels without a bot:*
227
+ ----------------------------------------------
228
+ `@BOT_NAME on #CHANNEL_NAME COMMAND`
229
+ `@BOT_NAME #CHANNEL_NAME COMMAND`
230
+ It will run the supplied command using the rules on the channel supplied.
231
+ You need to join the specified channel to be able to use those rules.
232
+ Also you can use this command to call another bot from a channel with a running bot.
233
+
234
+ The commands you will be able to use from a channel without a bot:
235
+ *bot rules*, *ruby CODE*, *add shortcut NAME: COMMAND*, *delete shortcut NAME*, *see shortcuts*, *shortcut NAME*
236
+ *And all the specific rules of the Channel*\n"
237
+ end
238
+
239
+ if help.key?(:general)
240
+ unless channel_type == :direct
241
+ txt += "===================================
242
+ *General commands even when the Smart Bot is not listening to you:*\n"
243
+ end
244
+ order.general.each do |o|
245
+ txt += help.general[o]
246
+ end
247
+ if channel_type == :master_bot
248
+ txt += help.on_master.create_bot
249
+ end
250
+ end
251
+
252
+ if help.key?(:on_bot)
253
+ unless channel_type == :direct
254
+ txt += "===================================
255
+ *General commands only when the Smart Bot is listening to you or on demand:*\n"
256
+ end
257
+ order.on_bot.each do |o|
258
+ txt += help.on_bot[o]
259
+ end
260
+ end
261
+
262
+ if help.key?(:on_bot) and help.on_bot.key?(:admin)
263
+ txt += "===================================
264
+ *Admin commands:*\n"
265
+ txt += "\n\n"
266
+ order.on_bot_admin.each do |o|
267
+ txt += help.on_bot.admin[o]
268
+ end
269
+ if help.key?(:on_master) and help.on_master.key?(:admin)
270
+ help.on_master.admin.each do |k, v|
271
+ txt += v if v.is_a?(String)
272
+ end
273
+ end
274
+ end
275
+
276
+ if help.key?(:on_master) and help.on_master.key?(:admin_master)
277
+ txt += "===================================
278
+ *Master Admin commands:*\n"
279
+ help.on_master.admin_master.each do |k, v|
280
+ txt += v if v.is_a?(String)
281
+ end
282
+ end
283
+
284
+ if help.key?(:on_bot) and help.on_bot.key?(:admin_master) and help.on_bot.admin_master.size > 0
285
+ txt += "===================================
286
+ *Master Admin commands:*\n"
287
+ end
288
+
289
+ if help.key?(:rules_file)
290
+ @logger.info channel_type
291
+ if channel_type == :extended or channel_type == :direct
292
+ @logger.info help.rules_file
293
+ help.rules_file = help.rules_file.gsub(/^\s*\*These are specific commands.+NAME_OF_BOT THE_COMMAND`\s*$/im, "")
294
+ end
295
+ txt += help.rules_file
296
+ end
297
+ return txt
298
+ end
299
+ end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: slack-smart-bot
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.9.6
4
+ version: 1.0.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Mario Ruiz
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2019-09-04 00:00:00.000000000 Z
11
+ date: 2019-10-21 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: slack-ruby-client
@@ -39,7 +39,7 @@ dependencies:
39
39
  version: '1.7'
40
40
  - - ">="
41
41
  - !ruby/object:Gem::Version
42
- version: 1.7.19
42
+ version: 1.7.21
43
43
  type: :runtime
44
44
  prerelease: false
45
45
  version_requirements: !ruby/object:Gem::Requirement
@@ -49,7 +49,21 @@ dependencies:
49
49
  version: '1.7'
50
50
  - - ">="
51
51
  - !ruby/object:Gem::Version
52
- version: 1.7.19
52
+ version: 1.7.21
53
+ - !ruby/object:Gem::Dependency
54
+ name: nice_hash
55
+ requirement: !ruby/object:Gem::Requirement
56
+ requirements:
57
+ - - "~>"
58
+ - !ruby/object:Gem::Version
59
+ version: '1'
60
+ type: :runtime
61
+ prerelease: false
62
+ version_requirements: !ruby/object:Gem::Requirement
63
+ requirements:
64
+ - - "~>"
65
+ - !ruby/object:Gem::Version
66
+ version: '1'
53
67
  - !ruby/object:Gem::Dependency
54
68
  name: async-websocket
55
69
  requirement: !ruby/object:Gem::Requirement
@@ -64,6 +78,26 @@ dependencies:
64
78
  - - "~>"
65
79
  - !ruby/object:Gem::Version
66
80
  version: 0.8.0
81
+ - !ruby/object:Gem::Dependency
82
+ name: rspec
83
+ requirement: !ruby/object:Gem::Requirement
84
+ requirements:
85
+ - - "~>"
86
+ - !ruby/object:Gem::Version
87
+ version: '3.8'
88
+ - - ">="
89
+ - !ruby/object:Gem::Version
90
+ version: 3.8.0
91
+ type: :development
92
+ prerelease: false
93
+ version_requirements: !ruby/object:Gem::Requirement
94
+ requirements:
95
+ - - "~>"
96
+ - !ruby/object:Gem::Version
97
+ version: '3.8'
98
+ - - ">="
99
+ - !ruby/object:Gem::Version
100
+ version: 3.8.0
67
101
  description: "Create a Slack bot that is smart and so easy to expand, create new bots
68
102
  on demand, run ruby code on chat, create shortcuts... \n The main scope of this
69
103
  gem is to be used internally in the company so teams can create team channels with
@@ -84,6 +118,37 @@ files:
84
118
  - README.md
85
119
  - lib/slack-smart-bot.rb
86
120
  - lib/slack-smart-bot_rules.rb
121
+ - lib/slack/smart-bot/comm.rb
122
+ - lib/slack/smart-bot/commands/general/bot_help.rb
123
+ - lib/slack/smart-bot/commands/general/bot_status.rb
124
+ - lib/slack/smart-bot/commands/general/bye_bot.rb
125
+ - lib/slack/smart-bot/commands/general/hi_bot.rb
126
+ - lib/slack/smart-bot/commands/general/stop_using_rules.rb
127
+ - lib/slack/smart-bot/commands/general/use_rules.rb
128
+ - lib/slack/smart-bot/commands/on_bot/add_shortcut.rb
129
+ - lib/slack/smart-bot/commands/on_bot/admin/add_routine.rb
130
+ - lib/slack/smart-bot/commands/on_bot/admin/extend_rules.rb
131
+ - lib/slack/smart-bot/commands/on_bot/admin/pause_bot.rb
132
+ - lib/slack/smart-bot/commands/on_bot/admin/pause_routine.rb
133
+ - lib/slack/smart-bot/commands/on_bot/admin/remove_routine.rb
134
+ - lib/slack/smart-bot/commands/on_bot/admin/run_routine.rb
135
+ - lib/slack/smart-bot/commands/on_bot/admin/see_routines.rb
136
+ - lib/slack/smart-bot/commands/on_bot/admin/start_bot.rb
137
+ - lib/slack/smart-bot/commands/on_bot/admin/start_routine.rb
138
+ - lib/slack/smart-bot/commands/on_bot/admin/stop_using_rules_on.rb
139
+ - lib/slack/smart-bot/commands/on_bot/delete_shortcut.rb
140
+ - lib/slack/smart-bot/commands/on_bot/ruby_code.rb
141
+ - lib/slack/smart-bot/commands/on_bot/see_shortcuts.rb
142
+ - lib/slack/smart-bot/commands/on_extended/bot_rules.rb
143
+ - lib/slack/smart-bot/commands/on_master/admin/kill_bot_on_channel.rb
144
+ - lib/slack/smart-bot/commands/on_master/admin_master/exit_bot.rb
145
+ - lib/slack/smart-bot/commands/on_master/admin_master/notify_message.rb
146
+ - lib/slack/smart-bot/commands/on_master/create_bot.rb
147
+ - lib/slack/smart-bot/listen.rb
148
+ - lib/slack/smart-bot/process.rb
149
+ - lib/slack/smart-bot/process_first.rb
150
+ - lib/slack/smart-bot/treat_message.rb
151
+ - lib/slack/smart-bot/utils.rb
87
152
  homepage: https://github.com/MarioRuiz/slack-smart-bot
88
153
  licenses:
89
154
  - MIT
@@ -103,7 +168,8 @@ required_rubygems_version: !ruby/object:Gem::Requirement
103
168
  - !ruby/object:Gem::Version
104
169
  version: '0'
105
170
  requirements: []
106
- rubygems_version: 3.0.3
171
+ rubyforge_project:
172
+ rubygems_version: 2.7.6
107
173
  signing_key:
108
174
  specification_version: 4
109
175
  summary: Create a Slack bot that is smart and so easy to expand, create new bots on