Collaboration

Let Isaac help you build IRC bots

Writing an IRC bot does not have to be difficult or tedious. Isaac is an IRC bot framework library that provides a simple, easy to use domain specific language that abstracts away the complexities of the task.

This may come as a surprise to some readers, but Internet Relay Chat (IRC) is still widely used. Rumors of its death have been wildly exaggerated.

IRC is a realtime chat protocol that has been around since 1988. Instant Messaging, SMS, Skype, and other options have supplanted IRC in the popular consciousness as the de facto standards for realtime communication on the Internet, but IRC still enjoys substantial usage. This is in part because IRC offers advantages that other realtime messaging protocols do not.

Taking the various modern IM protocols (the most obvious potential replacement for IRC) as an example, we see that they are designed as a person-to-person conversation tool either without concern for usability for group discussion or with such concern addressed only as an afterthought. This makes IMs generally not as well-suited for group discussion as IRC. IRC's client/server architecture is better suited to thinking of discussion channels on a server as "places" where people can congregate for discussion than typical IM protocols that assume discussion takes place in a peer-to-peer manner.

Another effect of the client/server architecture of IRC, as contrasted with the at least nominally peer-to-peer architecture of IM protocols, is that IRC channels can accept arbitrary client connections by default, while IM group chats are typically joined by invitation only. Coupled with the relative simplicity of the protocol for implementors, this serves as encouragement to add automated capabilities to IRC channels they frequent by writing IRC bots.

The term "bot" is short for "robot" -- a virtual or mechanical artificial agent. In this case, the specific type of robot being discussed is a software agent. IRC bots are programs that to some degree simulate the behavior of a normal IRC user at least as far as connecting to an IRC server or network, joining one or more channels on that IRC server or network, and responding to statements made in those channels. These bots can be used to provide any number of useful services. Such services might include responding to questions with information contained in a database to which the bot has access, performing automated tasks on command, and managing user permissions in a moderated IRC channel.

Many languages well suited to admin scripting such as Perl, Python, Ruby, and Tcl offer a number of IRC bot development frameworks as open source libraries. These frameworks offer varying levels of complexity and feature-richness for developing useful automated tools that respond to traffic in IRC channels. Often, the best framework is the simplest and that offers the basic necessities for your bot, but frameworks that have bigger feature sets may be favored by those who write a lot of IRC bots that vary wildly in functionality so that they only need to learn one framework to do everything they need to get done.

On a personal note, I am a roleplaying gamer. I started with Dungeons and Dragons about three decades ago, and have played dozens -- maybe hundreds -- of different RPGs since. Since I have started carrying RPG rulebooks around on my laptop as PDFs, I have also on occasion wanted a dice roller program to simulate the act of rolling dice without having to carry physical polyhedrons with me, as well. I have written several of them in recent years. I wrote my most recent in about 10 minutes a month ago, give or take, because I wanted one that supported virtual dice numbered from either 0 or 1 up to an arbitrary high number (among other specific features such as a friendly open source license). I decided to call it "droll".

I have since added other features, such as "exploding"; on a "roll" that produces the highest value available on the die, it automatically adds another die roll to the total. For instance, this is how calling the program to roll five "exploding" dice numbered 0-5 might look with the current version of droll (as of this writing):

> droll 5x05

5x05: [5, 1, 0, 2, 0, 5, 0] + 0 = 13

Despite the fact the command asked for five dice to be rolled, seven numbers were generated because two of them were fives, in each case prompting an immediate additional roll of a virtual die numbered 0-5. Because I play some RPGs with friends online, via IRC, it occurred to me that I should write an IRC bot that makes use of this dice rolling program so that everyone involved in a particular game can use the same program for public die rolls.

Droll is written in Ruby. I investigated the options for Ruby-based IRC bot frameworks, and ultimately narrowed down the options to a library called Isaac that provides a simple domain specific language (DSL) for creating IRC bots. Isaac is a copyfree licensed framework that can be installed using the Ruby gem toolset. To use it with MRI, the reference implementation of Ruby 1.8.x, issue this command to install the Isaac gem:

> gem install isaac

Whether you need to be logged in as an administrative user will depend on your current setup. To use the Rubinius implementation of Ruby, you can install the Isaac gem specifically for Rubinius with this command (assuming you have Rubinius installed):

> rbx gem install isaac

Actually writing my first IRC bot, called "drollbot", took about five or 10 minutes of cumulative time. Later work has refined the tool, but an initial working IRC bot took less time than it is likely to take to read this article. Isaac abstracts away the low-level heavy lifting for creating an automated IRC client -- a bot -- and allows you to focus on what kind of input you want it to recognize, and what kind of response you want it to give.

Taking a very simple "hello world" approach to writing an IRC bot, this is all it takes to write an IRC bot that will connect to the #botwar channel on the Freenode IRC network and respond to people's greetings with a hello:

require 'rubygems'

require 'isaac'

configure do |c|

c.nick = 'hello_bot'

# c.password = 'password'

c.server = 'irc.freenode.net'

# c.port = 7000

# c.ssl = true

c.verbose = true

end

on :connect do

join '#botwar'

end

on :channel, /^hello_bot/ do

msg channel, "Hello, #{nick}!"

end

In many cases, you will not need everything in the configure block. The c.nick and c.server options at least are likely to be necessary. If you have your bot's nickname registered with the particular IRC network you are using, setting c.password will cause the IRC bot to automatically attempt to authenticate itself. If the port number is not set, Isaac defaults to using 6667. If you want to connect to Freenode using SSL to encrypt communications, you need to set c.port to 7000 and c.ssl to true. The c.verbose configuration option causes the IRC bot to output potentially helpful diagnostic and monitoring information to the terminal from which you launched your IRC bot.

The fact that SSL and a registered username are unnecessary for a simple hello world program is the reason those configuration lines are commented out. The lines are still included in the above source code example merely to show how they can be used.

The on :connect block performs actions when the bot first connects to the IRC network; the join directive takes a comma separated list of arguments as IRC channels on the connected IRC network that the bot should join.

Finally, the on :channel block takes a match pattern as an argument to determine what kind of message it should recognize, and to which it should respond, in an IRC channel's traffic. The behavior specified within the block is what the bot does in response to such messages. In this case, a regular expression specifies the condition for response as its nickname being the first thing in a message posted to the channel. The response is to use the implicit variable nick to respond to the channel where the message was posted. The nick variable contains the nickname -- the IRC username, that is -- of the account that posted the message to which your IRC bot would respond.

In practical terms, what this all means is that if you name your program file hellobot.rb, you can start it like this:

> ruby hellobot.rb

The #botwar channel is pretty much the official testing ground for IRC bots on the Freenode network. You can sign into the channel from the IRC client of your choice and test out hellobot's functionality. In my case, I used irssi, and did this test:

16:56 <@apotheon> hello_bot: hi there

16:56 <@hello_bot> Hello apotheon!

As you can see, it worked well enough. Drollbot, my die rolling IRC bot, is a little bit more sophisticated, with most of its functionality in the droll tool, which is called as a library by drollbot.

Isaac offers other functionality as well. You can check out some documentation and simple usage examples at Isaac's GitHub repository (linked above). You can also look at an example of the syntax for writing a bot that handles private messages by looking at the source for drollbot, which is provided by the drollbot.rb file in my BitBucket repository for droll.

The droll project may be distributed under the terms of the Open Works license.

About

Chad Perrin is an IT consultant, developer, and freelance professional writer. He holds both Microsoft and CompTIA certifications and is a graduate of two IT industry trade schools.

8 comments
unexist
unexist

There are many Ruby bot frameworks out there, most of them have one thing in common: They aren't really active anymore if they ever were. I started with isaac a while ago and had to change/fix many things on my own. There are many pending tickets and even more forks. All updates so far were mostly pull requests and I would say the project is frozen or dead. I switched to cinch (https://github.com/cinchrb/cinch) then, a really active and new framework. It uses a similar DSL like isaac, a plugin interface and proper threading. This allows to run many different plugins and prevents the bot from crashing, when some plugin does something nasty. There is also a plugin repository, that gets new plugins every day. Isaac was a really nice idea, but still lacks many things. If you really want to play with Ruby and IRC bots, I suggest to give cinch a try too.

darkstate
darkstate

Many years ago, In the early days of broadband, I got infected by a Iroffer bot and had someone fill my pc up full of films and music that i hadn't even requested or asked for,This of course was a nasty trojan that was using iroffer on IRC. This in turn made me curious about what Iroffer was, and what IRC was. Iroffer is a fileserver that is used on irc that takes commands via dcc, So yes someone was actually controlling something on my pc without me knowing remotely, but Iroffer isn't built for nasty stuff like this, Its main job is to be a legit bit of software that is used as a fileserver on IRC. This then got me into using IRC on a regular basis, not for downloading films/music etc but to start and run a network using unrealircd/neostats/services and a bunch of other stuff including other bots like eggdrop. That was over 5 yrs ago, I didn't keep the server going for long as It was time consuming keeping it up to date and botnet free, but the time I was on there I did learn a lot from a lot of people. Anyone who has a question about anything will find a channel on IRC that has someone Interested In it, And I mean anything. I do pop on there now and again to see what going on and whats new and believe me when i say this, Its pretty much the same as it was when i first went on there, except now people are more tech savvy.

apotheon
apotheon

What would you recommend for Ruby 1.8 compatibility? Cinch is 1.9+ only. edit: Also . . . Isaac is far from a dead project. The link to the GitHub project page included in the article leads to an active project, with several commits this year.

apotheon
apotheon

I think that writing IRC bots can serve as one of the best simple introductory paths to learning more about programming. Programming is all about automation, and robot scripts are more directly about automation than many other forms of programming. Further, thanks to the proliferation of easy to use frameworks for IRC bot development in popular high-level languages, it's an extremely easy field of development to get into. You just need an idea for something you'd like an IRC bot to do for you.

unexist
unexist

I would suggest to switch to 1.9 and let 1.8 finally die. There is no reason to keep it artificially alive. Six commits so far this year and all are related to pull requests. This is pretty much dead for me.

apotheon
apotheon

The way developers are backporting is kind of haphazard and, generally, a bad idea. There should have been a more clean split. The result of the current policy of feature backports for minor version updates of 1.8 appears to be increasing danger of legacy code breakage in a manner that is not reasonably expected from minor version updates. I applaud security fixes being applied to 1.8, though. It would be more accurate to say that YARV is faster than MRI. Execution speed is a function of the implementation, and not of the language definition version (even when the definition is manifest in a reference implementation). By the way, actual completeness would suggest that there should be less movement in core development, not more -- so the suggestion that pull requests making up the lion's share of changes means it's not "complete" is exactly backwards. In any case, such a state of affairs might mean nothing more than that the process of selecting people to give direct commit access is being overrun by enthusiasm from outside contributors, which would *also* suggest that the project is quite the opposite of "dead". Your evidence of project death does not support your conclusion without some kind of additional evidence or context.

unexist
unexist

I really would like to get rid of 1.8. Keeping 1.8 alive binds developers to stupid tasks like backporting features of 1.9 or security fixes. It was an upstream decision to make 1.8 and 1.9 not compatible to each other after all. Not to mention that 1.9 is just faster. For me, the lack of own contributions and only reactions on pull requests shows, that the original author has no time to continue the project and it's obviously far away from being complete.

apotheon
apotheon

Portability is important. Why would I want to intentionally write nonportable code by using a library that provides nothing for which I have any use above and beyond the library I'm using? I'm not keeping 1.8 artificially alive; I'm just keeping my software portable between 1.8 and 1.9 implementations of Ruby when there is no reason to do otherwise other than your disdain for portability. > Six commits so far this year and all are related to pull requests. This is pretty much dead for me. I guess it's a good thing the whole world doesn't live by your standards, then.

Editor's Picks