Many people use IRC (Internet Relay Chat) to communicate with others around the world, usually within a specific group or community (developer projects etc). During the years that IRC has been used, many people have written scripts that log into the IRC server and perform specific tasks. These are commonly referred to as “IRC Bots”. They appear as users in the channel, but are in fact just scripts running off a computer somewhere.
An IRC Bot can be used to manage channels (kicking members, banning members, making members OPs), or just to perform fun tasks (such as randomly generate quotes for members). Either way, a lot of people don’t realise just how easy making a bot is, so I’ve put together this tutorial which will walk you through the steps of building your very own IRC bot.
First Things First
Before you start programming in Ruby you will have to have it installed on your computer. I use Ubuntu Linux and so I used the command:
sudo apt-get install ruby ruby1.9
This will install ruby versions 1.8 through 1.9 onto your system. Another program that is useful to have when debugging ruby is the interactive version:
sudo apt-get install irb
If you use another Operating System (like Windows) you will have to look up how to install ruby on the internet.
Step 1
Create a new directory which will contain all your files associated with the Bot. I’ve created a directory “IRC Bot” in my home folder, and then a subdirectory “Ruby” in that.
Enter into the directory you have just created.
Step 2
Create a file called “config.rb”, open it in your favourite editor, and type the following:
$irc_server = ''
$irc_port = ''
$irc_nick = ''
$irc_host = ''
$irc_realname = ''
$irc_nickserv = ''
$irc_identify = ''
$irc_channel = ''
$irc_prefix = ''
$irc_password_prompt = '(This nickname is registered and protected|This nickname is owned by someone else)'
$irc_password_accepted = 'Password accepted \- you are now recognized'
These are the global configuration variables that we will use throughout the program. Here is a brief description of each:
$irc_server - The address where the IRC server is located, for example ‘irc.freenode.net’.
$irc_port - The port through which you can access the IRC server. Usually this is set to ‘6667′.
$irc_nick - The nickname your bot will use when it connects to the server.
$irc_host - The host of your bot (you can set this to any address you like, for instance ‘adrianhayter.com’).
$irc_realname - The “real name” of your bot (can be anything, but I usually set it to the same value as $irc_nick).
$irc_nickserv - The nickname of the NickServ bot on the IRC server (usually left as ‘NickServ’).
$irc_identify - The command used to identify users on the IRS server (usually set to ‘IDENTIFY {password}’, where {password} is the password associated with the Bot’s nickname).
$irc_channel - The name of the IRC channel you want the Bot to join (’#linux’ etc).
$irc_prefix - The prefix you want your bot to have which saves time when typing out commands (set it to something like ‘!’ or ‘%’).
$irc_password_prompt - This is a regular expression which matches the password prompt from the server (usually can be left as it is above).
$irc_password_accepted - This is a regular expression which matches the password accepted message from the server (usually can be left as it is above).
Save the config.rb with your new values.
Step 3
Create a file called “bot.rb” and open it in your favourite editor.
Add the lines:
require 'config.rb'
require 'socket'
require 'parse.rb'$connect_log = ""
$joined = 0def place(s)
strx = s.gsub(/\n/, "")
strx = strx.gsub(/\r/, "")
$con.send strx + "\n", 0
puts "--> " + strx
end$con = TCPSocket.new($irc_server,$irc_port)
place("USER " + $irc_nick + " " + $irc_host + " blah :" + $irc_realname)
place("NICK " + $irc_nick)
I’ve written a lot here, and if you have never used Ruby before then it will appear confusing, so I’ll go through it in a bit more detail.
The first three lines are all “require” statements. These statements read the files into the current bot.rb program. The first reads the config.rb that we just created, the next loads the “socket” class which is a class already built into Ruby that allows the creation of sockets to access content on the internet. The last loads the file “parse.rb” which we will create later.
The next two lines are global variables, the first is a string to store the outputs of the server (which we will use later), and the second is a variable which we will set to 1 when the bot has joined the channel.
Then we get to our first functn ion, which is called “place”. It accepts a parameter “s”, and strips this parameter of all new lines and carriage returns, before sending it down the connection and outputting it to the terminal. You don’t have to use this function, but it is very useful this entire bot program is based around it.
Finally, we open a new TCP Socket connection to the IRC server using the details we gave in the config.rb file, and then send our user and nick information down it using the place function.
Step 4
Now that we have a connection to the server, we are going to have to create an infinite loop which continually gets data from the server and checks it to see if it is important.
Add this code below what you have already written:
while true do$connect_log = $con.recv(512)
s = $connect_log.split("\r")
for i in s
puts i
if i =~ /PING\ / then
a = i.split("\:")
place("PONG #{$irc_host} :#{a[1]}")
endif i =~ /#{$irc_password_prompt}/ then
place("PRIVMSG #{$irc_nickserv} \:#{$irc_identify}")
endif i =~ /#{$irc_password_accepted}/ && $joined == 0 then
place("JOIN #{$irc_channel}")
$joined = 1
endparse(i)
end
$connect_log = ''
puts "Log Cleared\n\n"
end
This code fetches 512 bytes of data from the server and splits it into an array (separated by a carriage return). It then goes through each of these lines and checks if it is a PING from the server (at which point it will PONG the message back). This stops your bot getting booted from the server due to a PING timeout. It also checks if the password prompt has been given by the server, at which point it will send back the relevant identify message. If the server accepts the identify, then the bot will detect the accepted message and will join the channel you set in the config.rb.
Since a lot of servers have different messages for identify / password accepted, you may have to do a little investigating to find the right one. Luckily, the line “puts i” at the start of the for loop outputs the server message to the terminal, so you can see what messages are being sent, and change the config.rb variables accordingly.
At the end, it sends “i” through the function parse() (which is in the file parse.rb) and clears the log.
Step 5
Finally, create a file called “parse.rb” and open it in your favourite editor.
Add this code:
def parse(x)# INITIALIZE VARIABLES
upmynick = $irc_nick
mynick = upmynick.downcase
nick = ""
chan = ""
fullmsg = ""
upfullmsg = ""
msg = ""
upmsg = ""# SPLIT CODE UP
s = x.split("\:",3)
if s[1] =~ /!/ then
nick = s[1].split("!")[0]
end
if s[1] =~ /\ / then
chan = s[1].split("\ ")[2]
end
if s[2] != nil then
puts s[2]
fullmsg = s[2].downcase
upfullmsg = s[2]
end
if s[3] != nil then
puts s[3]
fullmsg = fullmsg + s[3].downcase
upfullmsg = upfullmsg + s[3]
endfullmsg = fullmsg.strip
upfullmsg = upfullmsg.strip# CHECK IF MESSAGE IS DIRECTED AT BOT
if upfullmsg =~ /^(#{upmynick}\:|#{$irc_prefix})(\ )*/ then
direct = true
upmsg = upfullmsg.split(/^(#{upmynick}\:|#{$irc_prefix})*/, 2)
upmsg = upmsg[2].strip
msg = upmsg.downcase.strip
else
upmsg = upfullmsg.strip
msg = fullmsg.strip
end
end
This is a very complex parsing function, but will be your starting point in creating your own custom commands. The local variables “upmynick” and “mynick” are set to the normal case bot nickname, and the lowercase bot nickname respectively. This can be very useful, as you will want to check regular expressions against the lowercase nick, but output messages with the normal case nick.
The parse function then splits the message “i” up into sections, and gets information from those sections. The local variables “nick” and “chan” are set to the obvious (the nickname of the user who sent the message, and the channel they sent it to). The variables “fullmsg” and “upfullmsg” are simply the entire message the user has sent, in lowercase and normal case.
Most IRC bots only respond to commands if they are told directly to the bot, so the next part is very useful unless you want to piss a load of people off. If the variable “upfullmsg” begins with the bot nickname (and a colon), or the bot prefix (usually &, %, ., etc), then we know that the user is telling the bot directly. A new variable “direct” is set to true, and two new variables are created (upmsg, and msg). These variables are very similar to upfullmsg and fullmsg, but they don’t have the bot nickname or prefix at the start.
So, if the “fullmsg” was “IRC_BOT: hello!”, and the IRC bot’s nickname was set to “IRC_BOT”, then msg and upmsg would now be set to “hello!”. This simply means that everytime you check the regex of a command, you don’t need to include regex to check if the bot’s nickname is being referred to. You only need to see if direct is true.
Step 6
The final stage of an IRC Bot is to add some functions to it. I’m going to show you how to make one simple function (get the bot to flip a coin) and how to add it to the parse function.
At the end of the parse.rb, before the last “end”, add the following code:
if direct == true && msg =~ /^(flip|coin)/ then
if rand(2) == 1 then
flip = "Heads"
else
flip = "Tails"
end
place("PRIVMSG #{chan} :#{flip}")
end
Simply explained, this code checks that the variable “direct” is true (i.e. the command is being told directly to the bot), and that the message sent begins with either the word “flip” or “coin”. If both these conditions are met, then the code generates a random number between 0 and 2. If the number is 1, then the outcome is “Heads”, if it is not, the outcome is “Tails”. Note that a the random number in ruby can never be the number you set in the rand() function. So the only two numbers ever outputted by rand(2) will be 0 and 1.
The bot then uses the place() function we defined earlier in bot.rb to send a message back to the channel with whatever the variable “flip” has been set to.
Finally…
To run your IRC bot, simply run bot.rb using ruby.
Thanks very much for reading my tutorial. Please comment on things you think could be explained in more detail, and if something makes no sense. If you are having loads of trouble doing anything, then please feel free to download the complete files from this tutorial here:
http://adrianhayter.com/ircbot.release.1.0.tar.gz
Popularity: 5% [?]















Recent Comments