Previous Section  < Day Day Up >  Next Section

Hack 85 Understanding CTCP Messages

figs/beginner.gif figs/hack85.gif

CTCP messages are used quite frequently on IRC. Learn what they mean so you can use them effectively.

CTCP is the Client-to-Client Protocol, which is used over IRC to send structured data. In general, a CTCP request will be sent as part of a PRIVMSG message [Hack #78] to a user or to a channel. This message consists of a string of text between two ASCII 0x01 characters (ASCII character 1). There are two forms of CTCP messages: tagged data and queries. Queries are also used to set up DCC connections [Hack #69] .

13.9.1 Tagged Data

Tagged data consists of specially tagged and formatted data used to send special messages between clients. This is seldom used with modern IRC clients, with the exception of the CTCP ACTION command.

The original CTCP specification spoke of actions as being "used by losers on IRC to simulate `role-playing' games." Actions are behind the /me action command. The string is fairly simple and consists of the ACTION command (all uppercase) followed by the text of the action. For example:

\001ACTION jumps for joy!\001

\001ACTION is considering switching to Gentoo.\001

\001ACTION tries to recompile his kernel, but fails.\001

If the user Fennec is sending these messages, most IRC clients will render these actions similar to this:

* Fennec jumps for joy!

* Fennec is considering switching to Gentoo.

* Fennec tries to recompile his kernel, but fails.

13.9.2 Queries

Several simple CTCP commands request information from someone else. When a client receives these, it should reply with a CTCP command of the same name sent to the originator via NOTICE (and not via PRIVMSG). If your client does not understand a CTCP query, it can be safely ignored.

Generally, a CTCP query is sent to an individual user. If you send a CTCP command to a channel, you can expect a response from all the clients on that channel. Doing this repeatedly is seldom appreciated or advisable. If you receive a CTCP query from a channel, however, you should reply only to the original sender.

An example command would be the following sent as a PRIVMSG:


This would be the reply, but note that it would be sent as a NOTICE:

\001TIME Sat Nov 12 1955 22:04:00 PST\001

Here are some valid CTCP queries:


Requests the name and version of your IRC client. Replies should be of the form CLIENT NAME:VERSION:ENVIRONMENT; however, this exact format is often ignored—for example: mIRC v6.14 Khaled Mardam-Bey.


Rarely used and primarily historical, but it should return the location of the source code for the IRC client.


Used as a way to ping an individual client. Typically, the sending machine will use the PING command with some representation of the current time; the receiving machine is expected to reply with an identical PING command, so it is possible to work out how long it took to get the reply.


Requests the time. It should be replied to with a human-readable string informing the user of the client's current local time.


Should return a string set by the IRC user, presumably giving information about the user.


Should tell what tagged data a client is capable of handling. See RFC 1459 for more information on how this command should be used.


Used to reply to a CTCP request that produces an error. When used as a query, the reply should echo back the exact data produced by the query, followed with an indication that no error has happened.

If you are running a PircBot-based bot, you may notice that it automatically responds to some of these queries, such as VERSION, PING, and TIME. You can override the methods that are responsible for replying, although it is a good idea to call the same method in the superclass to ensure that the bot still responds appropriately, for example:

public void onPing(String sourceNick, String sourceLogin,

        String sourceHostname, String target, String pingValue) {

    System.out.println("I got pinged by " + sourceNick);

    // Make the PircBot super class perform its normal response to the PING.

    super.onPing(sourceNick, sourceLogin, sourceHostname, target, pingValue);


You can override methods like this to find out which users are interested in your bot.

Thomas Whaples

    Previous Section  < Day Day Up >  Next Section