lib/slack/smart-bot/treat_message.rb in slack-smart-bot-1.14.2 vs lib/slack/smart-bot/treat_message.rb in slack-smart-bot-1.15.0
- old
+ new
@@ -19,12 +19,12 @@
if el.type == 'text'
data_text += el.text
elsif el.type == 'user'
data_text += "<@#{el.user_id}>"
elsif el.type == 'channel'
- tch = data.text.scan(/(<##{el.channel_id}\|[^\>]*>)/).join
- data_text += tch
+ tch = data.text.scan(/(<##{el.channel_id}\|[^\>]*>)/).flatten.first
+ data_text += tch.to_s
else
data_text += el.url
end
end
data_text += '```' if e.type == 'rich_text_preformatted'
@@ -39,26 +39,26 @@
data.text = CGI.unescapeHTML(data.text)
data.text.gsub!("\u00A0", " ") #to change (asc char 160) into blank space
end
data.text.gsub!('‘', "'")
data.text.gsub!('’', "'")
- data.text.gsub!('“', '"')
+ data.text.gsub!('“', '"')
data.text.gsub!('”', '"')
rescue Exception => exc
@logger.warn "Impossible to unescape or clean format for data.text:#{data.text}"
@logger.warn exc.inspect
end
-
+
unless data.key?(:routine)
- data.routine = false
+ data.routine = false
data.routine_name = ''
data.routine_type = ''
end
if config[:testing] and config.on_master_bot and !@buffered
@buffered = true
open("#{config.path}/buffer.log", "a") { |f|
- f.puts "|#{data.channel}|#{data.user}|#{data.user_name}|#{data.text}"
+ f.puts "|#{data.channel}|#{data.thread_ts}|#{data.user}|#{data.user_name}|#{data.text}"
}
end
if data.key?(:dest) and data.dest.to_s!='' # for run routines and publish on different channels
dest = data.dest
elsif data.channel[0] == "D" or data.channel[0] == "C" or data.channel[0] == "G" #Direct message or Channel or Private Channel
@@ -78,42 +78,55 @@
if !att.text.nil? and att.text != ''
data.text += "\n#{att.text}"
end
end
end
-
if !dest.nil? and config.on_master_bot and !data.text.nil? and data.text.match(/^ping from (.+)\s*$/) and data.user == config[:nick_id]
@pings << $1
end
- if config.on_master_bot and @vacations_check != Date.today
- @vacations_check = Date.today
+ if config.on_master_bot and @vacations_check != Time.now.strftime("%Y%m%d%H") #every hour since depends on user's time zone
+ @vacations_check = Time.now.strftime("%Y%m%d%H")
t = Thread.new do
- check_vacations(only_first_day: true)
+ check_vacations(date: nil, only_first_day: true)
end
end
typem = :dont_treat
+
+ @users = get_users() if @users.empty?
+ if data.key?(:bot_id) and data.bot_id.to_s!=''
+ if @slack_bots.key?(data.bot_id) #bot or workflow
+ data.user = @slack_bots[data.bot_id]
+ else
+ bot_info = get_user_info(data.bot_id, is_bot: true)
+ unless bot_info.nil? or bot_info.empty?
+ @slack_bots[data.bot_id] = bot_info.user.id
+ data.user = bot_info.user.id
+ @users << bot_info.user unless bot_info.nil? or bot_info.empty?
+ end
+ end
+ end
if data.nil? or data.user.nil? or data.user.to_s==''
user_info = nil
- @users = get_users() if @users.empty?
else
- #todo: when changed @questions user_id then move user_info inside the ifs to avoid calling it when not necessary
- user_info = @users.select{|u| u.id == data.user or (u.key?(:enterprise_user) and u.enterprise_user.id == data.user)}[-1]
- if user_info.nil? or user_info.empty?
- @users = get_users()
- user_info = @users.select{|u| u.id == data.user or (u.key?(:enterprise_user) and u.enterprise_user.id == data.user)}[-1]
+ user_info = find_user(data.user, get_sso_user_name: true)
+ if user_info.nil?
+ @logger.warn "User not found on users with id #{data.user} and user_team #{data.user_team}"
+ elsif !user_info.key?(:team_id) or user_info.team_id.to_s.empty?
+ @logger.warn "User with id #{data.user} and user_team #{data.user_team} has no team_id. User_info: #{user_info.inspect}"
end
end
if !dest.nil? and !data.text.nil? and !data.text.to_s.match?(/\A\s*\z/)
+
get_bots_created()
- if data.channel[0] == "D" and !data.text.to_s.match?(/^\s*<@#{config[:nick_id]}>\s+/) and
+ if data.channel[0] == "D" and !data.text.to_s.match?(/^\s*<@#{config[:nick_id]}>\s+/) and
(data.text.to_s.match?(/^\s*(on)?\s*<#\w+\|[^>]*>/i) or data.text.to_s.match?(/^\s*(on)?\s*#\w+/i))
data.text = "<@#{config[:nick_id]}> " + data.text.to_s
end
#todo: we need to add mixed channels: @smart-bot on private1 #bot1cm <#CXDDFRDDF|bot2cu>: echo A
if data.text.match(/\A\^\^+/) # to open a thread it will be only when starting by single ^
typem = :dont_treat
- elsif data.text.match(/^\s*<@#{config[:nick_id]}>\s+(on\s+)?((<#\w+\|[^>]*>\s*)+)\s*:?\s*(.*)/im) or
+ elsif data.text.match(/^\s*<@#{config[:nick_id]}>\s+(on\s+)?((<#\w+\|[^>]*>\s*)+)\s*:?\s*(.*)/im) or
data.text.match(/^\s*<@#{config[:nick_id]}>\s+(on\s+)?((#[a-zA-Z0-9\-\_]+\s*)+)\s*:?\s*(.*)/im) or
data.text.match(/^\s*<@#{config[:nick_id]}>\s+(on\s+)?(([a-zA-Z0-9\-\_]+\s*)+)\s*:\s*(.*)/im)
channels_rules = $2 #multiple channels @smart-bot on #channel1 #channel2 echo AAA
data_text = $4
channel_rules_name = ''
@@ -130,14 +143,14 @@
end
end
else
channels_arr.each do |row|
row[0] = @channels_id[row[1]] if row[0] == ''
- row[1] = @channels_name[row[0]] if row[1] == ''
+ row[1] = @channels_name[row[0]] if row[1] == ''
end
end
-
+
# to be treated only on the bots of the requested channels
channels_arr.each do |tcid, tcname|
if @channel_id == tcid
data.text = data_text
typem = :on_call
@@ -161,13 +174,13 @@
if @channel_id == data.channel #only to be treated by the bot on the channel
typem = :on_bot
end
elsif data.channel[0] == "D" #Direct message
get_rules_imported()
- if @rules_imported.key?(user_info.name) && @rules_imported[user_info.name].key?(user_info.name) and
- @bots_created.key?(@rules_imported[user_info.name][user_info.name])
- if @channel_id == @rules_imported[user_info.name][user_info.name]
+ if @rules_imported.key?("#{user_info.team_id}_#{user_info.name}") && @rules_imported["#{user_info.team_id}_#{user_info.name}"].key?(user_info.name) and
+ @bots_created.key?(@rules_imported["#{user_info.team_id}_#{user_info.name}"][user_info.name])
+ if @channel_id == @rules_imported["#{user_info.team_id}_#{user_info.name}"][user_info.name]
#only to be treated by the channel we are 'using'
typem = :on_dm
end
elsif config.on_master_bot
#only to be treated by master bot
@@ -202,50 +215,65 @@
end
end
load "#{config.path}/rules/general_commands.rb" if File.exist?("#{config.path}/rules/general_commands.rb") and @datetime_general_commands != File.mtime("#{config.path}/rules/general_commands.rb")
eval(File.new(config.path + config.rules_file).read) if !defined?(rules) and File.exist?(config.path+config.rules_file) and !config.rules_file.empty?
unless typem == :dont_treat or user_info.nil?
- if (Time.now - @last_activity_check) > 60 * 30 #every 30 minutes
+ if (Time.now - @last_activity_check) > TIMEOUT_LISTENING #every 30 minutes
@last_activity_check = Time.now
@listening.each do |k,v|
- v.each do |kk, vv|
- @listening[k].delete(kk) if (Time.now - vv) > 60 * 30
+ unless k == :threads
+ v.each do |kk, vv|
+ if (Time.now - vv) > TIMEOUT_LISTENING
+ if @listening[:threads].key?(kk) && @active_chat_gpt_sessions.key?(k) &&
+ @active_chat_gpt_sessions[k].key?(kk)
+ unreact :running, kk, channel: @listening[:threads][kk]
+ session_name = @active_chat_gpt_sessions[k][kk]
+ chatgpt_message = "ChatGPT session has been terminated due to inactivity."
+ if !session_name.to_s.empty?
+ chatgpt_message += "\n\nIf you want to start it again on this thread call `chatgpt #{session_name}`"
+ end
+ respond chatgpt_message, @listening[:threads][kk], thread_ts: kk
+ @listening[:threads].delete(kk)
+ end
+ @listening[k].delete(kk)
+ end
+ end
+ @listening.delete(k) if @listening[k].empty?
end
- @listening.delete(k) if @listening[k].empty?
end
end
begin
#user_info.id = data.user #todo: remove this line when slack issue with Wxxxx Uxxxx fixed
data.user = user_info.id #todo: remove this line when slack issue with Wxxxx Uxxxx fixed
- if data.thread_ts.nil?
+ team_id_user = "#{user_info.team_id}_#{user_info.name}"
+ if data.thread_ts.to_s.empty?
qdest = dest
else
qdest = data.thread_ts
end
- if !answer(user_info.name, qdest).empty?
+ if !answer(user_info, qdest).empty?
if data.text.match?(/\A\s*(Bye|Bæ|Good\sBye|Adiós|Ciao|Bless|Bless\sBless|Adeu)\s(#{@salutations.join("|")})\s*$/i)
- answer_delete(user_info.name, qdest)
+ answer_delete(user_info, qdest)
command = data.text
else
- command = answer(user_info.name, qdest)
- @answer[user_info.name][qdest] = data.text
- @questions[user_info.name] = data.text # to be backwards compatible #todo remove it when 2.0
+ command = answer(user_info, qdest)
+ @answer[team_id_user][qdest] = data.text
+ @questions[team_id_user] = data.text # to be backwards compatible #todo remove it when 2.0
end
- elsif @repl_sessions.key?(user_info.name) and data.channel==@repl_sessions[user_info.name][:dest] and
- ((@repl_sessions[user_info.name][:on_thread] and data.thread_ts == @repl_sessions[user_info.name][:thread_ts]) or
- (!@repl_sessions[user_info.name][:on_thread] and data.thread_ts.to_s == '' ))
-
+ elsif @repl_sessions.key?(team_id_user) and data.channel==@repl_sessions[team_id_user][:dest] and
+ ((@repl_sessions[team_id_user][:on_thread] and data.thread_ts == @repl_sessions[team_id_user][:thread_ts]) or
+ (!@repl_sessions[team_id_user][:on_thread] and data.thread_ts.to_s == '' ))
+
if data.text.match(/^\s*```(.*)```\s*$/im)
- @repl_sessions[user_info.name][:command] = $1
- else
- @repl_sessions[user_info.name][:command] = data.text
+ @repl_sessions[team_id_user][:command] = $1
+ else
+ @repl_sessions[team_id_user][:command] = data.text
end
command = 'repl'
else
command = data.text
end
-
#when added special characters on the message
if command.match(/\A\s*```(.*)```\s*\z/im)
command = $1
elsif command.size >= 2 and
((command[0] == "`" and command[-1] == "`") or (command[0] == "*" and command[-1] == "*") or (command[0] == "_" and command[-1] == "_"))
@@ -289,20 +317,20 @@
process_first(user_info, command, dest, @channel_id, typem, data.files, data.ts, data.thread_ts, data.routine, data.routine_name, data.routine_type, command_orig)
elsif (dest[0] == "D" or @channel_id == data.channel or data.user == config[:nick_id]) and
command.size > 0 and command[0] != "-"
process_first(user_info, command, dest, data.channel, typem, data.files, data.ts, data.thread_ts, data.routine, data.routine_name, data.routine_type, command_orig)
# if @botname on #channel_rules: do something
- elsif typem == :on_pub or typem == :on_pg
+ elsif (typem == :on_pub or typem == :on_pg) and command.size > 0 and command[0] != "-"
process_first(user_info, command, dest, channel_rules, typem, data.files, data.ts, data.thread_ts, data.routine, data.routine_name, data.routine_type, command_orig)
end
-
rescue Exception => stack
@logger.fatal stack
end
-
else
- @logger.warn "Pay attention there is no user on users with id #{data.user}" if user_info.nil? and data.user.to_s!=''
+ if user_info.nil? and data.user.to_s!=''
+ @logger.warn "Pay attention there is no user on users with id #{data.user}"
+ end
if !config.on_master_bot and !dest.nil? and (data.channel == @master_bot_id or dest[0] == "D") and
data.text.match?(/^\s*(!|!!|\^)?\s*bot\s+status\s*$/i) and @admin_users_id.include?(data.user)
respond "ping from #{config.channel}", dest
elsif !config.on_master_bot and !dest.nil? and data.user == config[:nick_id] and dest == @master_bot_id
# to treat on other bots the status messages populated on master bot
@@ -340,11 +368,11 @@
config.on_maintenance = file_cts.on_maintenance
config.on_maintenance_message = file_cts.on_maintenance_message
end
end
end
-
+
when /^Bot has been (closed|killed) by/i
sleep 2
get_bots_created()
when /^Changed status on (.+) to :(.+)/i
sleep 2
@@ -377,19 +405,23 @@
end
@status = :exit if config.exit_bot
end
end
if @status == :exit
+ @listening[:threads].each do |thread_ts, channel_thread|
+ unreact :running, thread_ts, channel: channel_thread
+ respond "ChatGPT session closed since SmartBot is going to be closed", channel_thread, thread_ts: thread_ts
+ end
@logger.info 'Game over!'
sleep 3
exit!
end
end
end
end
unless data.nil? or data.channel.nil? or data.channel.empty?
@announcements_activity_after[data.channel] ||= 0
- @announcements_activity_after[data.channel] += 1
+ @announcements_activity_after[data.channel] += 1
end
rescue Exception => stack
@logger.fatal stack
end
end