Convos::Controller::Events - Stream events from Convos::Core to web
DESCRIPTION
Convos::Controller::Stream is a Mojolicious::Controller which can stream events from the backend, and also act on instructions.
API
Overview
The WebSocket API is accessible from https://example.com/events. The endpoint requires an active session, meaning the WebSocket will be closed after sending back an error if an active session is not present.
Once the WebSocket is opened, it will send and receive JSON encoded messages. The messages sent to the WebSocket should contain a "method" and an "id" key.
All the code examples below are written in JavaScript, and might require that the WebSocket is already successfully set up.
"id"
The "id" key will be echoed back in the response, so you can pair the request with the response on the client side. It is highly suggested to pass in an "id" since WebSocket responses can easily be out of order. The ID can be simply an incremtal number, such as 1, 2, 3, ..., meaning it doesn't have to be globally unique.
Note however that purly server side generated messages will not have an "id" key.
"method"
The default method is "ping", unless specified, though it is highly recommened to always include a "method". See "Methods" for a list of supported methods.
Methods
ping
The "ping" method is used to keep the WebSocket open. Example:
ws.onmessage = (e) => {
// "ts" is a high precision epoch timestamp
// {event: "pong", ts: 1593647381.72949}
const data = JSON.parse(e.data);
};
ws.send(JSON.stringify({method: "ping"});
send
The "send" method is used to send messages or instructions to a connection. All the input keys are echoed back, along with the response. Here are the input keys you can use:
connection_id
Must be present and must be a known "connection_id". Will result in an error if the "connection_id" is invalid.
conversation_id
This key is optional, but must be present if you want to send a message to specific channel or private conversation.
message
The actual message or instruction to send. An instruction must start with "/", like "/part", while everything else will be sent as a regular message. To force sending a message you can use the instruction "/say". Example:
{ method: "send", connection_id: "irc-libera", conversation_id: "#convos", message: "/say /part is a command you can use to leave a conversation" }
See the actual Convos::Core::Connection to see which actions are supported and not.
Here is an example on how to use the "send" method:
ws.onmessage = (e) => {
// The response will be dependent on what the action actually does
// {event: "sent", id: 42, ...}
const data = JSON.parse(e.data);
};
ws.send(JSON.stringify({
method: "send",
connection_id: "irc-whatever",
conversation_id: "#conversation_name",
id: 42,
message: "some message"
});
Errors
Any invalid input or error while trying to handle the instructions will result in an error structure like this:
{
// Required
event: "sent", # handshake, sent, ...
errors: [
{message: "some error", path: "/"}
],
// If present in input
connection_id: "irc-whatever",
id: 42,
message: "some message",
}
The "path" inside the error element might point to which part was actually invalid. Example:
{message: "Missing connection ID.", path: "/connection_id"}
Server events
A server generated event for a given user will be be passed over the WebSocket.
Messages
A message sent in a channel, private conversation or generated by the server will result in a "messsage" event. Example:
{
connection_id: "irc-whatever",
conversation_id: "superwoman",
from: "Superwoman",
highlight: false,
messsage: "Some message",
ts: 1593647381.72949,
type: "private",
}
Details:
connection_id
Identities from which connection the message originates from.
conversation_id
An unique ID that identifies the conversation on a given connection.
from
A human readable version of who sent the message.
highlight
True if this message should be highlighted in the user interface. This is true if your nick is mentioned or if the message matches any "highlight_keywords" in Convos::Core::User.
message
The actual message that was sent.
ts
A high precision epoch timestamp.
type
Can be either "private", which is just a normal message, "notice" which is not a very important message, "action" if the message should be prefixed with the nickname and "error" if this is an error message.
The value of "type" might change in the future. Suggested values:
Old | New --------|-------- private | normal notice | notice action | ? error | error
State changes
A state change is triggered when the connection, the user or another participant changes state. It can be everything from when disconnected, nick changes or join events. Example structure:
{
connection_id: "irc-whatever",
conversation_id: "#conversation_name"
nick: "Superwoman",
type: "join",
}
Details:
connection_id
Identities from which connection the message originates from.
conversation_id
An unique ID that identifies the conversation on a given connection.
This key is only present in certain cases. See "type" below.
from, mode
"from" contains the nick that made the mode change, and "mode" contains the new "mode".
This key is only present in certain cases. See "type" below.
frozen
Will contain a reason for why you are not enable to join/talk in a given conversation. Empty string if everything is ok.
This key is only present in certain cases. See "type" below.
kicker
The nick of whom kicking "nick".
This key is only present in certain cases. See "type" below.
name
See "name" in Convos::Core::Conversation.
This key is only present in certain cases. See "type" below.
nick
The target nick for this event.
This key is only present in certain cases. See "type" below.
new_nick, old_nick
Used to identify from what nick and to what nick in a "nick_change" event.
This key is only present in certain cases. See "type" below.
message
A human readable message with details of this event.
This key is only present in certain cases. See "type" below.
topic
See "topic" in Convos::Core::Conversation.
This key is only present in certain cases. See "type" below.
type
Can be...
Type | Extra keys -------------|--------------------------------------- me | nick, ... frozen | conversation_id, frozen, name, topic, unread join | conversation_id, nick quit | conversation_id, nick, message part | conversation_id, nick, message part | conversation_id, kicker, nick, message mode | conversation_id, from, mode, nick nick_change | new_nick, old_nick
METHODS
start
Will push Convos::Core::User and Convos::Core::Connection events as JSON objects over a WebSocket connection and receive messages from the frontend.
webhook
See https://convos.chat/api.html#op-post--webhook