Message IDs

Copyright © 2016 James Wheare <james@irccloud.com>

Unlimited redistribution and modification of this document is allowed provided that the above copyright notice and this permission notice remains intact.


Introduction ๐Ÿ”—

This specification describes a message tag indicating a server supplied unique ID for events.

Motivation ๐Ÿ”—

Communication on IRC has historically been limited to a flat structure of sequential messages without unique identifiers shared across clients. As a result, the protocol lacks the ability to establish relationships between messages and other entities. This places limits on client-side enhancements such as reply tracking, message editing, rating or sending other forms of message annotation.

The message ID tag is a way for servers to enable these enhancements.

Architecture ๐Ÿ”—

Dependencies ๐Ÿ”—

This specification doesnโ€™t define any capabilities of its own, but the message-tags capability MUST be negotiated for servers wishing to use this tag.

Tags ๐Ÿ”—

This specification adds the msgid tag, which has a required value.

Servers MAY attach this tag on any event. If this tag is being used, it SHOULD be attached to all PRIVMSG and NOTICE events.

Tag value ๐Ÿ”—

The tag value MUST be a unique ID chosen by the originating server. Uniqueness in this context means that any other message transmitted on the entire network at any time MUST NOT share the same value.

To allow their use outside the tag space, e.g. as command parameters, message IDs MUST NOT start with a colon (:) and MUST NOT contain any of SPACE, CR, LF.

However, if a message is re-transmitted as-is, for example with the chathistory batch type, the ID SHOULD be reused. As a result, clients MUST accept shared IDs.

Clients MUST treat the ID as a case sensitive opaque identifier. Clients MUST NOT use case folding or normalization when comparing IDs.

Relationships with other specifications ๐Ÿ”—

In order to treat messages that refer to IDs consistently, clients need to know the IDs for their own messages as well. Servers that provide message IDs SHOULD also provide the echo-message capability.

Server implementation considerations ๐Ÿ”—

This section is non-normative.

Choosing an ID format ๐Ÿ”—

In order to guarantee sufficient uniqueness, message IDs canโ€™t be implemented as simple numeric counters that risk clashing with other servers on the network, or being reset if the server restarts.

Some examples of appropriate IDs are:

When using timestamps, make sure theyโ€™re correctly synchronised using NTP or similar.

Networks might also consider the risk of collisions when thereโ€™s a chance of merging with another network in future, and choose an appropriately resistant ID format.

Although clients are required to treat IDs as case sensitive opaque values, servers might still choose a case insensitive ID format internally.

Servers might wish to encode additional information within the ID, for internal use only. For instance, including account information for the author in an ID could enable authenticated message edits or deletes, without having to maintain and consult a separate message store. This requires careful attention to several concerns: security, privacy, and backwards and forwards compatibility of different ID generation schemes.

Client implementation considerations ๐Ÿ”—

This section is non-normative.

Message IDs have no guarantee of being universally unique across different IRC networks, nor will they necessarily share the same format. There is also no requirement that numeric IDs increase monotonically. Donโ€™t attempt to correlate them beyond their scope and donโ€™t use them for message ordering.

In the case of re-transmitted messages that share an ID, clients might choose to mark a message as repeated, or just use the most recent occurence as the target for followup actions. Using server IDs alone as internal primary keys isnโ€™t recommended, otherwise re-transmitted messages may not be individually addressable in client-side message stores.

Handling duplicates gracefully is also useful in the case of servers accidentally reusing an ID.

Examples ๐Ÿ”—

This section is non-normative, message IDs are not required to be UUIDs or have any specific format. Additional tags used in these examples may or may not have a specified meaning elsewhere.

A channel PRIVMSG sent by the server:

S: @msgid=63E1033A051D4B41B1AB1FA3CF4B243E :nick!user@host PRIVMSG #channel :Hello!

A private PRIVMSG sent by the server:

S: @msgid=server1-1480339715754191-21 :nick!user@host PRIVMSG me :Hello!

A channel NOTICE sent by the server:

S: @msgid=G6PuDDBWQYmu3HmXXOAPzA :nick!user@host NOTICE #channel :Hello!

A private NOTICE sent by the server:

S: @msgid=ticketid-5 :nick!user@host NOTICE me :Hello!

A channel JOIN sent by the server:

S: @msgid=msgid123 :nick!user@host JOIN #channel account :Real Name

A channel PRIVMSG sent by the server, and a possible client response. The +example/reply tag is a non-standard example:

S: @msgid=msgid1 :nick!user@host PRIVMSG #channel :Hello!
C: @+example/reply=msgid1 :nick2!user2@host2 PRIVMSG #channel :Hello to you!

Two channel PRIVMSG messages sent by the server, with possible non-standard example annotations to indicate split message concatenation:

S: @msgid=msgid1;example/split :nick!user@host PRIVMSG #channel :Hello
S: @msgid=msgid2;example/concat=msgid1 :nick!user@host PRIVMSG #channel : World

A client negotiating the message-tags capability to enable and disable messages tagged with IDs.

S: :nick!user@host PRIVMSG #channel :Hello
C: CAP REQ message-tags
S: :irc.example.com CAP me ACK :message-tags
S: @msgid=msgid-a :nick!user@host PRIVMSG #channel :Hello again
C: CAP REQ -message-tags
S: :irc.example.com CAP me ACK :-message-tags
S: :nick!user@host PRIVMSG #channel :Another hello

Errata ๐Ÿ”—

Previous versions of this specification did not describe forbidden message ID bytes.


Software supporting msgid: Ergo, IRCCloud Teams, InspIRCd, UnrealIRCd, AdiIRC, catgirl, mIRC, gamja, IRCCloud, Kiwi IRC, PIRC.pl web client, CoreIRC, Goguma, IRCCloud (as Server), KiwiBNC (as Server), KiwiBNC (as Client), pounce (as Server), pounce (as Client), soju (as Server), BitBot, Limnoria, Moon Moon, girc, Kitteh IRC Client Library, Matrix2051