Skip to content

Instantly share code, notes, and snippets.

@alexschwartz
Created June 14, 2012 21:11
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save alexschwartz/2932976 to your computer and use it in GitHub Desktop.
Save alexschwartz/2932976 to your computer and use it in GitHub Desktop.
Post to IRC channel
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
#!/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
@aji
Copy link

aji commented Jun 14, 2012

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!

@alexschwartz
Copy link
Author

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