summaryrefslogtreecommitdiff
path: root/docs/api/events.md
blob: 7fc7d783f2981ae881804fbffd6669ed0883bce0 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
# Events

```mermaid
---
Events flow through it
---
sequenceDiagram
	actor Andrea
	participant API
	actor Blake

	Note over Andrea,Blake: Subscribing to events

	Andrea ->> API : Subscribe
	Blake ->> API : Subscribe

	Note over Andrea,Blake: Sending a message

	Andrea ->>+ API : Send "hello, world!"
	API -->>- Andrea : Accepted

	Note over Andrea,Blake: Receiving events

	par
	API --) Andrea : Andrea sent "hello, world!"
	and
	API --) Blake : Andrea sent "hello, world!"
	end
```

The core of the service is to facilitate conversations between users. Conversational activity is delivered to clients using
_events_. Each event notifies interested clients of activity sent to the service through its API.


## Asynchronous completion

A number of endpoints return
`202 Accepted` responses. The actions performed by those endpoints will be completed before events are delivered. To await the completion of an operation which returns this response, clients must monitor the event stream for the corresponding event.


## `GET /api/events`

Subscribes to events.

This endpoint is designed for use with the [EventSource] DOM API, and supports several features of that API, as described below. Other clients may implement these features for themselves.

[EventSource]: https://developer.mozilla.org/en-US/docs/Web/API/EventSource

### Query parameters

This endpoint requires a
`resume_point` (integer) query parameter. The event stream will collect events published after that point in time. The value must be obtained by calling the [
`GET /api/boot`](./boot.md) method.

### Request headers

This endpoint accepts an optional `last-event-id` (string) header. If present, the value must be the value of the
`id` field of the last message processed by the client. The returned event stream will begin with the following message. If absent, the returned event stream will begin from the start of the event collection.

This header is set automatically by `EventSource` when reconnecting to an event stream.

### Success

This endpoint will respond with a status of `200 Okay` when successful. The body of the response is an [event stream]:

[event stream]: https://developer.mozilla.org/en-US/docs/Web/API/Server-sent_events/Using_server-sent_events#event_stream_format

```
id: 1234
data: {
data:   "type": "message",
data:   "event": "sent",
data:   "at": "2024-09-27T23:19:10.208147Z",
data:   "channel": "C9876cyyz",
data:   "sender": "U1234abcd",
data:   "id": "M1312acab",
data:   "body": "beep"
data: }
```

The service will keep the connection open, and will deliver events as they occur.

The service may terminate the connection at any time. Clients should reconnect and resume the stream, using the
`last-event-id` header to resume from the last message received. The
`id` of each event is an ephemeral ID, useful only for this purpose.

Each event's `data` consists of a JSON object describing one event. Every event includes the following fields:

| Field   | Type             | Description                                                                                                  |
|:--------|:-----------------|:-------------------------------------------------------------------------------------------------------------|
| `type`  | string           | The type of entity the event describes. Will be one of the types listed in the next section.                 |
| `event` | string, optional | The specific kind of event. Will be one of the events listed with the associated `type` in the next section. |

The remaining fields depend on the `type` and (if present) the `event` field.


## Heartbeat events

```json
{
  "type": "heartbeat"
}
```

To help clients detect network interruptions, the service guarantees that it will deliver an event after a fixed interval called the "heartbeat interval." The specific interval length is given in seconds as part of the [boot response](./boot.md). If the service determines that the heartbeat interval is close to expiring, it will synthesize and deliver a heartbeat event.

Clients should treat any period of time without events, longer than the heartbeat interval, as an indication that the event stream may have been interrupted. Clients may also use other techniques, such as [browser APIs](https://developer.mozilla.org/en-US/docs/Web/API/EventSource/error_event), to detect this condition and restart the connection.

These events have the `type` field set to `"heartbeat"`. The `event` field is absent.


## User events

The following events describe changes to users.

These events have the `type` field set to `"user"`.

### User created

```json
{
  "type": "user",
  "event": "created",
  "at": "2024-09-27T23:17:10.208147Z",
  "id": "U1234abcd",
  "name": "example username"
}
```

Sent whenever a new user is created.

These events have the `event` field set to `"created"`. They include the following additional fields:

| Field  | Type      | Description                                                                                                                                        |
|:-------|:----------|:---------------------------------------------------------------------------------------------------------------------------------------------------|
| `at`   | timestamp | The moment the user was created.                                                                                                                   |
| `id`   | string    | A unique identifier for the newly-created user. This can be used to associate the user with other events, or to make API calls targeting the user. |
| `name` | string    | The user's name.                                                                                                                                   |

## Channel events

The following events describe changes to [channels](./channels-messages.md).

These events have the `type` field set to `"channel"`.

### Channel created

```json
{
  "type": "channel",
  "event": "created",
  "at": "2024-09-27T23:18:10.208147Z",
  "id": "C9876cyyz",
  "name": "example channel 2"
}
```

Sent whenever a new channel is created.

These events have the `event` field set to `"created"`. They include the following additional fields:

| Field        | Type                | Description                                                                                                                                                 |
|:-------------|:--------------------|:------------------------------------------------------------------------------------------------------------------------------------------------------------|
| `at`         | timestamp           | The moment the channel was created.                                                                                                                         |
| `id`         | string              | A unique identifier for the newly-created channel. This can be used to associate the channel with other events, or to make API calls targeting the channel. |
| `name`       | string              | The channel's name.                                                                                                                                         |
| `deleted_at` | timestamp, optional | If set, the moment the channel was deleted.                                                                                                                 |

When a channel is deleted or expires, the `"created"` event is replaced with a tombstone
`"created"` event, so that the original channel cannot be trivially recovered from the event stream. Tombstone events have a
`deleted_at` field, and a `name` of `""`. Tombstone events for channels use an empty string as the name, and not
`null` or with the `name` field removed entirely, to simplify client development. While clients
_should_ treat deleted channels specially, for example by rendering them as "channel deleted" markers, they don't have to be - they make sense if interpreted as channels with empty names, too.

Once a deleted channel is [purged](./channels-messages.md#expiry-and-purging), these tombstone events are removed from the event stream.

### Channel deleted

```json
{
  "type": "channel",
  "event": "deleted",
  "at": "2024-09-28T03:40:25.384318Z",
  "id": "C9876cyyz"
}
```

Sent whenever a channel is deleted or expires.

These events have the `event` field set to `"deleted"`. They include the following additional fields:

| Field | Type      | Description                         |
|:------|:----------|:------------------------------------|
| `at`  | timestamp | The moment the channel was deleted. |
| `id`  | string    | The deleted channel's ID.           |

## Message events

The following events describe changes to [messages](./channels-messages.md).

These events have the `type` field set to `"message"`.

### Message sent

```json
{
  "type": "message",
  "event": "sent",
  "at": "2024-09-27T23:19:10.208147Z",
  "channel": "C9876cyyz",
  "sender": "U1234abcd",
  "id": "M1312acab",
  "body": "an effusive blob of prose, condensed down to a single string"
}
```

Sent whenever a message is sent by a client.

These events have the `event` field set to `"sent"`. They include the following additional fields:

| Field        | Type                | Description                                                                                                                                   |
|:-------------|:--------------------|:----------------------------------------------------------------------------------------------------------------------------------------------|
| `at`         | timestamp           | The moment the message was sent.                                                                                                              |
| `channel`    | string              | The ID of the channel the message was sent to.                                                                                                |
| `sender`     | string              | The ID of the user that sent the message.                                                                                                     |
| `id`         | string              | A unique identifier for the message. This can be used to associate the message with other events, or to make API calls targeting the message. |
| `body`       | string              | The text of the message.                                                                                                                      |
| `deleted_at` | timestamp, optional | If set, the moment the message was deleted.                                                                                                   |

When a message is deleted or expires, the `"sent"` event is replaced with a tombstone
`"sent"` event, so that the original message cannot be trivially recovered from the event stream. Tombstone events have a
`deleted_at` field, and a `body` of `""`. Tombstone events for messages use an empty string as the `body`, and not
`null` or with the `body` field removed entirely, to simplify client development. While clients
_should_ treat deleted messages specially, for example by rendering them as "message deleted" markers, they don't have to be - they make sense if interpreted as messages with empty bodies, too.

Once a deleted message is [purged](./channels-messages.md#expiry-and-purging), these tombstone events are removed from the event stream.

### Message deleted

```json
{
  "type": "message",
  "event": "deleted",
  "at": "2024-09-28T02:44:27.077355Z",
  "id": "M1312acab"
}
```

Sent whenever a message is deleted or expires.

These events have the `event` field set to `"deleted"`. They include the following additional fields:

| Field | Type      | Description                         |
|:------|:----------|:------------------------------------|
| `at`  | timestamp | The moment the message was deleted. |
| `id`  | string    | The deleted message's ID.           |