docs/md/events.md
# Frontend Client Events
## Message deleted
When an admin/mod/etc. deletes a message from a room, everyone on that room will receive an event with the name
`gn_message_deleted` so they can remove it locally as well.
```json
{
"id": "<server-generated UUID>",
"published": "<server-generated timestamp, RFC3339 format>",
"object": {
"id": "<UUID of the message that was deleted>"
},
"target": {
"id": "<UUID of the room the message was deleted in>"
},
"verb": "delete",
"actor": {
"id": "<ID of the user who deleted the message>",
"displayName": "<name of the user, base64>"
}
}
```
## Message received
When user A receives a private message, or a message from a room that user A is in, the event `message` will be sent
to user A with the following content:
```json
{
"id": "<server-generated UUID>",
"published": "<server-generated timestamp, RFC3339 format>",
"actor": {
"id": "<UUID of the sender>",
"displayName": "<name of the sender>"
},
"verb": "send",
"target": {
"id": "<UUID of the room, or this user's UUID if private msg>",
"displayName": "<name of the room, or target user name if private msg>",
"objectType": "<room/private>"
},
"object": {
"content": "<the message body>",
"displayName": "<the name of the channel, or empty if private msg>",
"url": "<UUID of the channel for this room, or empty if private msg>"
}
}
```
## Message has been read
If user A sends a message to user B and user B invokes the `read` api to indicate the message has been read, user A
will receive a `gn_message_read` event with the following content:
```json
{
"id": "<server-generated UUID>",
"published": "<server-generated timestamp, RFC3339 format>",
"actor": {
"id": "<user id of the one sending the read receipt>"
},
"verb": "read",
"target": {
"id": "<uuid of the room the messages are all in>"
},
"object": {
"attachments": [
{"id": "<message1 uuid>"},
{"id": "<message2 uuid>"},
{"id": "<message3 uuid>"}
]
}
}
```
## Message has been delivered
If user A sends a message to user B and user B invokes the `received` api to indicate the message has been received,
user A will receive a `gn_message_received` event with the following content:
```json
{
"id": "<server-generated UUID>",
"published": "<server-generated timestamp, RFC3339 format>",
"actor": {
"id": "<user id of the one sending the read receipt>"
},
"verb": "received",
"target": {
"id": "<uuid of the room the messages are all in>"
},
"object": {
"attachments": [
{"id": "<message1 uuid>"},
{"id": "<message2 uuid>"},
{"id": "<message3 uuid>"}
]
}
}
```
## User info updated
When a user updates his/her user information (e.g. avatar, is streaming, age etc.), the event `gn_user_info_updated`
will be sent to either all rooms that the user is in, or a specific room that user chose to send to. The event looks
like this:
```json
{
"actor": {
"id": "997110",
"displayName": "YmF0bWFu"
},
"object": {
"attachments": [{
"content": "MA==",
"objectType": "streaming"
},{
"content": "MzU=",
"objectType": "age"
}],
"objectType": "userInfo"
},
"verb": "update",
"id": "<server-generated UUID>",
"published": "<server-generated timestamp, RFC3339 format>"
}
```
The `content` on each attachment is always base64 encoded. The `objectType` tells which field has been updated. Possible
values depends on implementation, but is usually same as what's returned for user info when joining a room (`gn_join`).
## Admin presence requested
When someone requests the presence of an admin in a room all users in the Admin room for that channel will receive an
event called `gn_admin_requested` containing the following:
```json
{
"id": "<server-generated UUID>",
"published": "<server-generated timestamp, RFC3339 format>",
"actor": {
"id": "<UUID of user requesting>",
"displayName": "<name of the user requesting>",,
"attachments": [
{
"content": "NDA=",
"objectType": "age"
},
{
"content": "aHR0cDovL3NvbWUtdXJsLnRsZC9mb28uanBn",
"objectType": "avatar"
}
]
},
"verb": "help",
"object": {
"content": "<base64 encoded message>"
},
"generator": {
"id": "<UUID of the room the help was requested for>",
"displayName": "<name of the room>"
},
"target": {
"id": "<UUID of the admin room>",
"displayName": "<base64 of the admin room name>"
}
}
```
## A room was removed
When a room is removed by an admin/owner an event called `gn_room_removed` will be sent to everyone on the server (to
keep the room list in sync on client side):
```json
{
"actor": {
"id": "<user ID who removed the room>",
"displayName": "<name of the user who removed the room, in base64>"
},
"target": {
"id": "<room uuid>",
"displayName": "<room name in base64>",
"objectType": "room"
},
"object": {
"content": "<an optional reason, in base64>"
},
"id": "c42ebf01-3d50-4f27-a345-4ed213be045d",
"published": "2016-10-07T10:45:34Z",
"verb": "removed"
}
```
## A room was renamed
When a room is renamed by an admin/owner an event called `gn_room_renamed` will be sent to everyone on the server (to
keep the room list in sync on client side):
```json
{
"actor": {
"id": "<user ID who renamed the room>",
"displayName": "<name of the user who renamed the room, in base64>"
},
"target": {
"id": "<room uuid>",
"displayName": "<NEW room name in base64>",
"objectType": "room"
},
"id": "c42ebf01-3d50-4f27-a345-4ed213be045d",
"published": "2016-10-07T10:45:34Z",
"verb": "renamed"
}
```
## Invitation received
When user B invites user A to join room X, the event `gn_invitation` will be sent to user A with the following content:
```json
{
"id": "<server-generated UUID>",
"published": "<server-generated timestamp, RFC3339 format>",
"actor": {
"id": "<UUID of user B>",
"displayName": "<name of user B>",,
"attachments": [
{
"content": "NDA=",
"objectType": "age"
},
{
"content": "aHR0cDovL3NvbWUtdXJsLnRsZC9mb28uanBn",
"objectType": "avatar"
}
]
},
"verb": "invite",
"object": {
"url": "<UUID of the channel for room X>",
"displayName": "<name of the channel for room X>"
},
"target": {
"id": "<UUID of the room>",
"displayName": "<name of the room>"
}
}
```
## Another user joins the room
If user A is in room X, and another user B joins room X, the server will send an event called `gn_user_joined` to user A
with the following content:
```json
{
"id": "<server-generated UUID>",
"published": "<server-generated timestamp, RFC3339 format>",
"actor": {
"id": "<user B's UUID>",
"displayName": "<name of user B>",
"content": "globalmod,moderator"
"image": {
"url": "<user B's image url>"
},
"attachments": [
{
"content": "NDA=",
"objectType": "age"
},
{
"content": "aHR0cDovL3NvbWUtdXJsLnRsZC9mb28uanBn",
"objectType": "avatar"
}
]
},
"target": {
"id": "<uuid of the room>",
"displayName": "<name of the room>"
},
"verb": "join"
}
```
The `actor.content` describes the roles this user has in this room, plus any global roles. Examples:
* `globalmod,moderator`
* `moderator`
* `superuser`
If no specific roles, the value will be blank.
## Another user leaves room
When user A is in room X, and another user B leaves room X, the sever will send an event called `gn_user_left` to user A
with the following content:
```json
{
"id": "<server-generated UUID>",
"published": "<server-generated timestamp, RFC3339 format>",
"actor": {
"id": "<user B's UUID>",
"displayName": "<name of user B>",
},
"target": {
"id": "<uuid of the room>",
"displayName": "<name of the room>"
},
"verb": "leave"
}
```
## Another user connects
When a user connects (or stops being invisible), the `gn_user_connected` event will be sent.
```json
{
"actor": {
"id": "<user B's UUID>",
"displayName": "<name of user B>",
"attachments": [
{
"content": "NDA=",
"objectType": "age"
},
{
"content": "aHR0cDovL3NvbWUtdXJsLnRsZC9mb28uanBn",
"objectType": "avatar"
}
]
},
"id": "<server-generated UUID>",
"published": "<server-generated timestamp, RFC3339 format>",
"verb": "connect"
}
```
## Another user disconnects
If user A is in any room that user B is in, and user B disconnects from the chat server, an event called
`gn_user_disconnected` will be sent to user A with the following content:
```json
{
"id": "<server-generated UUID>",
"published": "<server-generated timestamp, RFC3339 format>",
"actor": {
"id": "<user B's UUID>",
"displayName": "<name of user B>",
},
"verb": "disconnect"
}
```
## You were banned
If you are banned, either in a room, a channel or globally, you will receive the following event named `gn_banned`:
```json
{
"actor": {
"id": "<ID of the one who banned you>",
"displayName": "<username of the one who banned you, in base64>"
},
"object": {
"id": "<your user ID>",
"displayName": "<your username in base64>",
"summary": "30s",
"updated": "2017-02-15T09:11:52Z",
"content": "<the reason for the ban>"
},
"target": {
"id": "<room/channel uuid>",
"displayName": "<room/channel name, in base64>",
"objectType": "<room/channel/global>"
},
"verb": "ban",
"id": "<server-generated UUID>",
"published": "<server-generated timestamp, RFC3339 format>"
}
```
* target.id and target.displayName will not be present if target.objectType is "global",
* object.summary is the duration of the ban, e.g. 30s, 2h, 7d etc.,
* object.updated is the timestamp when the ban will expire, in UTC,
* object.content is the reason for the ban, but if no reason is given by the banned, this field will not be present.
## A new room is created
When a new room is created in a channel that user A is in, an event called `gn_room_created` will be sent to user A with
the following content:
```json
{
"id": "<server-generated UUID>",
"published": "<server-generated timestamp, RFC3339 format>",
"actor": {
"id": "<UUID of user who created the room>",
"displayName": "<name of the user who created the room>",,
"attachments": [
{
"content": "NDA=",
"objectType": "age"
},
{
"content": "aHR0cDovL3NvbWUtdXJsLnRsZC9mb28uanBn",
"objectType": "avatar"
}
]
},
"object": {
"url": "<UUID of the channel for this room>"
},
"target": {
"id": "<UUID of the new room>",
"displayName": "<name of the new room>",
"objectType": "temporary"
},
"verb": "create"
}
```
The `target.objectType` will always be `temporary` since all rooms created using the API are user created rooms, meaning
they will be automatically removed when the owner leaves.
## A user is kicked from a room
When a user is kicked from a room, an event will be sent to all users in that room (except the kicked user), called
`gn_user_kicked`, with the following content:
```json
{
"id": "<server-generated UUID>",
"published": "<server-generated timestamp, RFC3339 format>",
"actor": {
"id": "<UUID of the kicker>",
"displayName": "<name of the kicker>",
"attachments": [
{
"content": "NDA=",
"objectType": "age"
},
{
"content": "aHR0cDovL3NvbWUtdXJsLnRsZC9mb28uanBn",
"objectType": "avatar"
}
]
},
"object": {
"id": "<UUID of the kicked user>",
"displayName": "<name of the kicked user>",
"content": "<optional reason field>",
"attachments": [
{
"content": "NDA=",
"objectType": "age"
},
{
"content": "aHR0cDovL3NvbWUtdXJsLnRsZC9mb28uanBn",
"objectType": "avatar"
}
]
},
"target": {
"id": "<UUID of the room the user was kicked from>",
"displayName": "<name of the room the user was kicked from>"
},
"verb": "kick"
}
```
## Broadcast received
When a message is broadcasted to every user on the server, a `gn_broadcast` event is received:
```json
{
"actor": {
"displayName": "<admin in base64>",
"id": "0"
},
"content": "<base64>",
"verb": "broadcast",
"id": "<server-generated UUID>",
"published": "<server-generated timestamp, RFC3339 format>",
"provider": {
"id": "popp"
}
}
```
## A user is banned
TODO: currently the user will be banned, but the "kicked" event will be broadcasted to relevant users. There's currently
no "banned" event for this.
## User was muted
If a user is muted (using the REST API), the `gn_mute` event will be sent to the user. The `object.summary` field is
the remaining seconds.
Example event:
```json
["gn_mute", {
"actor": {
"id": "0",
"objectType": "user"
},
"verb": "mute",
"object": {
"id": "5000439",
"summary": "1m",
"updated": "2023-08-17T07:05:33Z",
"objectType": "user",
"content": ""
},
"target": {
"id": "2e7d537e-bed5-47c5-a7f6-357075759e5d",
"objectType": "room",
"displayName": ""
},
"published": "2023-08-17T07:04:33Z",
"id": "039bc358-1034-4f1d-b716-7d014fa4bad5"
}]
```
## User was un-muted
If a mute is removed for a user (using the REST API), the `gn_ummute` event will be sent to the user.
Example event:
```json
["gn_unmute", {
"actor": {
"id": "0",
"objectType": "user"
},
"verb": "unmute",
"object": {
"id": "5000439",
"objectType": "user"
},
"target": {
"objectType": "room",
"id": "2e7d537e-bed5-47c5-a7f6-357075759e5d",
"displayName": ""
},
"id": "c89dd0b0-3da0-4b24-9841-05adad714339",
"published": "2023-08-17T07:06:20Z"
}]
```