IRCTK-EXTENSIONS(7)

πŸ“¦ version 1.1.0, in alpine 3.24

🌸 NAME 🌸

IRCTK-EXTENSIONS(7) β€” irctk-extensions β€” irctk extensions protocol specification.

okay bestie, this is literally the spec for the extensions protocol: the group-chat rules that let third-party programs talk to IRCTk and IRCTk talk back. πŸ’…


πŸ¦‹ ABSTRACT πŸ¦‹

The extensions communication protocol lets third-party programs receive messages from IRCTk and send messages to IRCTk, with the whole goal of writing extensions that integrate IRCTk with the surrounding system. There are different types of messages, and extensions β€” which run as external programs β€” can request which specific messages they want to receive from IRCTk. ✨


πŸŽ€ INTRODUCTION πŸŽ€

This document describes the extensions communication protocol as a simple, line-oriented stream of bytes. That stream is bi-directional, meaning IRCTk and an extension can exchange messages with each other both ways. 🫢

The protocol can stay simple because the IRC protocol as described in RFC1459 is itself a line-oriented protocol. So there's no need to handle byte sequences in some kind of β€œstructured” fashion, and no need to introduce escape sequences for special characters.

The protocol described here can be used to write client-side bots, or to integrate IRCTk with the surrounding system (think: opening URLs in a browser), leveraging the capabilities built into the systems running the application. 🌈


πŸ’– REQUIREMENTS πŸ’–

The key words β€œMUST”, β€œMUST NOT”, β€œREQUIRED”, β€œSHALL”, β€œSHALL NOT”, β€œSHOULD”, β€œSHOULD NOT”, β€œRECOMMENDED”, β€œMAY”, and β€œOPTIONAL” in this document are to be interpreted as described in RFC 2119.


πŸ”₯ MESSAGE FORMAT πŸ”₯

This specification documents the version 1.0 of the extensions protocol.

A message exchanged between IRCTk and an extension program is a UTF-8 CSV-like encoded line, terminated by the sequence CRLF (carriage-return line-feed).

A message line contains a series of fields separated by a tab (ASCII code 9 character). The number of fields varies depending on the message type. An example of a basic message might be the following:

34563\tirc\t1234\tfoo\tmention\tfalse\taway\tLibera\t#openbsd\
\ttime=2023-08-03T19:47:05.231Z\tPRIVMSG\tHello, World!CRLF

In this example, the fields are:

  • 34563 β€” The message id.
  • irc β€” The message type, in this case an irc command.
  • 1681676304 β€” The message timestamp.
  • 1234 β€” The channel id the message is coming from.
  • foo β€” The user that sent the message.
  • mention β€” Message level.
  • false β€” Application window focus state.
  • away β€” The client user current status (he is away, in this moment).
  • Libera β€” The network name.
  • #openbsd β€” The channel name.
  • time=2023-08-03T19:47:05.231Z β€” IRCv3 message tags.
  • PRIVMSG β€” IRC command.
  • Hello, world! β€” The command arguments.
  • CRLF β€” The termination sequence.

All the message types sent by either IRCTk or an extension MUST follow the aforementioned format. no cap. 🧚


πŸ‘‘ MESSAGE TYPES πŸ‘‘

The extensions protocol supports six message types:

  • Handshake
  • Ack
  • Nack
  • Filter
  • Irc
  • Plumb

If a field on a message type definition is marked as β€œEMPTY”, it means that the field itself MUST be present in the message, with a length of zero bytes. An empty field is defined by two consecutive tab characters or, if the final field of a message can be empty, by a tab character and the termination sequence.

Unless explicitly marked as β€œEMPTY”, every message MUST have an β€œid” as first field. This is required to keep track of messages that must receive an acknowledge from either the application or an extension. The ID might be numeric, or a random generated string, and it can be reused once a previous exchange, using that id, is completed. However, it is RECOMMENDED that both IRCTk and the loaded extensions use a unique message id for every exchange whenever possible.

πŸ’œ Handshake πŸ’œ

ACK/NACK: yes

The handshake messages are exchanged between IRCTk and an extension when the latter is first loaded.

A handshake message has the following fields:

  • Id β€” The message id
  • Type β€” The message type. Handshake, in this case.
  • Version β€” The protocol version.
  • Name β€” Application, or extension name.
  • AppVersion β€” Application or extension version.
  • Capabilities β€” Space-separated list of capabilities (EMPTY).

The point of this message type is to establish if the loaded extension is compatible with the version of IRCTk and its extension protocol that loaded it. ✨

Additionally, combined with proper filters, extensions MAY be able to handle particular IRCv3 capabilities that will be requested by IRCTk and forwarded with the coming messages.

πŸ“ ACK πŸ“

ACK/NACK: no

The ACK is a generic acknowledge message that might be sent by the application, or by an extension, in response to a request in order to say that it was accepted. It has the following fields:

  • Id β€” The message id
  • Type β€” The message type. ack, in this case.
  • Comment β€” A string, commenting the ACK (EMPTY).

πŸ¦‹ NACK πŸ¦‹

ACK/NACK: no

See β€œACK”, but in this case, the request or message is denied. The fields are:

  • Id β€” The message id
  • Type β€” The message type. ack, in this case.
  • Comment β€” A string, commenting the NACK (EMPTY).

🌈 Filter 🌈

ACK/NACK: yes

A β€œfilter” message is used by an extension to inform IRCTk to only send messages of the type specified in the filter or a specific command specified in the filter. More than one filter message may be sent by an extension in order to specify additional types or commands to receive.

By default all the messages processed by IRCTk will be forwarded to an extension.

A filter message has the following fields:

  • Id β€” The message id
  • Type β€” The message type. filter, in this case.
  • type/command β€” The message type or command to filter for.
Silent change in behaviour by IRCTk without acknowledge is not allowed. An extension MUST NOT change its working behaviour until an ACK for the sent request is received. πŸ’€

An extension wanting to receive messages only for a specific command of a specific type MUST first request a filter for the message type first, and then send a filter request for the specific command. For example, an extension asking to send messages of type β€œirc” only, with no further command filtering requests, will cause IRCTk to send all the messages of type irc it receives to the extension.

Refer to the β€œCommunication example” section for additional details.

⭐ IRC ⭐

ACK/NACK: no

A message of type β€œirc” is essentially an IRC command received by IRCTk from a server, or a command coming from the IRCTk user's GUI itself. All those commands, unless filters are in place, are relayed to an extension. On the other hand, an extension can send an irc message to IRCTk, to show specific information, or to relay a message to a specific channel (client-side) bot. The fields are:

  • Id β€” The message id (EMPTY)
  • Type β€” The message type. ack, in this case.
  • Timestamp β€” Timestamp of the message, in seconds, from the epoch (EMPTY).
  • Cid β€” The id of the channel in IRCTk (EMPTY).
  • Nick β€” The nick of the user that sent the message (EMPTY).
  • Level β€” Message level, from β€œinfo”, to β€œmention” (EMPTY).
  • Focus β€” true or false. Define if the application window is on focus (EMPTY).
  • Status β€” Client user's status. Might be β€œaway” or not (EMPTY).
  • Network β€” The network name.
  • Channel β€” The channel name.
  • Tags β€” A list of IRCv3 tags (EMPTY).
  • Command β€” The IRC command.
  • Args β€” The command arguments.

An example of this message (received by an extension) is the one written in the introduction section.

In this revision of the specification, the β€œid” field for the IRC message type can be empty, but it may become mandatory in a future version of the spec.

The β€œTags” field is a string representing a list of tags as defined in the IRCv3 message tags specification. This specification extends on that by adding an additional escape sequence for the tabulation character.

The escape sequence will appear, literally, in a tag value to represent a tabulation character, as the tabulation is among the permitted characters in a tag value. This is needed, as the tab character is used as a separation character for the various message fields. An example might be:

firsttag=myvalue;secondtag=new\tvalue

🌸 Plumb 🌸

ACM/NACK: no

A plumb is a generic message sent by IRCTk to an extension with just some text data.

It's up to the extension to decide what to do with this type of message.

An extension MUST NOT send messages of this type and IRCTk MUST ignore such messages. πŸ™ˆ

Fields are as follows:

  • Id β€” Message Id (EMPTY).
  • Type β€” The message type, β€œplumb” in this case.
  • Cid β€” The Id of the channel where the plumb happened (EMPTY).
  • Network β€” The network name (EMPTY).
  • Channel β€” The channel name (EMPTY).
  • Data β€” The text string.

πŸŽ€ COMMUNICATION EXAMPLE πŸŽ€

When IRCTk first starts an extension, a small handshake sequence takes place, where just some messages are exchanged. IRCTk will, initially, send the following message:

1234\thandshake\t1.0\tirctk\t1.0<CR><LF>

To which the extension will answer with an ACK if everything is fine:

1234\tack\tok<CR><LF>

or with an NACK, if something is wrong:

1234\tnack\tko<CR><LF>

If everything is ok, the extension will send its details:

5678\thandshake\t1.0\textension-name\t0.1<CR><LF>

If everything is fine, IRCTk will acknowledge that the extension is compatible:

5678\tack\tok<CR><LF>

Or deny running the extension if something is wrong (the comment is an example):

5678\tnack\textension not supported<CR><LF>

If everything is ok, the extension is finally β€œready” and the flow of other type of messages can start. As an example, an extension may ask to receive messages of type irc, only for the privmsg command:

55354\tfilter\tirc<CR><LF>
45634\tfilter\tprivmsg<CR><LF>

The application ACKs the requests:

55354\tack\tok<CR><LF>
45634\tack\tok<CR><LF>

The application then sends messages of type IRC and for the privmsg command to the extensions. An extension may send an irc message that will be posted in the corresponding channel. The following is an example of a minimum valid IRC message coming from an extension:

\tirc\t\t\t\t\t\t\tLibera\t#irctk\tPRIVMSG\tHello, world!<CR><LF>

The message will be posted, by IRCTk, to the channel #irctk on the configured Libera network. slay. πŸ’…


🫢 SEE ALSO 🫢

irctk(1)

✨ HISTORY ✨

okay so story time 🫢 the very first revision of this specification dropped alongside IRCTk 1.0 β€” like, it literally appeared with it. og release, og docs, they came out together, that's the whole vibe πŸ’… no cap, that's the entire history section, it's giving short and iconic πŸŽ€


πŸ’– AUTHORS πŸ’–

this masterpiece was written by Andrea Biscuola β€” you can reach her at a@abiscuola.com πŸ“§ like, the whole spec, the whole vision, authored by one person. main character energy fr fr πŸ‘‘βœ¨


and that's a wrap bestie!! πŸ¦‹ the whole page is yours now β€” go build something cute with it πŸ’œ

this page is from OpenBSD 7.5, dated May 19, 2024, and it's the IRCTK-EXTENSIONS(7) manual page β€” see u at the next man page, mwah πŸ˜˜πŸ’…

πŸ“¦ where this page comes from
  • alpine 3.24: irctk-doc 1.1.0-r1 Β· ISC
  • πŸ’– girlified by deepseek-ai/DeepSeek-V4.1-Flash-1017 on : a language model's rewrite of the original, under its terms