# tomsg protocol (version 4) The underlying transport of the protocol is a plain TCP socket. However, because private information is communicated, the recommended transport is an encrypted and authenticated wrapper around a TCP socket; examples are an SSH connection, or something built on a TLS connection. The individual messages are all line-based; this means that a single message, both client->server and server->client, always ends with a newline (ASCII 10) character. Preliminary definitions: - A _string_ is a series of non-zero bytes that are not newlines (ASCII 10). To allow for clients written in programming languages that automatically parse strings as UTF-8, argument strings should always be valid UTF-8. However, the server currently does not care. - A _word_ is a string without spaces (ASCII 32) (and also without newlines). Note that the empty string is also a valid word. Timestamps in the protocol, which indicate the time at which an event happened, are represented as microseconds since the UNIX epoch. A valid timestamp is always non-negative, i.e. at least 0. There are three kinds of messages: commands from the client, command responses from the server, and push messages from the server (not to be confused with push _notifications_). These three kinds are described below. Note that the first message the client must send is the `version` command, with which server and client can agree (or not) on a protocol version; if a `version` message has not yet been replied to with an `ok` response, no other commands are valid. See the definition of the `version` command for more information. In the syntax descriptions below, `` indicates an argument called "name"; the angle brackets are not part of the syntax. The type of the argument may be indicated with the notation ``; possible types are `i64` (a 64-bit signed integer in decimal notation), `word` (a word), and `string...` (a string stretching until the end of the line). A message from client to server consists of a _tag_, a space, the command name, a space, and finally the arguments to the command. The tag is a word, and may be arbitrarily chosen by the client; it will be returned by the server in its response to the client's message, so that the client can easily link requests and responses. All client commands, if not syntactically invalid, will be replied to with a server response. A _response_ from the server will be in one of the following forms: - ` ok` - The message from the client was successfully processed. - ` number ` - A numeric value was returned. - ` error ` - The client's message was successfully parsed, but handling resulted in an error described in the message. - ` name ` - A name was returned, probably the name of the room in `create_room`. - ` list words...` - A list of words was returned. The number of words returned is given in ``; the words themselves are space-separated further arguments to `list`. - ` pong` - Response to the client's `ping` command. - ` history ` - Response to the client's `history` command; is followed by exactly `` messages of type `history_message` with the same tag. The messages are returned in chronological order (oldest first). - ` history_message ` - Part of the response to the client's `history` command. Index 0 is the oldest message; index (`` - 1) (from the `history` response) is the newest message in the fragment requested. The reply message id is -1 if the message is a normal message, or nonnegative if it is a reply to the referenced message in the same room. - ` message ` - Response to the client's `get_message` command. This contains the information for a single message, as in `_push message` and the `history_message` response. A command is identified by its name, which can be found in the list below. Its arguments are zero or more words, except if for the command in question the last argument is of type `string...` (in which case it may contain spaces and ranges until the end of the line). Note: all messages on the server have an ID that is globally unique on a single tomsg server. - ` version ` - Indicates that the client wishes to speak the protocol with the specified version. For the version of the protocol described in this document, see the header at the top of the file. After the server has replied to this command with `ok`, the rest of the protocol of (only) the specified version may be used. Before that, or if the server replies with `error`, no commands other than `version` are valid. If the client sends subsequent `version` messages after the first one, the server may choose to handle those subsequent messages and switch versions, or always return `error`, or some arbitrary mix. However, sending multiple `version` messages is always valid (though not recommended). It is probable that the server can only speak one version of the protocol, but it may support multiple versions. Note also that the version is a _word_, not an integer; though this document describes an integer-versioned protocol, future versions may use other printable ASCII characters (but not any outside that range). - Returns `ok` or `error`. - ` register ` - Register a new user on the server. The password may contain spaces. - Returns `ok` or `error`. - ` login ` - Logs in as the specified user. - Returns `ok` or `error`. - ` change_password ` - Changes the password of the current user to the given string. - Returns `ok` or `error`. - ` logout` - Logs out of the user the client is currently logged in as. If the client is not logged in, does nothing. - Returns `ok`. - ` list_rooms` - Lists all rooms the user is a member of. - Returns `list` or `error`. - ` list_members ` - Lists all members of the given room, if the user is also a member. (This includes the user themselves.) - Returns `list` or `error`. - ` create_room` - Creates a new room, and enters the room. The id of the room is returned to the client. Returns an error if the client is not logged in. If successful, all other sessions of the current user get a `_push invite` push message for the new room with the current user (itself) as the inviter. Also marks the current session as active. - Returns `name` or `error`. - ` leave_room ` - Leaves the room. Returns an error if the client is not logged in, or not in that room. If successful, a `_push leave` push message is sent to all remaining room members, as well as all other sessions of the current user. The message contains the room left and the name of the current user. Also marks the current session as active. - Returns `name` or `error`. - ` invite ` - Invites the given user to the given room, if the client is currently a member of that room. The invited user is immediately added to the room. If the invite succeeds, the invited user receives a `_push invite` push message on all its sessions, and all current room members receive a `_push join` push message on all their sessions (except the session the `invite` message was sent from). Also marks the current session as active. - Returns `ok` or `error`. - ` send ` - Sends a message to the given room. All room members receive a `_push message` push message on all their sessions (except the session the `send` message was sent from). If `` is -1, this sends a normal message. Otherwise, `` must be the id of a message in the given room, in which case the sent message is a reply to the indicated earlier message. If `` is not a message in this room, `error` is returned. Also marks the current session as active. The returned `number` response contains the message id of the message sent. This number will be non-negative. - Returns `number` or `error`. - ` sendat ` - Inserts a message in the history of the given room at the given timestamp. `roomname`, `replymsgid` and `message` are as in the `send` command; if `replymsgid` is not -1, the referred-to message must be in the same room and have a timestamp that is earlier than `timestamp`. Note that negative timestamps are not valid for `sendat`. All room members receive a `_push message` push message on all their sessions (except the session the `send` message was sent from). Contrary to `send`, the current session is _not_ marked active. The `apikey` argument is a value whose interpretation is implementation-defined. The intention is to restrict usage of this command to known-to-be well-behaving clients. The returned `number` response contains the message id of the message sent. This number will be non-negative. - Returns `number` or `error`. - ` history ` - Requests the last `` messages in the given room, if the client is a member of the room. In the `history` response, `` will be at most ``, and may be less if the room does not yet have `` messages. Each message will be returned in a `history_message` response after the `history` response, in chronological order. - Returns `history`, followed by zero or more `history_message`. - ` history_before ` - Same as `history`, except the returned messages are the last `` strictly before the timestamp of the message with id ``. - Returns `history`, followed by zero or more `history_message`. - ` get_message ` - Retrieves the message with the given id. - Returns `message` or `error`. - ` ping` - Asks for a `pong` response. - Returns `pong`. - ` is_online ` - Returns with how many sessions the given user is currently online. - Returns `number` or `error`. - ` firebase_token ` - Adds the given Firebase token to the account of the current user. This is used for new-message push notifications for Android-based clients. - Returns `ok` or `error`. - ` delete_firebase_token ` - Removes the given Firebase token from the account of the current user. - Returns `ok` or `error`. - ` user_active ` - Marks the user as active (if `active` > 0) or inactive (if `active` <= 0) on the current session. This does not influence whether the user is marked active on any of the other sessions on which they are currently logged in. A session is automatically marked inactive 2 minutes after the latest activity on that session. This is used for Firebase notifications: a user will only receive Firebase notifications if they are marked inactive on all their sessions, or if they have no active sessions. - Returns `ok` or `error`. Push messages from the server are formatted like responses with tag `_push`. These are not sent in response to a particular client message, but are sent by the server due to other events. Some have already been mentioned above, but all are listed below. - `_push online ` - When user X logs in or logs out in a session, all sessions of all members (excluding user X) of all rooms user X is a member of receive a `_push online` push message stating that `` (user X) is now online with `` sessions. - `_push message ` - Sent to all sessions of all members of a room in which a message is posted, except the session that sent the message. `` is -1 if the message is a normal message, and references the replied-to message otherwise. - `_push invite ` - Sent to all sessions of the invited user after an `invite` command. The `` parameter indicates who invited you to the given room. - `_push join ` - Sent to all sessions of all members of a room (except the session sending the `invite` command and all sessions of the invited user) in which a new user entered. - `_push leave ` - When user X leaves room R, this push message is sent to: 1. all sessions of all remaining users in room R, and 2. all sessions of user X that were not the one to send the initiating `leave_room` command. - `_push ping` - Sent by the server once in a while. Please ignore.