slack-smart-bot 1.15.1 → 1.15.25
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/README.md +34 -1
- data/img/chat_gpt_attach_image.png +0 -0
- data/lib/slack/smart-bot/ai/open_ai/models.rb +19 -10
- data/lib/slack/smart-bot/ai/open_ai/send_gpt_chat.rb +14 -10
- data/lib/slack/smart-bot/comm/dont_understand.rb +23 -6
- data/lib/slack/smart-bot/comm/get_user_info.rb +9 -10
- data/lib/slack/smart-bot/comm/respond.rb +56 -28
- data/lib/slack/smart-bot/comm/send_file.rb +17 -6
- data/lib/slack/smart-bot/commands/general/ai/open_ai/open_ai_chat.rb +885 -129
- data/lib/slack/smart-bot/commands/general/ai/open_ai/open_ai_chat_add_collaborator.rb +3 -3
- data/lib/slack/smart-bot/commands/general/ai/open_ai/open_ai_chat_copy_session.rb +132 -15
- data/lib/slack/smart-bot/commands/general/ai/open_ai/open_ai_chat_delete_session.rb +1 -1
- data/lib/slack/smart-bot/commands/general/ai/open_ai/open_ai_chat_get_prompts.rb +50 -12
- data/lib/slack/smart-bot/commands/general/ai/open_ai/open_ai_chat_list_sessions.rb +99 -34
- data/lib/slack/smart-bot/commands/general/ai/open_ai/open_ai_chat_share_session.rb +12 -2
- data/lib/slack/smart-bot/commands/general/ai/open_ai/open_ai_chat_use_model.rb +36 -25
- data/lib/slack/smart-bot/commands/general/bot_help.rb +29 -24
- data/lib/slack/smart-bot/commands/general/poster.rb +0 -1
- data/lib/slack/smart-bot/commands/general/see_announcements.rb +1 -1
- data/lib/slack/smart-bot/commands/general/summarize.rb +22 -8
- data/lib/slack/smart-bot/commands/general_bot_commands.rb +156 -55
- data/lib/slack/smart-bot/commands/on_bot/general/bot_stats.rb +13 -11
- data/lib/slack/smart-bot/commands/on_extended/bot_rules.rb +21 -17
- data/lib/slack/smart-bot/commands/on_master/admin_master/exit_bot.rb +2 -2
- data/lib/slack/smart-bot/commands.rb +19 -19
- data/lib/slack/smart-bot/process_first.rb +38 -35
- data/lib/slack/smart-bot/treat_message.rb +57 -56
- data/lib/slack/smart-bot/utils/download_http_content.rb +91 -0
- data/lib/slack/smart-bot/utils/get_authorizations.rb +41 -0
- data/lib/slack/smart-bot/utils/get_keywords.rb +33 -0
- data/lib/slack/smart-bot/utils/get_openai_sessions.rb +46 -6
- data/lib/slack/smart-bot/utils/get_teams.rb +9 -1
- data/lib/slack/smart-bot/utils/save_stats.rb +13 -5
- data/lib/slack/smart-bot/utils/transform_to_slack_markdown.rb +36 -0
- data/lib/slack/smart-bot/utils/update_openai_sessions.rb +9 -4
- data/lib/slack/smart-bot/utils.rb +48 -44
- data/lib/slack-smart-bot.rb +10 -9
- data/whats_new.txt +27 -1
- metadata +63 -2
@@ -1,11 +1,11 @@
|
|
1
1
|
class SlackSmartBot
|
2
|
-
def bot_rules(dest, help_command, typem, rules_file, user, send_to_file: false)
|
3
|
-
save_stats(__method__)
|
2
|
+
def bot_rules(dest, help_command, typem, rules_file, user, send_to_file: false, savestats: true, return_output: false)
|
3
|
+
save_stats(__method__) if savestats
|
4
4
|
if has_access?(__method__, user)
|
5
5
|
if typem == :on_extended or typem == :on_call #for the other cases above.
|
6
6
|
output = []
|
7
|
-
if help_command.to_s !=
|
8
|
-
help_command =
|
7
|
+
if help_command.to_s != ""
|
8
|
+
help_command = "" if help_command.to_s.match?(/^\s*expanded\s*$/i) or help_command.to_s.match?(/^\s*extended\s*$/i)
|
9
9
|
expanded = true
|
10
10
|
else
|
11
11
|
expanded = false
|
@@ -25,7 +25,7 @@ class SlackSmartBot
|
|
25
25
|
commands << h
|
26
26
|
elsif !h.match?(/\A\s*\*/) and !h.match?(/\A\s*=+/) #to avoid general messages for bot help *General rules...*
|
27
27
|
all_found = true
|
28
|
-
help_command.to_s.split(
|
28
|
+
help_command.to_s.split(" ") do |hc|
|
29
29
|
unless hc.match?(/^\s*\z/)
|
30
30
|
if !h.match?(/#{hc}/i)
|
31
31
|
all_found = false
|
@@ -35,9 +35,9 @@ class SlackSmartBot
|
|
35
35
|
commands_search << h if all_found
|
36
36
|
end
|
37
37
|
end
|
38
|
-
if commands.size < 10 and help_command.to_s!=
|
38
|
+
if commands.size < 10 and help_command.to_s != "" and commands_search.size > 0
|
39
39
|
commands_search.shuffle!
|
40
|
-
(10-commands.size).times do |n|
|
40
|
+
(10 - commands.size).times do |n|
|
41
41
|
unless commands_search[n].nil?
|
42
42
|
output << commands_search[n]
|
43
43
|
help_found = true
|
@@ -47,7 +47,6 @@ class SlackSmartBot
|
|
47
47
|
unless help_found
|
48
48
|
output << "*#{config.channel}*: I didn't find any command with `#{help_command}`"
|
49
49
|
end
|
50
|
-
|
51
50
|
else
|
52
51
|
message = "-\n\n\n===================================\n*Rules from channel #{config.channel}*\n"
|
53
52
|
if typem == :on_extended
|
@@ -59,7 +58,7 @@ class SlackSmartBot
|
|
59
58
|
|
60
59
|
unless rules_file.empty?
|
61
60
|
begin
|
62
|
-
eval(File.new(config.path+rules_file).read) if File.exist?(config.path+rules_file)
|
61
|
+
eval(File.new(config.path + rules_file).read) if File.exist?(config.path + rules_file)
|
63
62
|
end
|
64
63
|
end
|
65
64
|
if defined?(git_project) and git_project.to_s != "" and help_command.to_s == ""
|
@@ -73,28 +72,33 @@ class SlackSmartBot
|
|
73
72
|
message_not_expanded += "Also to get specific *expanded* help for a specific command or rule call *`bot rules COMMAND`*\n"
|
74
73
|
output << message_not_expanded
|
75
74
|
end
|
76
|
-
if output.join("\n").lines.count > 50 and dest[0]!=
|
75
|
+
if output.join("\n").lines.count > 50 and dest[0] != "D"
|
77
76
|
dest = :on_thread
|
78
|
-
output.unshift(
|
77
|
+
output.unshift("Since there are many lines returned the results are returned on a thread by default.")
|
79
78
|
end
|
80
79
|
if send_to_file
|
81
80
|
content = output.join("\n\n")
|
82
81
|
content.gsub!(/\*<([^>]*)\|([^>]*)>\*/, '## [\2](\1)')
|
83
82
|
content.gsub!(/^\s*(\*.+\*)\s*$/, '# \1')
|
84
|
-
content.gsub!(/command_id:\s+:/,
|
85
|
-
content = content.gsub("\n", " \n").gsub(/\|[\w\s]*>/i,">").gsub(/^\s*\-\-\-\-\-\-/, "\n------")
|
83
|
+
content.gsub!(/command_id:\s+:/, "### :")
|
84
|
+
content = content.gsub("\n", " \n").gsub(/\|[\w\s]*>/i, ">").gsub(/^\s*\-\-\-\-\-\-/, "\n------")
|
86
85
|
dest == :on_thread ? dest_file = dchannel : dest_file = dest
|
87
|
-
send_file(dest_file, "SmartBot Rules", "",
|
86
|
+
send_file(dest_file, "SmartBot Rules", "", "smartbot_rules.md", "text/markdown", "markdown", content: content)
|
87
|
+
elsif return_output
|
88
|
+
output.each do |h|
|
89
|
+
h.gsub!(/^\s*command_id:\s+:\w+\s*$/, "")
|
90
|
+
h.gsub!(/^\s*>.+$/, "") if help_command.to_s != ""
|
91
|
+
end
|
92
|
+
return output
|
88
93
|
else
|
89
94
|
output.each do |h|
|
90
|
-
msg = h.gsub(/^\s*command_id:\s+:\w+\s*$/,
|
91
|
-
msg.gsub!(/^\s*>.+$/,
|
95
|
+
msg = h.gsub(/^\s*command_id:\s+:\w+\s*$/, "")
|
96
|
+
msg.gsub!(/^\s*>.+$/, "") if help_command.to_s != ""
|
92
97
|
unless msg.match?(/\A\s*\z/)
|
93
98
|
respond msg, dest, unfurl_links: false, unfurl_media: false
|
94
99
|
end
|
95
100
|
end
|
96
101
|
end
|
97
|
-
|
98
102
|
end
|
99
103
|
end
|
100
104
|
end
|
@@ -37,7 +37,7 @@ class SlackSmartBot
|
|
37
37
|
respond "Game over!", dest
|
38
38
|
@listening[:threads].each do |thread_ts, channel_thread|
|
39
39
|
unreact :running, thread_ts, channel: channel_thread
|
40
|
-
respond "ChatGPT session closed since SmartBot is going to be closed", channel_thread, thread_ts: thread_ts
|
40
|
+
respond "ChatGPT session closed since SmartBot is going to be closed.\nCheck <##{@channels_id[config.status_channel]}>", channel_thread, thread_ts: thread_ts
|
41
41
|
end
|
42
42
|
if config.simulate
|
43
43
|
sleep 2
|
@@ -45,7 +45,7 @@ class SlackSmartBot
|
|
45
45
|
config.simulate = false
|
46
46
|
Thread.exit
|
47
47
|
else
|
48
|
-
respond
|
48
|
+
respond "Ok, It will take around 40s to close all the bots, all routines and the master bot."
|
49
49
|
sleep 35
|
50
50
|
respond "Ciao #{display_name}!", dest
|
51
51
|
unreact :runner
|
@@ -79,25 +79,25 @@ require_relative "commands/general/set_public_holidays"
|
|
79
79
|
require_relative "commands/general/personal_settings"
|
80
80
|
require_relative "commands/general/teams/memos/add_memo_team_comment"
|
81
81
|
require_relative "commands/general/teams/memos/see_memo_team"
|
82
|
-
require_relative
|
83
|
-
require_relative
|
84
|
-
require_relative
|
85
|
-
require_relative
|
86
|
-
require_relative
|
87
|
-
require_relative
|
88
|
-
require_relative
|
89
|
-
require_relative
|
90
|
-
require_relative
|
91
|
-
require_relative
|
92
|
-
require_relative
|
93
|
-
require_relative
|
94
|
-
require_relative
|
95
|
-
require_relative
|
96
|
-
require_relative
|
97
|
-
require_relative
|
82
|
+
require_relative "commands/general/ai/open_ai/open_ai_chat"
|
83
|
+
require_relative "commands/general/ai/open_ai/open_ai_chat_get_prompts"
|
84
|
+
require_relative "commands/general/ai/open_ai/open_ai_chat_delete_session"
|
85
|
+
require_relative "commands/general/ai/open_ai/open_ai_chat_share_session"
|
86
|
+
require_relative "commands/general/ai/open_ai/open_ai_chat_list_sessions"
|
87
|
+
require_relative "commands/general/ai/open_ai/open_ai_chat_add_collaborator"
|
88
|
+
require_relative "commands/general/ai/open_ai/open_ai_chat_use_model"
|
89
|
+
require_relative "commands/general/ai/open_ai/open_ai_chat_copy_session"
|
90
|
+
require_relative "commands/general/ai/open_ai/open_ai_generate_image"
|
91
|
+
require_relative "commands/general/ai/open_ai/open_ai_variations_image"
|
92
|
+
require_relative "commands/general/ai/open_ai/open_ai_edit_image"
|
93
|
+
require_relative "commands/general/ai/open_ai/open_ai_models"
|
94
|
+
require_relative "commands/general/ai/open_ai/open_ai_whisper"
|
95
|
+
require_relative "commands/general/recap"
|
96
|
+
require_relative "commands/general/summarize"
|
97
|
+
require_relative "commands/general/get_smartbot_readme"
|
98
98
|
|
99
99
|
class SlackSmartBot
|
100
|
-
|
101
|
-
|
102
|
-
|
100
|
+
include SlackSmartBot::Commands::General::AI::OpenAI
|
101
|
+
include SlackSmartBot::Commands::General::Teams
|
102
|
+
include SlackSmartBot::Commands::General::Teams::Memos
|
103
103
|
end
|
@@ -7,12 +7,12 @@ class SlackSmartBot
|
|
7
7
|
Thread.current[:user] = user
|
8
8
|
Thread.current[:team_id_user] = team_id_user
|
9
9
|
if text.match(/\A\s*(stop|quit|exit|kill)\s+(iterator|iteration|loop)\s+(\d+)\s*\z/i)
|
10
|
-
save_stats :quit_loop, forced: true, data: {dest: dest, typem: typem, user: user, files: false, command: text, routine: routine}
|
10
|
+
save_stats :quit_loop, forced: true, data: { dest: dest, typem: typem, user: user, files: false, command: text, routine: routine }
|
11
11
|
num_iteration = $3.to_i
|
12
12
|
if config.team_id_admins.include?(team_id_user) or @loops.key?(team_id_user)
|
13
13
|
if config.team_id_admins.include?(team_id_user)
|
14
|
-
name_loop =
|
15
|
-
@loops.each do |k,v|
|
14
|
+
name_loop = ""
|
15
|
+
@loops.each do |k, v|
|
16
16
|
if v.include?(num_iteration)
|
17
17
|
name_loop = k
|
18
18
|
break
|
@@ -37,20 +37,20 @@ class SlackSmartBot
|
|
37
37
|
text.gsub!(encdata, "********")
|
38
38
|
end
|
39
39
|
text = "********" if !found
|
40
|
-
text+= " (encrypted #{Thread.current[:command_id]})"
|
40
|
+
text += " (encrypted #{Thread.current[:command_id]})"
|
41
41
|
end
|
42
42
|
@logger.info "command: #{user.team_id}/#{nick}> #{text}"
|
43
43
|
return :next #jal
|
44
44
|
end
|
45
45
|
if text.match(/\A\s*!*^?\s*(for\s*)?(\d+)\s+times\s+every\s+(\d+)\s*(m|minute|minutes|s|sc|second|seconds)\s+(.+)\s*\z/i)
|
46
|
-
save_stats :create_loop, forced: true, data: {dest: dest, typem: typem, user: user, files: false, command: text, routine: routine}
|
46
|
+
save_stats :create_loop, forced: true, data: { dest: dest, typem: typem, user: user, files: false, command: text, routine: routine }
|
47
47
|
# min every 10s, max every 60m, max times 24
|
48
48
|
command_every = text.dup
|
49
49
|
text = $5
|
50
50
|
num_times = $2.to_i
|
51
51
|
type_every = $4.downcase
|
52
52
|
every_seconds = $3.to_i
|
53
|
-
command_every.gsub!(/^\s*!*^?\s*/,
|
53
|
+
command_every.gsub!(/^\s*!*^?\s*/, "")
|
54
54
|
every_seconds = (every_seconds * 60) if type_every[0] == "m"
|
55
55
|
if num_times > 24 or every_seconds < 10 or every_seconds > 3600
|
56
56
|
respond "You can't do that. Maximum times is 24, minimum every is 10 seconds, maximum every is 60 minutes.", dest, thread_ts: thread_ts
|
@@ -61,10 +61,10 @@ class SlackSmartBot
|
|
61
61
|
@num_loops += 1
|
62
62
|
loop_id = @num_loops
|
63
63
|
@loops[team_id_user] << loop_id
|
64
|
-
respond "Loop #{loop_id} started. To stop the loop use: `#{[
|
64
|
+
respond "Loop #{loop_id} started. To stop the loop use: `#{["stop", "quit", "exit", "kill"].sample} #{["iteration", "iterator", "loop"].sample} #{loop_id}`", dest, thread_ts: thread_ts
|
65
65
|
#todo: command_orig should be reasigned maybe to remove for N times every X seconds. Check.
|
66
66
|
else
|
67
|
-
command_every =
|
67
|
+
command_every = ""
|
68
68
|
num_times = 1
|
69
69
|
every_seconds = 0
|
70
70
|
end
|
@@ -119,6 +119,10 @@ class SlackSmartBot
|
|
119
119
|
when /^Bot has been (closed|killed) by/i
|
120
120
|
if config.channel == @channels_name[dchannel]
|
121
121
|
@logger.info "#{nick}: #{text}"
|
122
|
+
@listening[:threads].each do |thread_ts, channel_thread|
|
123
|
+
unreact :running, thread_ts, channel: channel_thread
|
124
|
+
respond "ChatGPT session closed since SmartBot is going to be closed.\nCheck <##{@channels_id[config.status_channel]}>", channel_thread, thread_ts: thread_ts
|
125
|
+
end
|
122
126
|
if config.simulate
|
123
127
|
@status = :off
|
124
128
|
config.simulate = false
|
@@ -151,7 +155,7 @@ class SlackSmartBot
|
|
151
155
|
from_name = $1
|
152
156
|
to_name = $2
|
153
157
|
if config.on_master_bot and @bots_created.key?(@channels_id[from_name]) and
|
154
|
-
|
158
|
+
@bots_created[@channels_id[from_name]][:cloud]
|
155
159
|
@bots_created[@channels_id[from_name]][:extended].delete(to_name)
|
156
160
|
update_bots_file()
|
157
161
|
end
|
@@ -252,15 +256,15 @@ class SlackSmartBot
|
|
252
256
|
t = Thread.new do
|
253
257
|
begin
|
254
258
|
sleep every_seconds * i if every_seconds > 0
|
255
|
-
Thread.exit if command_every!=
|
256
|
-
@logger.info "i: #{i}, num_times: #{num_times}, every_seconds: #{every_seconds}, command: #{command_thread}" if command_every!=
|
259
|
+
Thread.exit if command_every != "" and @loops.key?(team_id_user) and !@loops[team_id_user].include?(loop_id)
|
260
|
+
@logger.info "i: #{i}, num_times: #{num_times}, every_seconds: #{every_seconds}, command: #{command_thread}" if command_every != ""
|
257
261
|
processed = false
|
258
262
|
processed_rules = false
|
259
263
|
|
260
264
|
if command_thread.match?(/\A.+\s+\?\?\s+.+\z/im) and !command_thread.match?(/\A\s*(add|create)\s+(silent\s+)?(bgroutine|routine)\s+([\w\.]+)/im)
|
261
265
|
pos = command_thread.index("??")
|
262
|
-
Thread.current[:prompt] = command_thread[pos+2..-1].strip
|
263
|
-
command_thread = command_thread[0..pos-1].strip
|
266
|
+
Thread.current[:prompt] = command_thread[pos + 2..-1].strip
|
267
|
+
command_thread = command_thread[0..pos - 1].strip
|
264
268
|
Thread.current[:stdout] = ""
|
265
269
|
else
|
266
270
|
Thread.current[:prompt] = ""
|
@@ -318,17 +322,16 @@ class SlackSmartBot
|
|
318
322
|
end
|
319
323
|
|
320
324
|
if !config.on_maintenance and @listening.key?(team_id_user) and @listening[team_id_user].key?(Thread.current[:thread_ts]) and !Thread.current[:thread_ts].empty? and
|
321
|
-
|
322
|
-
|
325
|
+
((@active_chat_gpt_sessions.key?(team_id_user) and @active_chat_gpt_sessions[team_id_user].key?(Thread.current[:thread_ts])) or
|
326
|
+
(@chat_gpt_collaborating.key?(team_id_user) and @chat_gpt_collaborating[team_id_user].key?(Thread.current[:thread_ts])))
|
323
327
|
@listening[team_id_user][Thread.current[:thread_ts]] = Time.now
|
324
328
|
command_thread = "? #{command_thread}" #chatgpt
|
325
329
|
end
|
326
330
|
|
327
|
-
|
328
331
|
unless config.on_maintenance or @status != :on
|
329
332
|
if typem == :on_pub or typem == :on_pg or typem == :on_extended
|
330
333
|
if command_thread.match(/\A(<)?\s*(#{@salutations.join("|")})\s+(rules|help)\s*(.+)?$/i) or command_thread.match(/\A(<)?\s*(#{@salutations.join("|")}),? what can I do/i)
|
331
|
-
$1.to_s==
|
334
|
+
$1.to_s == "" ? send_to_file = false : send_to_file = true
|
332
335
|
$3.to_s.match?(/rules/i) ? specific = true : specific = false
|
333
336
|
help_command = $4
|
334
337
|
react :runner
|
@@ -343,6 +346,7 @@ class SlackSmartBot
|
|
343
346
|
end
|
344
347
|
processed = (processed || general_bot_commands(user, command_thread, dest, files))
|
345
348
|
processed = (processed || general_commands(user, command_thread, dest, files)) if defined?(general_commands)
|
349
|
+
|
346
350
|
if processed
|
347
351
|
text_to_log = command_thread.dup
|
348
352
|
|
@@ -353,7 +357,7 @@ class SlackSmartBot
|
|
353
357
|
text_to_log.gsub!(encdata, "********")
|
354
358
|
end
|
355
359
|
text_to_log = "********" if !found
|
356
|
-
text_to_log+= " (encrypted #{Thread.current[:command_id]})"
|
360
|
+
text_to_log += " (encrypted #{Thread.current[:command_id]})"
|
357
361
|
end
|
358
362
|
@logger.info "command: #{user.team_id}/#{nick}> #{text_to_log}" unless user.id == config.nick_id_granular
|
359
363
|
end
|
@@ -369,19 +373,19 @@ class SlackSmartBot
|
|
369
373
|
((@listening[team_id_user].key?(dest) and !Thread.current[:on_thread]) or
|
370
374
|
(@listening[team_id_user].key?(thread_ts) and Thread.current[:on_thread]))) or
|
371
375
|
dest[0] == "D" or on_demand)
|
372
|
-
|
373
|
-
|
374
|
-
|
375
|
-
|
376
|
-
|
377
|
-
|
378
|
-
|
379
|
-
end
|
380
|
-
text_to_log = "********" if !found
|
381
|
-
text_to_log+= " (encrypted #{Thread.current[:command_id]})"
|
376
|
+
unless processed
|
377
|
+
text_to_log = command_thread.dup
|
378
|
+
found = false
|
379
|
+
if Thread.current.key?(:encrypted) and Thread.current[:encrypted].size > 0
|
380
|
+
Thread.current[:encrypted].each do |encdata|
|
381
|
+
found = true if !found and text_to_log.include?(encdata)
|
382
|
+
text_to_log.gsub!(encdata, "********")
|
382
383
|
end
|
383
|
-
|
384
|
+
text_to_log = "********" if !found
|
385
|
+
text_to_log += " (encrypted #{Thread.current[:command_id]})"
|
384
386
|
end
|
387
|
+
@logger.info "command: #{user.team_id}/#{nick}> #{text_to_log}" unless user.id == config.nick_id_granular
|
388
|
+
end
|
385
389
|
#todo: verify this
|
386
390
|
|
387
391
|
if dest[0] == "C" or dest[0] == "G" or (dest[0] == "D" and typem == :on_call)
|
@@ -493,10 +497,10 @@ class SlackSmartBot
|
|
493
497
|
end
|
494
498
|
end
|
495
499
|
|
496
|
-
if Thread.current[:prompt].to_s !=
|
500
|
+
if Thread.current[:prompt].to_s != ""
|
497
501
|
prompt = "#{Thread.current[:command]}\n\n#{Thread.current[:prompt]}\n\n#{Thread.current[:stdout]}\n\n"
|
498
|
-
Thread.current[:prompt] =
|
499
|
-
Thread.current[:stdout] =
|
502
|
+
Thread.current[:prompt] = ""
|
503
|
+
Thread.current[:stdout] = ""
|
500
504
|
if processed
|
501
505
|
if @active_chat_gpt_sessions.key?(team_id_user) and @active_chat_gpt_sessions[team_id_user].key?(Thread.current[:thread_ts])
|
502
506
|
open_ai_chat(prompt, false, :temporary)
|
@@ -508,9 +512,8 @@ class SlackSmartBot
|
|
508
512
|
if processed and config.general_message != "" and !routine
|
509
513
|
respond eval("\"" + config.general_message + "\"")
|
510
514
|
end
|
511
|
-
respond "_*Loop #{loop_id}* (#{i+1}/#{num_times}) <@#{user.name}>: #{command_every}_" if command_every!=
|
512
|
-
@loops[team_id_user].delete(loop_id) if command_every!=
|
513
|
-
|
515
|
+
respond "_*Loop #{loop_id}* (#{i + 1}/#{num_times}) <@#{user.name}>: #{command_every}_" if command_every != "" and processed
|
516
|
+
@loops[team_id_user].delete(loop_id) if command_every != "" and !processed and @loops.key?(team_id_user) and @loops[team_id_user].include?(loop_id)
|
514
517
|
rescue Exception => stack
|
515
518
|
@logger.fatal stack
|
516
519
|
end
|