Skip to content

Instantly share code, notes, and snippets.

@stephanschubert
Created September 16, 2009 09:08
Show Gist options
  • Save stephanschubert/187946 to your computer and use it in GitHub Desktop.
Save stephanschubert/187946 to your computer and use it in GitHub Desktop.
#!/usr/bin/ruby
%w(rubygems socket yaml).each { |lib| require lib }
class Bot
attr_reader :nick, :server, :port, :options, :server_info, :server_message
def initialize(nick, server, port, options = {}, &block)
@nick = nick
@server = server
@port = port
@options = options
@event_handlers = []
@socket = TCPsocket.open(server, port)
install_exit_handler
on("PING") { write "PONG #{server_message}" }
instance_eval(&block)
nick @nick
user @nick
while true
line = @socket.readline; puts line
fire_events(line)
sleep 0.1
end
end
def on(event, &block)
code = lookup_event_code(event)
handler = if code == 0
lambda { |line| instance_eval(&block) if line =~ /#{event}/i }
else
lambda { |line| instance_eval(&block) }
end
(@event_handlers[code] ||= []) << handler
end
def fire_events(line)
@server_info, @server_message = line.sub(/^:/, "").split(":")
@server_info =~ /(\d{3})/
if handlers = @event_handlers[$1.to_i]
handlers.each { |h| h.call(line) }
end
end
def write(string)
@socket.write(string + "\n")
end
def quit
write "QUIT"
end
def nick(nick)
write "NICK #{nick}"
end
def user(nick, realname = nil)
write "USER #{nick} 8 * :#{realname || nick}"
end
def join(channel)
write "JOIN #{channel}"
end
def say(to, message)
write "PRIVMSG #{to} #{message}"
end
private
def install_exit_handler
exit_handler = lambda { quit; @socket.close }
%w(INT TRAP).each { |signal| trap(signal, exit_handler) }
end
def lookup_event_code(event)
@event_codes ||= YAML.load_file("irc-events.yml")
@event_codes.find { |k, v| v == event.to_s }.first rescue 0
end
end
# Usage
Bot.new("mybot", "irc.freenode.net", "6667") do
on :endofmotd do
join "#mychannel"
say "#mychannel", "hello"
end
end
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment