IRCTK-EXTENSIONS(7)

NAME
irctk-extensions - irctk extensions protocol specification

ABSTRACT
The extensions communication protocol, allows third party programs to receive and send messages to and from IRCTk, with the idea of writing extensions to integrate IRCTk with the surrounding system. Different type of messages are provided, and the extensions, running as external programs, can request which specific messages to receive from IRCTk.

INTRODUCTION
This document describe the extensions communication protocol as a simple, line-oriented, stream of bytes. Such stream is bi-directional, meaning, IRCTk and an extension can exchange messages between each other.

The protocol can be kept simple due to the fact that the IRC protocol as described in RFC1459, is itself a line-oriented protocol, thus there is no need to handle bytes sequences in a, somehow, “structured” fashion, nor there is the need to introduce escape sequences for special characters.

The protocol described herein can be used to write client-side bots, or to integrate IRCTk with the surrounding system (think about 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.

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.

An handshake message have 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 means of this message type, is to establish if the loaded extension is compatible with the version of IRCTk and it's 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 it's working behaviour until an ACK for the sent request is received.

An extension wanting to receive messages only for specific command of a specific type, MUST first request a filter for the message type first, and then send a filter requests 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 it 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 sequences for the 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 a 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 it's 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.

SEE ALSO
irctk(1)

HISTORY
The first revision of this specification appeared with IRCTk 1.0

AUTHORS
Andrea Biscuola a@abiscuola.com