This document is the specification of WeeChat Relay protocol: the protocol used to relay WeeChat data to clients, which are mostly remote interfaces.

1. Introduction

1.1. Terminology

The following terms are used in this document:

  • relay: this is the WeeChat with relay plugin, which acts as "server" and allows clients to connect

  • client: this is another software, connected to relay via a network connection; in most cases, this client is a remote interface.

1.2. Network diagram

The clients are connected to relay like shown in this diagram:

                                              ┌──────────┐ Workstation
 ┌────────┐                               ┌───┤ client 1 │ (Linux, Windows,
 │  irc   │◄──┐  ╔═══════════╤═══════╗    │   └──────────┘ BSD, Mac OS X ...)
 └────────┘   └──╢           │       ║◄───┘   ┌──────────┐
   ......        ║  WeeChat  │ Relay ║◄───────┤ client 2 │ Mobile device
 ┌────────┐   ┌──╢           │       ║◄───┐   └──────────┘ (Android, iPhone ...)
 │ jabber │◄──┘  ╚═══════════╧═══════╝    │      ......
 └────────┘                               │   ┌──────────┐
   ......                                 └───┤ client N │ Other devices
                                              └──────────┘


└────────────┘   └───────────────────┘╘══════╛└────────────────────────────────┘
network servers    ncurses interface    relay         remote interfaces
                                      protocol
Note
All clients here are clients using weechat protocol in relay plugin. The relay plugin also allows IRC clients, then relay plugin acts as an IRC proxy (not described in this document).

2. Protocol generalities

  • Connections from client to relay are made using TCP sockets on IP/port used by relay plugin to listen to new connections.

  • Number of clients is limited by the option relay.network.max_clients.

  • Each client is independent from other clients.

  • Messages from client to relay are called commands, they are sent as text (a string).

  • Messages from relay to client are called messages, they are sent as binary data.

3. Commands (client → relay)

Commands have format: "(id) command arguments\n".

Fields are:

  • id: optional message identifier that will be sent in answer from relay; it must be enclosed in parentheses, and must not start with an underscore ("_") (ids starting with underscore are reserved for WeeChat event messages)

  • command: a command (see table below)

  • arguments: optional arguments for command (many arguments are separated by spaces).

List of available commands (detail in next chapters):

Command Description

init

Initialize connection with relay

hdata

Request a hdata

info

Request an info

infolist

Request an infolist

nicklist

Request a nicklist

input

Send data to a buffer (text or command)

sync

Synchronize buffer(s) (get updates for buffer(s))

desync

Desynchronize buffer(s) (stop updates for buffer(s))

quit

Disconnect from relay

3.1. init

Initialize connection with relay. This must be first command sent to relay. If not sent, relay will close connection on first command received, without warning.

Syntax:

init [<option>=<value>,[<option>=<value>,...]]

Arguments:

  • option: one of following options:

    • password: password used to authenticate on relay (option relay.network.password in WeeChat)

    • compression: compression type:

      • zlib: enable zlib compression for messages sent by relay

      • off: disable compression

Note
Compression zlib is enabled by default if relay supports zlib compression.

Examples:

# initialize and use zlib compression by default (if WeeChat supports it)
init password=mypass

# initialize and disable compression
init password=mypass,compression=off

3.2. hdata

Request a hdata.

Syntax:

(id) hdata <path> [<keys>]

Arguments:

  • path: path to a hdata, with format: "hdata:pointer/var/var/…/var", the last var is the hdata returned:

    • hdata: name of hdata

    • pointer: pointer ("0x12345") or list name (for example: "gui_buffers") (count allowed, see below)

    • var: a variable name in parent hdata (previous name in path) (count allowed, see below)

  • keys: comma-separated list of keys to return in hdata (if not specified, all keys are returned, which is not recommended on large hdata structures)

A count is allowed after pointer and variables, with format "(N)". Possible values are:

  • positive number: iterate using next element, N times

  • negative number: iterate using previous element, N times

  • *: iterate using next element, until end of list

Examples:

# request all buffers, hdata of type "buffer" is returned
# keys "number" and "name" are returned for each buffer
hdata buffer:gui_buffers(*) number,name

# request all lines of all buffers, hdata of type "line_data" is returned
# all keys are returned
hdata buffer:gui_buffers(*)/lines/first_line(*)/data

# request full name of first buffer
hdata buffer:gui_buffers full_name

3.3. info

Request an info.

Syntax:

(id) info <name>

Arguments:

  • name: name of info to retrieve

Example:

info version

3.4. infolist

Request an infolist.

Important
Content of infolist is a duplication of actual data. Wherever possible, use command hdata, which is direct access to data (it is faster, uses less memory and returns smaller objects in message).

Syntax:

(id) infolist <name> [<pointer> [<arguments>]]

Arguments:

  • name: name of infolist to retrieve

  • pointer: pointer (optional)

  • arguments: arguments (optional)

Example:

infolist buffer

3.5. nicklist

Request a nicklist, for one or all buffers.

Syntax:

(id) nicklist [<buffer>]

Arguments:

  • buffer: pointer (0x12345) or full name of buffer (for example: core.weechat or irc.freenode.#weechat)

Examples:

# request nicklist for all buffers
nicklist

# request nicklist for irc.freenode.#weechat
nicklist irc.freenode.#weechat

3.6. input

Send data to a buffer.

Syntax:

input <buffer> <data>

Arguments:

  • buffer: pointer (0x12345) or full name of buffer (for example: core.weechat or irc.freenode.#weechat)

  • data: data to send to buffer: if beginning by /, this will be executed as a command on buffer, otherwise text is sent as input of buffer

Examples:

input core.weechat /help filter
input irc.freenode.#weechat hello!

3.7. sync

Updated in version 0.4.1.

Synchronize one or more buffers, to get updates.

Important
It is recommended to send this command immediately after you asked data for buffers (lines, …). It can be send in same message (after a new line char: "\n").

Syntax:

sync [<buffer>[,<buffer>...] <option>[,<option>...]]

Arguments:

  • buffer: pointer (0x12345) or full name of buffer (for example: core.weechat or irc.freenode.#weechat); name "*" can be used to specify all buffers

  • options: one of following keywords, separated by commas (default is buffers,upgrade,buffer,nicklist for "*" and buffer,nicklist for a buffer):

    • buffers: receive signals about buffers (opened/closed, moved, renamed, merged/unmerged, hidden/unhidden); this can be used only with name "*" (WeeChat ≥ 0.4.1)

    • upgrade: receive signals about WeeChat upgrade (upgrade, upgrade ended); this can be used only with name "*" (WeeChat ≥ 0.4.1)

    • buffer: receive signals about buffer (new lines, type changed, title changed, local variable added/removed, and same signals as buffers for the buffer) (updated in version 0.4.1)

    • nicklist: receive nicklist after changes

Examples:

# synchronize all buffers with nicklist
# (the 3 commands are equivalent, but the first one is recommended
# for compatibility with future versions)
sync
sync *
sync * buffers,upgrade,buffer,nicklist

# synchronize core buffer
sync core.buffer

# synchronize #weechat channel, without nicklist
sync irc.freenode.#weechat buffer

# get general signals + all signals for #weechat channel
sync * buffers,upgrade
sync irc.freenode.#weechat

3.8. desync

Updated in version 0.4.1.

Desynchronize one or more buffers, to stop updates.

Note
This will remove options for buffers. If some options are still active for buffers, the client will still receive updates for these buffers.

Syntax:

desync [<buffer>[,<buffer>...] <option>[,<option>...]]

Arguments:

  • buffer: pointer (0x12345) or full name of buffer (for example: core.weechat or irc.freenode.#weechat); name "*" can be used to specify all buffers

  • options: one of following keywords, separated by commas (default is buffers,upgrade,buffer,nicklist for "*" and buffer,nicklist for a buffer); see command sync for values

Note
When using buffer "*", the other buffers synchronized (using a name) are kept.
So if you send: "sync *", then "sync irc.freenode.#weechat", then "desync *", the updates on #weechat channel will still be sent by WeeChat (you must remove it explicitly to stop updates).

Examples:

# desynchronize all buffers
# (the 3 commands are equivalent, but the first one is recommended
# for compatibility with future versions)
desync
desync *
desync * buffers,upgrade,buffer,nicklist

# desynchronize nicklist for #weechat channel (keep buffer updates)
desync irc.freenode.#weechat nicklist

# desynchronize #weechat channel
desync irc.freenode.#weechat

3.9. test

Test command: WeeChat will reply with various different objects.

This command is useful to test the decoding of binary objects returned by WeeChat.

Important
You must not use the pointer values returned by this command, they are not valid. This command must be used only to test decoding of a message sent by WeeChat.

Syntax:

test

Example:

test

Returned objects (in this order):

Type Type (in message) Value

char

chr

65 ("A")

integer

int

123456

integer

int

-123456

long

lon

1234567890

long

lon

-1234567890

string

str

"a string"

string

str

""

string

str

NULL

buffer

buf

"buffer"

buffer

buf

NULL

pointer

ptr

0x1234abcd

pointer

ptr

NULL

time

tim

1321993456

array of strings

arr str

[ "abc", "de" ]

array of integers

arr int

[ 123, 456, 789 ]

3.10. ping

WeeChat ≥ 0.4.2.

Send a ping to WeeChat which will reply with a message "_pong" and same arguments.

This command is useful to test that connection with WeeChat is still alive and measure the response time.

Syntax:

ping [<arguments>]

Example:

ping 1370802127000

3.11. quit

Disconnect from relay.

Syntax:

quit

Example:

quit

4. Messages (relay → client)

Messages are sent as binary data, using following format (with size in bytes):

┌────────╥─────────────╥────╥────────┬──────────╥───────╥────────┬──────────┐
│ length ║ compression ║ id ║ type 1 │ object 1 ║  ...  ║ type N │ object N │
└────────╨─────────────╨────╨────────┴──────────╨───────╨────────┴──────────┘
 └──────┘ └───────────┘ └──┘ └──────┘ └────────┘         └──────┘ └────────┘
     4          1        ??      3        ??                 3        ??
 └────────────────────┘ └──────────────────────────────────────────────────┘
       header (5)                        compressed data (??)
 └─────────────────────────────────────────────────────────────────────────┘
                               'length' bytes
  • length (unsigned integer): number of bytes of whole message (including this field)

  • compression (byte): flag:

    • 0x00: following data is not compressed

    • 0x01: following data is compressed with zlib

  • id (string): identifier sent by client (before command name); it can be empty (string with zero length and no content) if no identifier was given in command

  • type (3 chars): a type: 3 letters (see table below)

  • object: an object (see table below)

4.1. Compression

If flag compression is equal to 0x01, then all data after is compressed with zlib, and therefore must be uncompressed before being processed.

4.2. Identifier

There are two types of identifiers (id):

  • id sent by client: relay will answer with same id in its answer

  • id of an event: on some events, relay will send message to client using a specific id, beginning with underscore (see table below)

WeeChat reserved identifiers:

Identifier Received with sync Data sent Description Recommended action in client

_buffer_opened

buffers / buffer

hdata: buffer

Buffer opened

Open buffer

_buffer_moved

buffers / buffer

hdata: buffer

Buffer moved

Move buffer

_buffer_merged

buffers / buffer

hdata: buffer

Buffer merged

Merge buffer

_buffer_unmerged

buffers / buffer

hdata: buffer

Buffer unmerged

Unmerge buffer

_buffer_hidden

buffers / buffer

hdata: buffer

Buffer hidden

Hide buffer

_buffer_unhidden

buffers / buffer

hdata: buffer

Buffer unhidden

Unhide buffer

_buffer_renamed

buffers / buffer

hdata: buffer

Buffer renamed

Rename buffer

_buffer_title_changed

buffers / buffer

hdata: buffer

Title of buffer changed

Change title of buffer

_buffer_cleared

buffer

hdata: buffer

Buffer cleared

Clear buffer

_buffer_type_changed

buffer

hdata: buffer

Type of buffer changed

Change type of buffer

_buffer_localvar_added

buffer

hdata: buffer

Local variable added

Add local variable in buffer

_buffer_localvar_changed

buffer

hdata: buffer

Local variable changed

Change local variable in buffer

_buffer_localvar_removed

buffer

hdata: buffer

Local variable removed

Remove local variable from buffer

_buffer_line_added

buffer

hdata: line

Line added in buffer

Display line in buffer

_buffer_closing

buffers / buffer

hdata: buffer

Buffer closing

Close buffer

_nicklist

nicklist

hdata: nicklist_item

Nicklist for a buffer

Replace nicklist

_nicklist_diff

nicklist

hdata: nicklist_item

Nicklist diffs for a buffer

Update nicklist

_pong

(always)

string: ping arguments

Answer to a "ping"

Measure response time

_upgrade

upgrade

(empty)

WeeChat is upgrading

Desync from WeeChat (or disconnect)

_upgrade_ended

upgrade

(empty)

Upgrade of WeeChat done

Sync/resync with WeeChat

4.2.1. _buffer_opened

This message is sent to the client when the signal "buffer_opened" is sent by WeeChat.

Data sent as hdata:

Name Type Description

number

integer

Buffer number (≥ 1)

full_name

string

Full name (example: irc.freenode.#weechat)

short_name

string

Short name (example: #weechat)

nicklist

integer

1 if buffer has a nicklist, otherwise 0

title

string

Buffer title

local_variables

hashtable

Local variables

prev_buffer

pointer

Pointer to previous buffer

next_buffer

pointer

Pointer to next buffer

Example: channel #weechat joined on freenode, new buffer irc.freenode.#weechat: