Created
June 14, 2012 21:11
-
-
Save alexschwartz/2932976 to your computer and use it in GitHub Desktop.
Post to IRC channel
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
require "socket" | |
# The irc class, which talks to the server and holds the main event loop | |
class IRC | |
def initialize(params) | |
@host = params[:host] | |
@port = params[:port] | |
@nick = params[:nick] | |
@channel = params[:channel] | |
end | |
def post(msg) | |
send("PRIVMSG \##{@channel} #{msg}") | |
end | |
def send(s) | |
# Send a message to the irc server and print it to the screen | |
puts "--> #{s}" | |
@irc.send "#{s}\n", 0 | |
end | |
def connect() | |
# Connect to the IRC server | |
@irc = TCPSocket.open(@host, @port) | |
send "USER blah blah blah :blah blah" | |
send "NICK #{@nick}" | |
send "JOIN #{@channel}" | |
end | |
def evaluate(s) | |
# Make sure we have a valid expression (for security reasons), and | |
# evaluate it if we do, otherwise return an error message | |
if s =~ /^[-+*\/\d\s\eE.()]*$/ then | |
begin | |
s.untaint | |
return eval(s).to_s | |
rescue Exception => detail | |
puts detail.message() | |
end | |
end | |
return "Error" | |
end | |
def handle_server_input(s) | |
# This isn't at all efficient, but it shows what we can do with Ruby | |
# (Dave Thomas calls this construct "a multiway if on steroids") | |
case s.strip | |
when /^PING :(.+)$/i | |
puts "[ Server ping ]" | |
send "PONG :#{$1}" | |
when /^:(.+?)!(.+?)@(.+?)\sPRIVMSG\s.+\s:[\001]PING (.+)[\001]$/i | |
puts "[ CTCP PING from #{$1}!#{$2}@#{$3} ]" | |
send "NOTICE #{$1} :\001PING #{$4}\001" | |
when /^:(.+?)!(.+?)@(.+?)\sPRIVMSG\s.+\s:[\001]VERSION[\001]$/i | |
puts "[ CTCP VERSION from #{$1}!#{$2}@#{$3} ]" | |
send "NOTICE #{$1} :\001VERSION Ruby-irc v0.042\001" | |
when /^:(.+?)!(.+?)@(.+?)\sPRIVMSG\s(.+)\s:EVAL (.+)$/i | |
puts "[ EVAL #{$5} from #{$1}!#{$2}@#{$3} ]" | |
send "PRIVMSG #{(($4==@nick)?$1:$4)} :#{evaluate($5)}" | |
else | |
puts s | |
end | |
end | |
def main_loop() | |
# Just keep on truckin' until we disconnect | |
while true | |
ready = select([@irc, $stdin], nil, nil, nil) | |
next if !ready | |
for s in ready[0] | |
if s == $stdin then | |
return if $stdin.eof | |
s = $stdin.gets | |
send s | |
elsif s == @irc then | |
return if @irc.eof | |
s = @irc.gets | |
handle_server_input(s) | |
end | |
end | |
end | |
end | |
end |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#!/usr/local/bin/ruby | |
require 'socket' | |
require 'choice' | |
require './IRC' | |
Choice.options do | |
header '' | |
header 'Specific options:' | |
option :host do | |
short '-h' | |
long '--host=HOST' | |
desc 'The hostname of the IRC server (default irc.freeirc.de)' | |
default 'irc.freeirc.de' | |
end | |
option :port do | |
short '-p' | |
long '--port=PORT' | |
desc 'The port to connect to (default 6667)' | |
cast Integer | |
default 6667 | |
end | |
option :nick do | |
short '-n' | |
long '--nick=NICK' | |
desc 'The nick name (default gist2932976)' | |
default 'gist2932976' | |
end | |
option :channel do | |
short '-c' | |
long '--channel=CHANNEL' | |
desc 'The nick name (default #test)' | |
default '#test' | |
end | |
option :msg do | |
short '-m' | |
long '--message=MESSAGE' | |
long '--msg=MESSAGE' | |
desc "The message to post (default 'Hi folks!')" | |
default 'Hi folks!' | |
end | |
option :listen do | |
long '--listen' | |
desc "Listen to the thread" | |
default false | |
end | |
separator '' | |
separator 'Common options: ' | |
option :help do | |
long '--help' | |
desc 'Show this message' | |
end | |
option :verbose do | |
short '-v' | |
long '--verbose' | |
desc 'Enable verbose mode' | |
end | |
option :version do | |
long '--version' | |
desc 'Show version' | |
action do | |
puts "v#{PROGRAM_VERSION}" | |
exit | |
end | |
end | |
end | |
puts Choice.choices.inspect if Choice.choices[:verbose] | |
irc = IRC.new(Choice.choices) | |
irc.connect() | |
irc.post(Choice.choices[:msg]) | |
if Choice.choices[:listen] | |
begin | |
irc.main_loop() | |
rescue Interrupt | |
rescue Exception => detail | |
puts detail.message() | |
print detail.backtrace.join("\n") | |
retry | |
end | |
end |
To be honest: The original version v1 is a copy from http://www.dzone.com/snippets/simple-irc-bot-written-ruby
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
This is really cool! My favorite line is line 58 where you determine whether the command was in a channel or a query and generate the proper PRIVMSG target:
#{(($4==@nick)?$1:$4)}
Nice!