|
| 1 | +# MSC2476: User-defined ephemeral events in rooms |
| 2 | + |
| 3 | +Matrix currently handles the transfer of data in the form of Persistent- as well as Ephemeral Data |
| 4 | +Units, both of which follow the same general design in the way they're encoded and transferred over |
| 5 | +both the Client-Server and Server-Server API. |
| 6 | + |
| 7 | +Currently only users are only able to provide their own event types and data in the case of |
| 8 | +persistent data, in the form of state events as well as messages / timeline events. |
| 9 | +The sending of ephemeral data by clients - on the other hand - is currently limited to only typing |
| 10 | +notifications, event receipts, read markers, and presence updates. Which greatly limits the |
| 11 | +potential usefulness of ephemeral events as a general mechanism for transferring short-lived data. |
| 12 | + |
| 13 | +Therefore, this proposal suggest extending both the Client-Server and Server-Server APIs to allow |
| 14 | +users to transfer arbitrary ephemeral data types and content into rooms in which they have the right |
| 15 | +to do so. |
| 16 | + |
| 17 | + |
| 18 | +## Proposal |
| 19 | + |
| 20 | +The proposed change is to add support for users to provide their own data types and content, in a |
| 21 | +similar manner to the already existing support for users to send their own types of persistent data. |
| 22 | + |
| 23 | +Note though that this proposal does not include any support for sending user-defined ephemeral |
| 24 | +events which are not explicitly bound to rooms, like the global `m.presence` event. |
| 25 | + |
| 26 | +Examples of how this feature could be used are; as regular status updates to a user-requested |
| 27 | +long-lived task, which a bot might has started for a received event. Or pehaps as a GPS live-location |
| 28 | +feature, where participating client would regularly post their current location relative to a |
| 29 | +persistent geo-URI event. Perhaps for organizing meetups, or for viewing active tracking of the |
| 30 | +locations of vehicles in an autonomous fleet - along with peristent messages posted at a lesser |
| 31 | +rate for a timeline generation. |
| 32 | + |
| 33 | +The example that will be used througout this proposal is an ephemeral data object that's tracking |
| 34 | +the current status of a user-requested 3D print, with some basic printer- and print-status |
| 35 | +information being sent every few seconds to a control room, including a reference to the event that |
| 36 | +the status is referring to - which the client could use to render a progress bar or other graphic |
| 37 | +with. |
| 38 | + |
| 39 | +### Addition of an ephemeral event sending endpoint to the Client-Server API |
| 40 | + |
| 41 | +The suggested addition to the CS API is the endpoint |
| 42 | +`PUT /_matrix/client/r0/rooms/{roomId}/ephemeral/{eventType}/{txnId}`, which would act in an almost |
| 43 | +identical manner to the event sending endpoint that is already present. |
| 44 | +An example of how an update might be posted using the new endpoint; |
| 45 | + |
| 46 | +``` |
| 47 | +PUT /_matrix/client/r0/rooms/%21636q39766251%3Aexample.com/ephemeral/com.example.3dprint/19914 HTTP/1.1 |
| 48 | +Content-Type: application/json |
| 49 | +
|
| 50 | +{ |
| 51 | + "print_event_id": "$E2RPcyuMUiXyDkQ02ASEbFxcJ4wFNrt5JVgov0wrqWo", |
| 52 | + "printer_id": 10, |
| 53 | + "status": { |
| 54 | + "hotend_c": 181.4, |
| 55 | + "bed_c": 62.5, |
| 56 | + "position": [54, 275, 87.2] |
| 57 | + }, |
| 58 | + "time": { |
| 59 | + "elapsed": 4324, |
| 60 | + "estimated": 7439 |
| 61 | + } |
| 62 | +} |
| 63 | +``` |
| 64 | + |
| 65 | +Example of a response; |
| 66 | + |
| 67 | +Status code 200: |
| 68 | + |
| 69 | +```json |
| 70 | +{} |
| 71 | +``` |
| 72 | + |
| 73 | + |
| 74 | +**NB**; |
| 75 | +To reduce the risk of abuse, this endpoint is suggested to never allow sending any ephemeral data of |
| 76 | +any type matching the wildcard `m.*`, instead keeping the sending of those well-defined event types |
| 77 | +under their already existing endpoints. |
| 78 | + |
| 79 | +An error that could be returned for a user attempting to send such a blocked type is suggested as; |
| 80 | + |
| 81 | +Status code 403 |
| 82 | + |
| 83 | +```json |
| 84 | +{ |
| 85 | + "errcode": "M_FORBIDDEN", |
| 86 | + "error": "Cannot send this ephemeral type" |
| 87 | +} |
| 88 | +``` |
| 89 | + |
| 90 | +### Extension of power levels to handle user-defined ephemeral events |
| 91 | + |
| 92 | +As it would be possible for the user-defined events to be used to flood a room with invisible |
| 93 | +traffic by malicious users - increasing the bandwidth usage for all connected servers, this proposal |
| 94 | +also suggests extending the power levels to handle ephemeral types as well. |
| 95 | + |
| 96 | +The suggested keys to add to the `m.room.power_levels` events are as follows; |
| 97 | + |
| 98 | +- `ephemeral`, of type `{string: integer}` |
| 99 | +- `ephemeral_default`, of type `integer` |
| 100 | + |
| 101 | +These new keys are suggested to function in an identical manner to the already existing `events` and |
| 102 | +`events_default` keys, with the suggested default - and fallback - value for `ephemeral_default` |
| 103 | +being 50, while the suggested default - and fallback - values for `ephemeral` would be; |
| 104 | + |
| 105 | +```json |
| 106 | +{ |
| 107 | + "m.fully_read": 0, |
| 108 | + "m.receipt": 0, |
| 109 | + "m.typing": 0 |
| 110 | +} |
| 111 | +``` |
| 112 | + |
| 113 | +**NB**; |
| 114 | +To reduce the complexity of the change, this proposal suggests to - for the time being - only limit |
| 115 | +the user-defined types by these power levels changes. The default values for `m.*` specified here in |
| 116 | +`ephemeral_defaults` would then only be expected to be informational in purpose. |
| 117 | + |
| 118 | +### Extension of the ephemeral data received in /sync responses |
| 119 | + |
| 120 | +Because the user-defined ephemeral events can't be aggregated and massaged by Synapse in a simple |
| 121 | +manner, this then suggests instead adding a few more (**optional** but suggested for `m.*`, |
| 122 | +**required** otherwise) fields to the ephemeral events as they are encoded in a sync response. The |
| 123 | +suggested additions are; |
| 124 | + |
| 125 | +- `sender`, of type `string` |
| 126 | +- `origin_server_ts`, of type `integer` |
| 127 | + |
| 128 | +To reduce the risk of breaking existing clients, as well as reducing the scope of change required by |
| 129 | +this proposal, the suggestion is to leave the original `m.*` events unaltered for now - therefore |
| 130 | +the use of fields that can be both optional *as well as* required depending on the ephemeral type. |
| 131 | + |
| 132 | +```json |
| 133 | +{ |
| 134 | + "next_batch": "...", |
| 135 | + // ... |
| 136 | + "rooms": { |
| 137 | + "join": { |
| 138 | + "!636q39766251:example.com": { |
| 139 | + // ... |
| 140 | + "timeline": { |
| 141 | + "events": [ |
| 142 | + { |
| 143 | + "content": { |
| 144 | + "gcode": "mxc://example.com/GEnfasiifADESSAF", |
| 145 | + "printer": 10, |
| 146 | + }, |
| 147 | + "type": "com.example.3dprint_request", |
| 148 | + "event_id": "$4CvDieFIFAzSYaykmBObZ2iUhSa5XNEUnC-GQfLl2yc", |
| 149 | + "room_id": "!636q39766251:example.com", |
| 150 | + "sender": "@alice:matrix.org", |
| 151 | + "origin_server_ts": 1432735824653, |
| 152 | + "unsigned": { |
| 153 | + "age": 5558 |
| 154 | + } |
| 155 | + }, |
| 156 | + { |
| 157 | + "content": { |
| 158 | + "body": "Print of fan_shroud_v5.gcode started on printer 10, ETA is 2h. Stream is available at https://example.com/printers/10.m3u8", |
| 159 | + "print": { |
| 160 | + "gcode": "mxc://example.com/GEnfasiifADESSAF", |
| 161 | + "printer": 10, |
| 162 | + "video": "https://example.com/printers/10.m3u", |
| 163 | + "eta": 7253 |
| 164 | + }, |
| 165 | + "m.relates_to": { |
| 166 | + "m.in_reply_to": { |
| 167 | + "event_id": "$4CvDieFIFAzSYaykmBObZ2iUhSa5XNEUnC-GQfLl2yc" |
| 168 | + } |
| 169 | + }, |
| 170 | + "msgtype": "m.text" |
| 171 | + }, |
| 172 | + "origin_server_ts": 1432735825887, |
| 173 | + "sender": "@printbot:example.com", |
| 174 | + "type": "m.room.message", |
| 175 | + "unsigned": { |
| 176 | + "age": 4324 |
| 177 | + }, |
| 178 | + "event_id": "$E2RPcyuMUiXyDkQ02ASEbFxcJ4wFNrt5JVgov0wrqWo", |
| 179 | + "room_id": "" |
| 180 | + } |
| 181 | + ] |
| 182 | + }, |
| 183 | + "ephemeral": { |
| 184 | + "events": [ |
| 185 | + { |
| 186 | + "content": { |
| 187 | + "user_ids": [ |
| 188 | + "@alice:matrix.org", |
| 189 | + "@bob:example.com" |
| 190 | + ] |
| 191 | + }, |
| 192 | + "type": "m.typing", |
| 193 | + "room_id": "!636q39766251:example.com" |
| 194 | + }, |
| 195 | + { |
| 196 | + "content": { |
| 197 | + "print_event_id": "$E2RPcyuMUiXyDkQ02ASEbFxcJ4wFNrt5JVgov0wrqWo", |
| 198 | + "printer_id": 10, |
| 199 | + "status": { |
| 200 | + "hotend_c": 181.4, |
| 201 | + "bed_c": 62.5, |
| 202 | + "position": [54, 275, 87.2] |
| 203 | + }, |
| 204 | + "time": { |
| 205 | + "elapsed": 4324, |
| 206 | + "estimated": 7440 |
| 207 | + } |
| 208 | + }, |
| 209 | + "type": "com.example.3dprint", |
| 210 | + "room_id": "!636q39766251:example.com", |
| 211 | + "sender": "@printbot:example.com", |
| 212 | + "origin_server_ts": 1432735830211 |
| 213 | + } |
| 214 | + ] |
| 215 | + } |
| 216 | + } |
| 217 | + } |
| 218 | + } |
| 219 | +} |
| 220 | +``` |
| 221 | + |
| 222 | +### Extension of the Server-Server spec |
| 223 | + |
| 224 | +As the server-server protocol is currently only designed for transferring the well-defined EDUs that |
| 225 | +exist as part of the Matrix communication protocol, this proposal suggests adding additional fields |
| 226 | +to the EDU schema in order to let them transmit the user-specified data untouched - while still |
| 227 | +adding source information that is important for the receiving clients. |
| 228 | + |
| 229 | +The suggested (**optional** but suggested for `m.*`, **required** otherwise) fields to add to the |
| 230 | +EDU schema are; |
| 231 | + |
| 232 | +- `room_id`, of type `string` |
| 233 | +- `sender`, of type `string` |
| 234 | +- `origin`, of type `string` |
| 235 | +- `origin_server_ts`, of type `integer` |
| 236 | + |
| 237 | +A user-defined ephemeral event could then look like this when federated; |
| 238 | + |
| 239 | +```json |
| 240 | +{ |
| 241 | + "content": { |
| 242 | + "print_event_id": "$E2RPcyuMUiXyDkQ02ASEbFxcJ4wFNrt5JVgov0wrqWo" |
| 243 | + "printer_id": "10", |
| 244 | + "status": { |
| 245 | + "hotend_c": 181.4, |
| 246 | + "bed_c": 62.5, |
| 247 | + "position": [54, 275, 87.2] |
| 248 | + }, |
| 249 | + "time": { |
| 250 | + "elapsed": 4324, |
| 251 | + "estimated": 7440 |
| 252 | + } |
| 253 | + }, |
| 254 | + "room_id": "!636q39766251:example.com", |
| 255 | + "sender": "@printbot:example.com", |
| 256 | + "origin": "example.com", |
| 257 | + "origin_server_ts": 1432735830211, |
| 258 | + "edu_type": "com.example.3dprint" |
| 259 | +} |
| 260 | +``` |
| 261 | + |
| 262 | + |
| 263 | +## Potential issues |
| 264 | + |
| 265 | +Because this change completely redefines how ephemeral events are used, it is likely to be expected |
| 266 | +that some servers and clients could struggle to handle the new types of data that this proposal |
| 267 | +would create. But as the protocol is defined with an extensible transport - JSON, it should not be |
| 268 | +difficult - if even necessary - for clients or servers to be modified to support the changes. |
| 269 | + |
| 270 | +Additionally, as ephemeral data is never encoded into room state there's not as many tools for |
| 271 | +admins to handle abuse that occur through the use of the feature. |
| 272 | +The proposals suggested changes to power levels - and limitation of what event types can be sent - |
| 273 | +should mitigate the potential of abuse from the feature though, as long as admins don't allow any |
| 274 | +user-defined ephemeral types to be sent by regular users. |
| 275 | + |
| 276 | +This change could impact the - currently in review - [MSC2409], necessitating some kind of filter for |
| 277 | +what event types would be transferred to appservices. |
| 278 | + |
| 279 | + |
| 280 | +## Alternatives |
| 281 | + |
| 282 | +The ephemeral state that this change would allow to transfer could as easily be sent using |
| 283 | +self-destructing messages with the help of [MSC1763] or [MSC2228], which would result in a similar |
| 284 | +experience to the end user. |
| 285 | +Unfortunately using persistent events in such a manner would add a lot of unnecessary data to the |
| 286 | +room DAG, while also increasing both the computational work and the database pressure through the |
| 287 | +repeated and rapid insertions and redactions that it would result in. |
| 288 | + |
| 289 | +### Client-Server protocol changes |
| 290 | + |
| 291 | +The additions to ephemeral objects could be expanded to also apply to the normal `m.*` types as well, |
| 292 | +which would reduce the complexity of the spec as there would be no distinction between the built-in |
| 293 | +Matrix types as well as the user-defined types. |
| 294 | +This could cause some clients to break though, if they expect the well-defined objects to keep to |
| 295 | +their specced forms. |
| 296 | + |
| 297 | +### Server-Server protocol changes |
| 298 | + |
| 299 | +Instead of adding potentially optional keys to the EDU schema, the entire object could instead be |
| 300 | +embedded into the content key, using an EDU type key that denotes it as an user-defined type. |
| 301 | +This would mean a smaller change to the server-server communication, while still allowing a server |
| 302 | +module to filter or track events based on their types or origins. |
| 303 | + |
| 304 | +```json |
| 305 | +{ |
| 306 | + "content": { |
| 307 | + "room_id": "!636q39766251:example.com", |
| 308 | + "sender": "@printbot:example.com", |
| 309 | + "origin": "example.com", |
| 310 | + "origin_server_ts": 1432735830211, |
| 311 | + "type": "com.example.3dprint", |
| 312 | + "content": { |
| 313 | + "print_event_id": "$E2RPcyuMUiXyDkQ02ASEbFxcJ4wFNrt5JVgov0wrqWo", |
| 314 | + "printer_id": "10", |
| 315 | + "status": { |
| 316 | + "hotend_c": 181.4, |
| 317 | + "bed_c": 62.5, |
| 318 | + "position": [54, 275, 87.2] |
| 319 | + }, |
| 320 | + "time": { |
| 321 | + "elapsed": 4324, |
| 322 | + "estimated": 7440 |
| 323 | + } |
| 324 | + } |
| 325 | + }, |
| 326 | + "edu_type": "m.user_defined" |
| 327 | +} |
| 328 | +``` |
| 329 | + |
| 330 | +Possibly, the additional requirements for user-defined types could instead also be expanded to cover |
| 331 | +the regular Matrix types as well, which would remove the need for optional fields - but could in |
| 332 | +return impact the federation between servers, if they're built to only handle the exact requirements |
| 333 | +of the spec. |
| 334 | + |
| 335 | +[MSC1763]: https://github.com/matrix-org/matrix-doc/blob/matthew/msc1763/proposals/1763-configurable-retention-periods.md |
| 336 | +[MSC2228]: https://github.com/matrix-org/matrix-doc/tree/matthew/msc2228/proposals/2228-self-destructing-events.md |
| 337 | +[MSC2409]: https://github.com/Sorunome/matrix-doc/blob/soru%2Bhs/appservice-edus/proposals/2409-appservice-edus.md |
0 commit comments