Skip to main content

skip to main content

developerWorks  >  Java technology  >

IRC bot dreams

Craft and implement your own simple IRC bot using the Java language

developerWorks
Document options

Document options requiring JavaScript are not displayed


Rate this page

Help us improve this content


Level: Introductory

David Seager (seager@uk.ibm.com), Software Developer, IBM

01 Apr 2001

Internet Relay Chat (IRC) is a useful and fun tool for today's Internet users, and it is made all the more so by those handy automatons who sit on servers waiting to help out -- the bots. In this article, David Seager builds a very simple IRC bot in the Java language and demonstrates how it works.

A bot as a client

On a basic level, a bot is just a program that simulates an IRC client. It listens for messages and chat it recognises, and it performs useful functions and sends messages to users. The bot I've detailed in this article can respond to private messages from IRC users and can be easily extended to handle different commands, as well as perform other tasks.

Fast track to the code
Listing 1. The Testbot main method: This method instantiates itself, connects the bot to a server, and sends it into a loop that listens for messages and handles them.

Listing 2. BasicIRCBot logon() method fragment: This method logs on to the IRC server.

Listing 3. BasicIRCBot pingpong method: Pinging and ponging ensure that the clients and the server stay connected.

Listing 4. TestBot srv_privmsg implementation fragment: This method performs a string comparison against the command.

The program consists of two classes:

  • The base class BasicIRCBot is a framework bot that can log on to a server, remain connected, and listen for private messages.
  • The executable bot class Testbot extends BasicIRCBot and adds some logic for dealing with specific messages.



Back to top


Do your IRC RFC homework

Before attempting to prepare an IRC bot, you must have a working knowledge of the technology. Because I refer heavily to the specifications in Internet Request for Comments (RFC) 1459, you need to familiarize yourself with this document to properly simulate an IRC client (see Resources.)

The specification reveals that the IRC protocol uses plain text, formatted into various messages to handle actions such as logins, messages, actions, and notifications. The exact format of, say, a logon message is spelt out in the RFC, so I referred to it often to develop the bot.



Back to top


The code

The class BasicIRCBot handles the logon to an IRC server, setting up its nickname and description, listening for private messages, and handling other IRC-specific messages.

The actual runnable class, Testbot, extends BasicIRCBot and overrides the srv_privmsgs method, which is called with the contents of a private message and the name of the user who sent it. (See Resources for the complete source.) This method details how the bot decides to act on a message sent from an IRC user. As you can see in Listing 1, the main method of Testbot instantiates itself, connects the bot to a server, and sends it into a loop that listens for messages and handles them.

The BasicIRCBot class constructor takes two Strings -- the bot's nickname and description. After the class is instantiated, its connect method is called, passing the hostname and port of the IRC server as parameters. The bot opens a simple socket to the server and gets an output and input stream to send and receive messages to the server. This is mere sockets code and nothing IRC-specific has happened yet.


Listing 1. The main method


public static void main(java.lang.String[] args)

{

        Testbot IRC = new Testbot("testbot", "masters bot");

        IRC.connect("localhost", 6667);

        IRC.logon();

        IRC.running = true;

        while(IRC.running)

        {

                IRC.service();

        }

        IRC.logoff();

        IRC.disconnect();

}


Logging on
The next thing the bot does is log on to the IRC server in its logon method, as shown in Listing 2. This method sends the IRC logon message user Testbot ware2 irc : Test bot. The message tells the server that the bot's local username is "Testbot," its host is "ware2," and its description is "Test bot."

The next message sent to the server is nick Testbot, which requests the nickname Testbot for the bot. An IRC nickname is how a user is seen on the IRC network. It's used when another user wants to talk privately (with a series of private messages) and is typically known as a user's nick in IRC lingo.

These two messages are the minimum that should be sent to an IRC server to log on. At this point (if someone else isn't already using the nick Testbot), the server will log on the bot and send back a few welcome messages (containing the server's message of the day and server stats).

Now the bot is logged on to the server and can be examined from another IRC client using the command /whois Testbot.


Listing 2. BasicIRCBot logon() method fragment


// send user info

bw.write("user " + botName + " ware2 irc :" + botDescription);

bw.newLine();

bw.write("nick " + botName);

bw.newLine();

bw.flush();


The Testbot program next enters a loop calling the service method repeatedly until its running variable becomes false. It then logs out of the server and ends. The service method of BasicIRCBot is its core -- this method listens for messages sent from the IRC server, determines the type of message, and takes the appropriate action.

Pretty much all communications in IRC are routed through the server. If a user wants to send you a message, they send it to the server, which then relays it to you (the "R" in "IRC"). While there are many different types of messages in IRC, the BasicIRCBot deals only with two: pings and private messages.

A game of ping pong
To ensure that clients are still connected, an IRC server will periodically send them a ping message. This message takes the form ping [number] (for example, ping 10023). To indicate they are still there, clients respond with the message pong [number] (in this case, pong 10023). Failure to respond to a ping message quickly enough will result in the server disconnecting a user (or kicking them). This timeout value is a server-specific setting. Typical values are around a minute or so.

Ping handling occurs in the private pingpong method, which returns true if the server message was a ping and prints ping pong to System.out. Leave the bot idle and connected and watch its console output to see how often a server sends ping messages.


Listing 3. BasicIRCBot pingpong method

private boolean pingpong(String msg) throws IOException

{

  if(msg.substring(0,4).equalsIgnoreCase("ping"))

  {

    // send a pong back

    String pongmsg = "pong " + msg.substring(5);

    IRCor.write(pongmsg);

    IRCor.newLine();

    IRCor.flush();

    System.out.println("ping pong");

    return true;

  }

  return false;

}


Private messages
Most IRC messages take the form :<prefix> <command> <parameters>, so the BasicIRCBot service method splits the message into those three strings. The <command> is a string that indicates what is happening; for instance, a private message command is privmsg. The service method checks for this specific command string. If the message isn't a privmsg, the method sleeps for a tenth of a second and returns.

The meaning of the prefix portion of a message depends on the command. For a privmsg, the prefix contains the nickname, username, and host of the IRC user who sent the message (generally in the format <nickname>!=<username>@<hostname>, but possibly in the format <nickname>). The code extracts and passes the nickname and parameters to the BasicIRCBot private method parse_privmsg for further processing.

Private message parameters
A privmsg parameter contains the nick of the user the message is for (in this case, the bot's nick) and the message, coded in the format <nick> :<message> or <nick> <message>. The parse_privmsg extracts the nick and message and calls the protected method srv_privmsg to act upon the message.

In the BasicIRCBot class, this method is empty. We override it in the Testbot class to respond to a few different messages from a user. This technique allows us to extend the BasicIRCBot to handle messages from users.

Testbot commands
The srv_privmsg method performs a string comparison against the command.

  • If it starts with "hello," Testbot uses the protected BasicIRCBot method send_privmsg to send a private message back to the user, in this case hello <username>.
  • If the message is "time," Testbot will get the current time and send that back.
  • Finally, if the message equals "quit" and the user's nick is "master," the bot notifies the user that it is quitting and sets the variable running to false, causing the repetitive loop in main calling the service method to end. If the user is not "master," the bot will tell the user that it's not going to quit.


Listing 4. TestBot srv_privmsg implementation fragment


if(message.startsWith("hello"))

{

  send_privmsg(username, "hello " + username);

  return;

}

if(message.startsWith("time"))

{

  Date now = new Date();

  DateFormat nowTime = DateFormat.getTimeInstance();

  send_privmsg(username, "the time is " + nowTime.format(now));

  return;

}

if(message.equals("quit"))

{

  if(username.equals("master"))

  {

    send_notice(username, "testbot ends now");

    running = false;

  }

  else

  {

    send_privmsg(username, "sorry, you are not my master");

  }

  return;

}


The two message-sending methods, send_privmsg and send_notice in the BasicIRCBot class, form valid IRC messages and send them to the server. The format of a message when sending is slightly different than when receiving -- a private message is sent with privmsg <nickname> :<message> and a notify with notice <nickname> :<message>.



Back to top


The finale

That's pretty much all there is to writing a Java-based IRC bot. The BasicIRCBot:

  • Lurks on a server until it's told to quit or is kicked off
  • Responds to certain messages, providing a useful time service
  • Can be extended to join channels, respond to more messages, or perform any number of useful functions using the RFC as a guide

There are myraid ways to extend the BasicIRCBot, and I encourage you to give it a shot. If you extend the bot in a unique or interesting way, let me know and maybe I can persuade developerWorks to publish it.



Resources

  • The IRC protocol is detailed in RFC 1459 at irc.org.

  • Download the source code for the BasicIRCBot class.

  • Extend the BasicIRCBot with the TestBot class.


About the author

David Seager, a software developer with IBM, has been playing with Linux and Web-based applications for more than two years.




Rate this page


Please take a moment to complete this form to help us better serve you.



 


 


Not
useful
Extremely
useful
 


Share this....

digg Digg this story del.icio.us del.icio.us Slashdot Slashdot it!



Back to top