O'Reilly Hacks
oreilly.comO'Reilly NetworkSafari BookshelfConferences Sign In/My Account | View Cart   
Book List Learning Lab PDFs O'Reilly Gear Newsletters Press Room Jobs  


 
Buy the book!
IRC Hacks
By Paul Mutton
July 2004
More Info

HACK
#50
Pass Notes to Other Users
Not everybody can afford to be permanently connected to IRC, but it is still often a preferred medium for communication. Pass messages on to other users when they next join the channel with this simple IRC bot
The Code
[Discuss (0) | Link to this hack]

The Code

We can use a HashMap to store a list of messages to pass on, allowing more than one message to be sent to any one user. The HashMap will be indexed by nickname, and each entry will point to an ArrayList that contains messages for that user.

Create a file called TellBot.java:

import org.jibble.pircbot.*;
import java.util.*;

public class TellBot extends PircBot {
    
    // A map of String (nickname) to ArrayList (message Strings).
    private HashMap messages = new HashMap( );
    
    public TellBot(String name) {
        setName(name);
    }
    
    public void onMessage(String channel, String sender, String login,
            String hostname, String message) {
        
        String[] tokens = message.split("\\s+");

        // Check for the "tell" command.
        if (tokens.length > 2 && tokens[0].equalsIgnoreCase("tell")) {
            String nick = tokens[1];
            message = message.substring(message.indexOf(nick) + nick.length( ) + 1);
            
            // Convert the nickname to lowercase for use in the HashMap.
            String key = nick.toLowerCase( );
            ArrayList list = (ArrayList) messages.get(key);
            if (list == null) {
                // Create a new ArrayList if the HashMap entry is empty.
                list = new ArrayList( );
                messages.put(key, list);
            }
            
            // Add the message to the list for the target nickname.
            list.add(sender + " asked me to tell you " + message);
            sendMessage(channel, "Okay, " + sender);
        }
        
    }
    
    public void onJoin(String channel, String sender,
            String login, String hostname) {
        
        // Convert the nickname to lowercase to get the HashMap key.
        String key = sender.toLowerCase( );
        ArrayList list = (ArrayList) messages.get(key);
        if (list != null) {
            // Send all messages to the user.
            for (int i = 0; i < list.size( ); i++) {
                String message = (String) list.get(i);
                sendMessage(channel, sender + ", " + message);
            }
            // Now erase all messages for this user.
            messages.put(key, null);
        }
    }
    
}

Notice that the HashMap keys must be converted to lowercase. This effectively makes the nicknames case insensitive, so a message that is left for "Paul" can also be received by "paul."

The onMessage method is invoked whenever someone sends a message to the channel. This method checks to see if a user has entered the "tell" command—if so, it adds the message to the HashMap.

When a user joins the channel, the onJoin method is invoked. If there are any messages for this user, they are sent to the channel and then removed from the HashMap.

To instantiate the bot, you will need a main method. Create this in TellBotMain.java:

public class TellBotMain {
    
    public static void main(String[] args) throws Exception {
        TellBot bot = new TellBot("TellBot");
        bot.setVerbose(true);
        bot.connect("irc.freenode.net");
        bot.joinChannel("#irchacks");
    }
    
}

You can also tell the bot to join more than one channel—simply modify the joinChannel method call so it contains a comma-separated list, for example:

        bot.joinChannel("#irchacks,#jibble,#pircbot");

Messages will be accepted from all channels and delivered to the first one the recipient joins.


O'Reilly Home | Privacy Policy

© 2007 O'Reilly Media, Inc.
Website: | Customer Service: | Book issues:

All trademarks and registered trademarks appearing on oreilly.com are the property of their respective owners.