simple irc bot in Ruby


SUBMITTED BY: Guest

DATE: May 21, 2015, 10:08 a.m.

FORMAT: Ruby

SIZE: 3.4 kB

HITS: 684

  1. require "socket"
  2. # Don't allow use of "tainted" data by potentially dangerous operations
  3. $SAFE=1
  4. # The irc class, which talks to the server and holds the main event loop
  5. class IRC
  6. def initialize(server, port, nick, pass, channel)
  7. @server = server
  8. @port = port
  9. @nick = nick
  10. @pass = pass
  11. @channel = channel
  12. end
  13. def send(s)
  14. # Send a message to the irc server and print it to the screen
  15. puts "--> #{s}"
  16. @irc.send "#{s}\n", 0
  17. end
  18. def connect()
  19. # Connect to the IRC server
  20. @irc = TCPSocket.open(@server, @port)
  21. send "USER blah blah blah :blah blah"
  22. send "NICK #{@nick}"
  23. send "PASS #{@pass}"
  24. send "JOIN #{@channel}"
  25. end
  26. def evaluate(s)
  27. # Make sure we have a valid expression (for security reasons), and
  28. # evaluate it if we do, otherwise return an error message
  29. if s =~ /^[-+*\/\d\s\eE.()]*$/ then
  30. begin
  31. s.untaint
  32. return eval(s).to_s
  33. rescue Exception => detail
  34. puts detail.message()
  35. end
  36. end
  37. return "Error"
  38. end
  39. def handle_server_input(s)
  40. # This isn't at all efficient, but it shows what we can do with Ruby
  41. # (Dave Thomas calls this construct "a multiway if on steroids")
  42. case s.strip
  43. when /^PING :(.+)$/i
  44. puts "[ Server ping ]"
  45. send "PONG :#{$1}"
  46. when /^:(.+?)!(.+?)@(.+?)\sPRIVMSG\s.+\s:[\001]PING (.+)[\001]$/i
  47. puts "[ CTCP PING from #{$1}!#{$2}@#{$3} ]"
  48. send "NOTICE #{$1} :\001PING #{$4}\001"
  49. when /^:(.+?)!(.+?)@(.+?)\sPRIVMSG\s.+\s:[\001]VERSION[\001]$/i
  50. puts "[ CTCP VERSION from #{$1}!#{$2}@#{$3} ]"
  51. send "NOTICE #{$1} :\001VERSION Ruby-irc v0.042\001"
  52. when /^:(.+?)!(.+?)@(.+?)\sPRIVMSG\s(.+)\s:EVAL (.+)$/i
  53. puts "[ EVAL #{$5} from #{$1}!#{$2}@#{$3} ]"
  54. send "PRIVMSG #{(($4==@nick)?$1:$4)} :#{evaluate($5)}"
  55. else
  56. puts s
  57. end
  58. end
  59. def main_loop()
  60. # Just keep on truckin' until we disconnect
  61. while true
  62. ready = select([@irc, $stdin], nil, nil, nil)
  63. next if !ready
  64. for s in ready[0]
  65. if s == $stdin then
  66. return if $stdin.eof
  67. s = $stdin.gets
  68. send s
  69. elsif s == @irc then
  70. return if @irc.eof
  71. s = @irc.gets
  72. handle_server_input(s)
  73. end
  74. end
  75. end
  76. end
  77. end
  78. # The main program
  79. # If we get an exception, then print it out and keep going (we do NOT want
  80. # to disconnect unexpectedly!)
  81. irc = IRC.new('SERVER', PORT, 'USERNAME', 'PASSWORD', '#IRC CHANNEL')
  82. irc.connect()
  83. begin
  84. irc.main_loop()
  85. rescue Interrupt
  86. rescue Exception => detail
  87. puts detail.message()
  88. print detail.backtrace.join("\n")
  89. retry
  90. end

comments powered by Disqus