Home arrow Python arrow Page 4 - IRC on a Higher Level Concluded

Something Practical - Python

If you've been following this series of articles closely, then you already have the skills necessary to develop applications that communicate through IRC. The Python-IRCLib library is easy to learn and use, so putting it to work should not be a difficult task at all. However, the library contains a few more gems that are worth taking a look at, and these gems can make your development process go even more smoothly.

  1. IRC on a Higher Level Concluded
  2. SingleServerIRCBot
  3. Channel Information
  4. Something Practical
By: Peyton McCullough
Rating: starstarstarstarstar / 5
October 26, 2005

print this article



Let's take a look at something a bit more practical now: a full-fledged IRC bot capable of accepting commands from users. If that doesn't sound interesting, then let's take things one step futher: a bot that responds to users based on external scripts that can be loaded and reloaded on-the-fly.

Our bot will scan a directory, “commands”, for Python files. It will load these files as modules and store them in a dictionary. If a user prefixes the bot's name with a dollar symbol ( for example, “$PyBot” ), then the bot will examine the incoming message for a second argument. If a second argument is present, it will be compared to the dictionary of modules. If a module's name matches the command, the index function of the module will be called, and the connection and event type will be passed. Also, if we receive a CTCP command whose name matches a special password, the bot will rescan. Let's translate this to Python:

import glob
import ircbot
import imp

# Bot scan password
password = 'd3vsh3d0652'

# Connection informatoin
network = 'irc.freenode.net'
port = 6667
channel = '#irclib'
nick = 'PyBot'
name = 'Python Bot'

# We'll store the commands here
commands = {}

# Scan the "commands" directory and load the modules
def scan():
   for moduleSource in glob.glob ( 'commands/*.py' ):
      name = moduleSource.replace ( '.py', '' ).replace ( '\\',
'/' ).split ( '/' ) [ 1 ].upper()
      handle = open ( moduleSource )
      module = imp.load_module ( 'COMMAND', handle, ( 'commands/'
+ moduleSource ), ( '.py', 'r', imp.PY_SOURCE ) )
      commands [ name ] = module

# Create our bot class
class ModularBot ( ircbot.SingleServerIRCBot ):

   # Join a channel when welcomed
   def on_welcome ( self, connection, event ):
      connection.join ( channel )

   # Listen to public messages
   # If the user says our name, prefixed with "$", then we act
   def on_pubmsg ( self, connection, event ):
      if event.arguments() [ 0 ].split() [ 0 ].upper() == ( '$' +
nick.upper() ):

          # See if the user specified a valid command
          # If so, call the module
          if len ( event.arguments() [ 0 ].split() ) == 1:
          elif commands.has_key ( event.arguments() [ 0 ].split()
[ 1 ].upper() ):
             commands [ event.arguments() [ 0 ].split()
[ 1 ].upper() ].index ( connection, event )

   # Listen to CTCP messages for the scan password
   # If we get it, rescan
   def on_ctcp ( self, connection, event ):
      if event.arguments() [ 0 ] == password.upper():

# Scan for commands

# Create the bot and run it
bot = ModularBot ( [( network, port )], nick, name )

There are no suprises, the bot works exactly in the way I explained above. Now, all that's left is giving the bot a few commands to work with. To begin, let's start with an “about” command. To implement this, we simply create a file called “about.py” and place it in the “commands” directory, filling an index function with the appropriate information:

def index ( connection, event ):
   connection.privmsg ( event.source().split ( '!' ) [ 0 ], 'I am
an IRC bot built in Python.' )
   connection.privmsg ( event.source().split ( '!' ) [ 0 ], 'I am
modular and can load command modules on the fly.' )

The module will be automatically loaded when the bot is started up. Alternatively, we can have it reload the module by using this command in an IRC client:

/ctcp PyBot d3vsh3d0652

Pretty neat, huh? Of course, we can create commands that accept additional arguments as well. Consider a command that accepts a number and then attempts to square it:

def index ( connection, event ):

   # Do we have an extra argument?
   # If not, complain
   if len ( event.arguments() [ 0 ].split() ) == 2:
      connection.privmsg ( event.source().split ( '!' ) [ 0 ],
'Please include a number.' )

   # Try to square the number and return it to the user
         number = float ( event.arguments() [ 0 ].split() [ 2 ] )
         number = number ** 2
         connection.privmsg ( event.source().split ( '!' ) [ 0 ],
str ( number ) )


While working directly with the IRC protocol can get the job done, development can be messy and slow. The Python-IRCLib library exists between your applications and the IRC protocol, allowing you to take an object-oriented approach to the IRC protocol. It ensures that the result is quickly put together, compact and clean.

The library allows you to work with the protocol on several levels. In this article, we explored the top-most level of interaction: objects that act as clients, automating much of the dirty or otherwise repetitive work. You now have the skill necessary to develop a wide variety of IRC applications fit for just about any task you can think of –- whether it is recording statistics about users or accepting commands and interacting with users.

We also built a modular IRC bot. Feel free to use it and modify it as you see fit. If you wish to share any modifications or modules to the bot –- or information about any IRC project –- then please e-mail me because I would love to hear about it. One simple modification to the bot might be a help command, which lists the supported commands or calls a certain method of the modules.

There is one thing you should remember though: bots are nice, but the niceness can quickly wear off. Never build an overly-annoying application, and never seek to use a bot for malicious purposes.

>>> More Python Articles          >>> More By Peyton McCullough

blog comments powered by Disqus
escort Bursa Bursa escort Antalya eskort


- Python Big Data Company Gets DARPA Funding
- Python 32 Now Available
- Final Alpha for Python 3.2 is Released
- Python 3.1: String Formatting
- Python 3.1: Strings and Quotes
- Python 3.1: Programming Basics and Strings
- Tuples and Other Python Object Types
- The Dictionary Python Object Type
- String and List Python Object Types
- Introducing Python Object Types
- Mobile Programming using PyS60: Advanced UI ...
- Nested Functions in Python
- Python Parameters, Functions and Arguments
- Python Statements and Functions
- Statements and Iterators in Python

Developer Shed Affiliates


Dev Shed Tutorial Topics: