Create an IRC Bot using Python 2

Torrey Betts / Monday, April 4, 2016

What is IRC?

If you're unfamiliar with IRC (Internet Relay Chat) it is an application layer protocol used to facilitate chat with users all over the globe and has been around since the late 1980s and is still widely used to this day. There are several different IRC networks, so which one you chose to use comes down to your own personal preference.

Why Create an IRC Bot?

Simply put, IRC bots in general are simple and fun to create. They allow you to extend the functionality of a channel or even create fun interactive games for your channel. Basically, the sky is the limit in terms of possibilities for bot functionality, and when mixed with the ease of Python you can create a complex bot in very few lines of code.

How Do I Connect to the IRC Server?

The process for connecting to an IRC server is straight forward*.

  1. Connect to XXXX server on port XXXX (typically 6667)
  2. Send the USER command
  3. Send the NICK command
  4. Respond to any PING commands

* - It's important to note that some IRC servers differ in how you connect or the format of messages received, be sure to look up the reference information for the host you normally connect to.

Before connecting to the IRC server we'll setup the variables for server, botnick, the channel to join on connect and the boolean flags for sentUser and sentNick. The sentUser and sentNick boolean flags are used to determine whether or not those commands have been previously sent to the server during connection.

server = "ix.undernet.org"
channel = "#usa"
botnick = "uberbot" + str(random.randint(1, 10000))
sentUser = False
sentNick = False

Connect to XXXX server on port XXXX

To connect to a server a simple socket is created and then connected to by calling the connect method.

irc = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
print "\nConnecting to:" + server
irc.connect((server, 6667))

Send the USER command

Next, register (and something authenticate) a user session with a short username and a human-readable realname. The command format looks like this.

USER (username) (hostname) (unused) (realname)

if sentUser == False:
   irc.send("USER " + botnick + " " + botnick + " " + botnick + " :This is a fun bot\n")
   sentUser = True
   continue

Send the NICK command

After the USER command, send the NICK command to specify your chat nickname. The command format looks like this.

NICK (nickname)

if sentUser and sentNick == False:
   irc.send("NICK " + botnick + "\n")
   sentNick = True
   continue

Respond to any PING commands

IRC servers regularly send the PING command to connected clients to determine if they are still connected. To show you are connected each PING must be answered with a PONG and the supplied PING token. The PING command uses the following format.

PING (token)

if text.find("PING") != -1:
   irc.send("PONG " + text.split()[1] + "\n")

How Does My Bot Accept Commands?

To have your bot accept commands, you'll need to parse the input that comes from the buffer and then respond accordingly. Since IRC is text based the messages coming from the server are all easy to parse using regex or even a simple text find. The snippet below searches the message text from a channel or private message containing "!host". If found, the bot responds with the OS version information. 

if text.find(":!host") != -1:
irc.send("PRIVMSG " + channel + " :" + str(platform.platform()) + "\n")

Can I Just Have the Codez?

The source code below is the full listing of code used for this post.

import platform
import random
import socket
import sys

reload(sys)
sys.setdefaultencoding('utf8')

server = "ix.undernet.org"
channel = "#usa"
botnick = "uberbot" + str(random.randint(1, 10000))
sentUser = False
sentNick = False

irc = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
print "\nConnecting to:" + server
irc.connect((server, 6667))

try:
   while 1:
      text = irc.recv(2048)
      if len(text) > 0:
         print text
      else:
         continue

      if text.find("PING") != -1:
         irc.send("PONG " + text.split()[1] + "\n")

      if sentUser == False:
         irc.send("USER " + botnick + " " + botnick + " " + botnick + " :This is a fun bot\n")
         sentUser = True
         continue

      if sentUser and sentNick == False:
         irc.send("NICK " + botnick + "\n")
         sentNick = True
         continue

      if text.find("255 " + botnick) != -1:
         irc.send("JOIN " + channel + "\n")

      if text.find(":!host") != -1:
         irc.send("PRIVMSG " + channel + " :" + str(platform.platform()) + "\n")

except KeyboardInterrupt:
   irc.send("QUIT :I have to go for now!\n")
   print "\n"
   sys.exit()

Where Can I Learn More?

The links below are great references for learning about IRC, IRC bots and the IRC protocol.