class SlackSmartBot
def process_first(user, text, dest, dchannel, typem, files, ts, thread_ts, routine)
nick = user.name
rules_file = ""
text.gsub!(/^!!/,'^') if typem == :on_call
rules_file = config.rules_file
elsif dest[0] == "C" or dest[0] == "G" rules_file = config.rules_file
if @rules_imported.key?(user.id) and @rules_imported[user.id].key?(dchannel)
unless @bots_created.key?(@rules_imported[user.id][dchannel])
get_bots_created()
end
if @bots_created.key?(@rules_imported[user.id][dchannel])
rules_file = @bots_created[@rules_imported[user.id][dchannel]][:rules_file]
end
end
elsif dest[0] == "D" and @rules_imported.key?(user.id) and @rules_imported[user.id].key?(user.id) unless @bots_created.key?(@rules_imported[user.id][user.id])
get_bots_created()
end
if @bots_created.key?(@rules_imported[user.id][user.id])
rules_file = @bots_created[@rules_imported[user.id][user.id]][:rules_file]
end
end
if nick == config[:nick] begin
case text
when /^Bot has been (closed|killed) by/i
if config.channel == @channels_name[dchannel]
@logger.info "#{nick}: #{text}"
if config.simulate
@status = :off
config.simulate = false
Thread.exit
else
exit!
end
end
when /^Changed status on (.+) to :(.+)/i
channel_name = $1
status = $2
if config.on_master_bot or config.channel == channel_name
@bots_created[@channels_id[channel_name]][:status] = status.to_sym
update_bots_file()
if config.channel == channel_name
@logger.info "#{nick}: #{text}"
else @logger.info "Changed status on #{channel_name} to :#{status}"
end
end
when /extended the rules from (.+) to be used on (.+)\.$/i
from_name = $1
to_name = $2
if config.on_master_bot and @bots_created[@channels_id[from_name]][:cloud]
@bots_created[@channels_id[from_name]][:extended] << to_name
@bots_created[@channels_id[from_name]][:extended].uniq!
update_bots_file()
end
when /removed the access to the rules of (.+) from (.+)\.$/i
from_name = $1
to_name = $2
if config.on_master_bot and @bots_created[@channels_id[from_name]][:cloud]
@bots_created[@channels_id[from_name]][:extended].delete(to_name)
update_bots_file()
end
end
return :next rescue Exception => stack
@logger.fatal stack
return :next end
end
if text.match(/^@?(#{config[:nick]}):*\s+(.+)\s*/im) or
text.match(/^()\^\s*(.+)\s*/im) or
text.match(/^()!\s*(.+)\s*/im) or
text.match(/^()<@#{config[:nick_id]}>\s+(.+)\s*/im)
command2 = $2
if text.match?(/^()\^\s*(.+)/im)
add_double_excl = true
addexcl = false
if command2.match?(/^![^!]/) or command2.match?(/^\^/)
command2[0]=''
elsif command2.match?(/^!!/)
command2[0]=''
command2[1]=''
end
else
add_double_excl = false
addexcl = true
end
command = command2
else
addexcl = false
if text.include?('$') command = text.lstrip.rstrip
else
command = text.downcase.lstrip.rstrip
end
end
if command.include?('$') command.scan(/\$([^\$]+)/i).flatten.each do |sc|
sc.strip!
if @shortcuts.key?(nick) and @shortcuts[nick].keys.include?(sc)
command.gsub!("$#{sc}", @shortcuts[nick][sc])
elsif @shortcuts.key?(:all) and @shortcuts[:all].keys.include?(sc)
command.gsub!("$#{sc}", @shortcuts[:all][sc])
elsif @shortcuts_global.key?(nick) and @shortcuts_global[nick].keys.include?(sc)
command.gsub!("$#{sc}", @shortcuts_global[nick][sc])
elsif @shortcuts_global.key?(:all) and @shortcuts_global[:all].keys.include?(sc)
command.gsub!("$#{sc}", @shortcuts_global[:all][sc])
end
end
command.scan(/\$([^\s]+)/i).flatten.each do |sc|
sc.strip!
if @shortcuts.key?(nick) and @shortcuts[nick].keys.include?(sc)
command.gsub!("$#{sc}", @shortcuts[nick][sc])
elsif @shortcuts.key?(:all) and @shortcuts[:all].keys.include?(sc)
command.gsub!("$#{sc}", @shortcuts[:all][sc])
elsif @shortcuts_global.key?(nick) and @shortcuts_global[nick].keys.include?(sc)
command.gsub!("$#{sc}", @shortcuts_global[nick][sc])
elsif @shortcuts_global.key?(:all) and @shortcuts_global[:all].keys.include?(sc)
command.gsub!("$#{sc}", @shortcuts_global[:all][sc])
end
end
text = command
text = "!" + text if addexcl and text[0] != "!"
text = "^" + text if add_double_excl
end
if command.scan(/^(shortcut|sc)\s+([^:]+)\s*$/i).any? or
(@shortcuts.keys.include?(:all) and @shortcuts[:all].keys.include?(command)) or
(@shortcuts.keys.include?(nick) and @shortcuts[nick].keys.include?(command)) or
(@shortcuts_global.keys.include?(:all) and @shortcuts_global[:all].keys.include?(command)) or
(@shortcuts_global.keys.include?(nick) and @shortcuts_global[nick].keys.include?(command))
command = $2.downcase unless $2.nil?
if @shortcuts.keys.include?(nick) and @shortcuts[nick].keys.include?(command)
text = @shortcuts[nick][command].dup
elsif @shortcuts.keys.include?(:all) and @shortcuts[:all].keys.include?(command)
text = @shortcuts[:all][command].dup
elsif @shortcuts_global.keys.include?(nick) and @shortcuts_global[nick].keys.include?(command)
text = @shortcuts_global[nick][command].dup
elsif @shortcuts_global.keys.include?(:all) and @shortcuts_global[:all].keys.include?(command)
text = @shortcuts_global[:all][command].dup
else
respond "Shortcut not found", dest unless dest[0] == "C" and dchannel != dest return :next end
text = "!" + text if addexcl and text[0] != "!"
text = "^" + text if add_double_excl
end
command = text
begin
t = Thread.new do
begin
Thread.current[:dest] = dest
Thread.current[:user] = user
Thread.current[:command] = command
Thread.current[:rules_file] = rules_file
Thread.current[:typem] = typem
Thread.current[:files?] = !files.nil? && files.size>0
Thread.current[:ts] = ts
Thread.current[:thread_ts] = thread_ts
Thread.current[:routine] = routine
if thread_ts.to_s == ''
Thread.current[:on_thread] = false
Thread.current[:thread_ts] = Thread.current[:ts] else
Thread.current[:on_thread] = true
end
if (dest[0] == "C") || (dest[0] == "G") and @rules_imported.key?(user.id) &&
@rules_imported[user.id].key?(dchannel) && @bots_created.key?(@rules_imported[user.id][dchannel])
Thread.current[:using_channel] = @rules_imported[user.id][dchannel]
elsif dest[0] == "D" && @rules_imported.key?(user.id) && @rules_imported[user.id].key?(user.id) and
@bots_created.key?(@rules_imported[user.id][user.id])
Thread.current[:using_channel] = @rules_imported[user.id][user.id]
else
Thread.current[:using_channel] = ''
end
processed = process(user, command, dest, dchannel, rules_file, typem, files, Thread.current[:thread_ts])
@logger.info "command: #{nick}> #{command}" if processed
on_demand = false
if command.match(/^@?(#{config[:nick]}):*\s+(.+)/im) or
command.match(/^()!!(.+)/im) or
command.match(/^()\^(.+)/im) or
command.match(/^()!(.+)/im) or
command.match(/^()<@#{config[:nick_id]}>\s+(.+)/im)
command2 = $2
Thread.current[:command] = command2
if command2.match?(/^()!!(.+)/im) or
command.match?(/^()\^(.+)/im)
Thread.current[:on_thread] = true
end
command = command2
on_demand = true
end
unless config.on_maintenance and processed
if @status == :on and
(!answer.empty? or
(@repl_sessions.key?(nick) and dest==@repl_sessions[nick][:dest] and
((@repl_sessions[nick][:on_thread] and thread_ts == @repl_sessions[nick][:thread_ts]) or
(!@repl_sessions[nick][:on_thread] and !Thread.current[:on_thread] ))) or
(@listening.key?(nick) and typem != :on_extended and
((@listening[nick].key?(dest) and !Thread.current[:on_thread]) or
(@listening[nick].key?(thread_ts) and Thread.current[:on_thread] ) )) or
dest[0] == "D" or on_demand)
@logger.info "command: #{nick}> #{command}" unless processed
if dest[0] == "C" or dest[0] == "G" or (dest[0] == "D" and typem == :on_call)
if typem != :on_call and @rules_imported.key?(user.id) and @rules_imported[user.id].key?(dchannel)
if @bots_created.key?(@rules_imported[user.id][dchannel])
if @bots_created[@rules_imported[user.id][dchannel]][:status] != :on
respond "The bot on that channel is not :on", dest
rules_file = ""
end
end
end
unless rules_file.empty?
begin
eval(File.new(config.path+rules_file).read) if File.exist?(config.path+rules_file)
rescue Exception => stack
@logger.fatal "ERROR ON RULES FILE: #{rules_file}"
@logger.fatal stack
end
if defined?(rules)
command[0] = "" if command[0] == "!"
command.gsub!(/^@\w+:*\s*/, "")
if method(:rules).parameters.size == 4
rules(user, command, processed, dest)
elsif method(:rules).parameters.size == 5
rules(user, command, processed, dest, files)
else
rules(user, command, processed, dest, files, rules_file)
end
else
@logger.warn "It seems like rules method is not defined"
end
end
elsif @rules_imported.key?(user.id) and @rules_imported[user.id].key?(user.id)
if @bots_created.key?(@rules_imported[user.id][user.id])
if @bots_created[@rules_imported[user.id][user.id]][:status] == :on
begin
eval(File.new(config.path+rules_file).read) if File.exist?(config.path+rules_file) and !['.','..'].include?(config.path + rules_file)
rescue Exception => stack
@logger.fatal "ERROR ON imported RULES FILE: #{rules_file}"
@logger.fatal stack
end
else
respond "The bot on <##{@rules_imported[user.id][user.id]}|#{@bots_created[@rules_imported[user.id][user.id]][:channel_name]}> is not :on", dest
rules_file = ""
end
end
unless rules_file.empty?
if defined?(rules)
command[0] = "" if command[0] == "!"
command.gsub!(/^@\w+:*\s*/, "")
if method(:rules).parameters.size == 4
rules(user, command, processed, dest)
elsif method(:rules).parameters.size == 5
rules(user, command, processed, dest, files)
else
rules(user, command, processed, dest, files, rules_file)
end
else
@logger.warn "It seems like rules method is not defined"
end
end
else
@logger.info "it is a direct message with no rules file selected so no rules file executed."
if command.match?(/^\s*bot\s+rules\s*(.*)$/i)
respond "No rules running. You can use the command `use rules from CHANNEL` to specify the rules you want to use on this private conversation.\n`bot help` to see available commands.", dest
end
unless processed
dont_understand('')
end
end
if processed and @listening.key?(nick)
if Thread.current[:on_thread] and @listening[nick].key?(Thread.current[:thread_ts])
@listening[nick][Thread.current[:thread_ts]] = Time.now
elsif !Thread.current[:on_thread] and @listening[nick].key?(dest)
@listening[nick][dest] = Time.now
end
end
end
end
rescue Exception => stack
@logger.fatal stack
end
end
rescue => e
@logger.error "exception: #{e.inspect}"
end
end
end