|
| 1 | +# MSC2409: Proposal to send typing, presence and receipts to appservices |
| 2 | + |
| 3 | +*Note: This proposal is a continuation of [MSC1888](https://github.com/matrix-org/matrix-doc/pull/1888) |
| 4 | +and deprecates that one.* |
| 5 | + |
| 6 | +The [appservice /transactions API](https://spec.matrix.org/v1.11/application-service-api/#put_matrixappv1transactionstxnid) |
| 7 | +currently supports pushing PDU events (regular message and state events) |
| 8 | +however it doesn't provision for EDU events (typing, presence and receipts). This means that bridges cannot |
| 9 | +react to Matrix users who send any typing or presence information in a room the service is part of. |
| 10 | + |
| 11 | +There is an interest amongst the community to have equal bridging on both sides of a bridge, so that |
| 12 | +read reciepts and typing notifications can be seen on the remote side. To that end, this proposal |
| 13 | +specifies how these can be pushed to an appservice. |
| 14 | + |
| 15 | +## Proposal |
| 16 | + |
| 17 | +### Changes to the registration file |
| 18 | + |
| 19 | +In order that appservices don't get flooded with EDUs, appservices have to opt-in to receive them by |
| 20 | +setting `receive_ephemeral` to true. A registration file could look like following: |
| 21 | + |
| 22 | +```yaml |
| 23 | +id: "IRC Bridge" |
| 24 | +url: "http://127.0.0.1:1234" |
| 25 | +as_token: "30c05ae90a248a4188e620216fa72e349803310ec83e2a77b34fe90be6081f46" |
| 26 | +hs_token: "312df522183efd404ec1cd22d2ffa4bbc76a8c1ccf541dd692eef281356bb74e" |
| 27 | +sender_localpart: "_irc_bot" |
| 28 | +# We want to receive EDUs |
| 29 | +receive_ephemeral: true |
| 30 | +namespaces: |
| 31 | + users: |
| 32 | + - exclusive: true |
| 33 | + regex: "@_irc_bridge_.*" |
| 34 | + aliases: |
| 35 | + - exclusive: false |
| 36 | + regex: "#_irc_bridge_.*" |
| 37 | + rooms: [] |
| 38 | +``` |
| 39 | +
|
| 40 | +For now, receiving EDUs is all-or-nothing. A future MSC may add more granular |
| 41 | +filtering capabilities for appservices. |
| 42 | +
|
| 43 | +### Changes to the /transactions/ API |
| 44 | +
|
| 45 | +The `PUT /_matrix/app/v1/transactions/{txnId}` API currently supports sending PDUs |
| 46 | +via the `events` array. |
| 47 | + |
| 48 | +```json |
| 49 | +{ |
| 50 | + "events": [ |
| 51 | + { |
| 52 | + "content": { |
| 53 | + "membership": "join", |
| 54 | + "avatar_url": "mxc://domain.com/SEsfnsuifSDFSSEF#auto", |
| 55 | + "displayname": "Alice Margatroid" |
| 56 | + }, |
| 57 | + "type": "m.room.member", |
| 58 | + "event_id": "$143273582443PhrSn:domain.com", |
| 59 | + "room_id": "!jEsUZKDJdhlrceRyVU:domain.com", |
| 60 | + "sender": "@example:domain.com", |
| 61 | + "origin_server_ts": 1432735824653, |
| 62 | + "unsigned": { |
| 63 | + "age": 1234 |
| 64 | + }, |
| 65 | + "state_key": "@alice:domain.com" |
| 66 | + } |
| 67 | + ] |
| 68 | +} |
| 69 | +``` |
| 70 | + |
| 71 | +This proposal would extend the `PUT /_matrix/app/v1/transactions/` endpoint to include a new key |
| 72 | +`ephemeral` to behave similar to the various sections of the CS API `/sync` endpoint. The `ephemeral` key |
| 73 | +MAY be omitted entirely if there are no ephemeral events to send. |
| 74 | + |
| 75 | +```json |
| 76 | +{ |
| 77 | + "ephemeral": [ |
| 78 | + { |
| 79 | + "type": "m.typing", |
| 80 | + "room_id": "!jEsUZKDJdhlrceRyVU:domain.com", |
| 81 | + "content": { |
| 82 | + "user_ids": [ |
| 83 | + "@alice:example.com" |
| 84 | + ] |
| 85 | + } |
| 86 | + }, |
| 87 | + { |
| 88 | + "type": "m.receipt", |
| 89 | + "room_id": "!jEsUZKDJdhlrceRyVU:domain.com", |
| 90 | + "content": { |
| 91 | + "$1435641916114394fHBLK:matrix.org": { |
| 92 | + "m.read": { |
| 93 | + "@rikj:jki.re": { |
| 94 | + "ts": 1436451550453 |
| 95 | + } |
| 96 | + } |
| 97 | + } |
| 98 | + } |
| 99 | + } |
| 100 | + ], |
| 101 | + "events": [ |
| 102 | + // ... |
| 103 | + ] |
| 104 | +} |
| 105 | +``` |
| 106 | + |
| 107 | +The reason for a new key rather than bundling the events into `events` is that |
| 108 | +existing appservices may mistake them for PDUs and might behave erratically. |
| 109 | +While `events` may now be a somewhat misleading name, this is an acceptable tradeoff. |
| 110 | + |
| 111 | +The array is effectively a combination of the `presence` and `ephemeral` sections of the |
| 112 | +client-server `/sync` API. User-defined ephemeral events don't exist yet, which means there are |
| 113 | +only three event types that can currently occur: |
| 114 | +[`m.presence`](https://spec.matrix.org/v1.11/client-server-api/#mpresence), |
| 115 | +[`m.typing`](https://spec.matrix.org/v1.11/client-server-api/#mtyping), |
| 116 | +and [`m.receipt`](https://spec.matrix.org/v1.11/client-server-api/#mreceipt). |
| 117 | + |
| 118 | +This proposal does not cover any other types of events which are sent as EDUs in the federation API, |
| 119 | +such as to-device events or other e2ee features. Those are left to a separate MSC. |
| 120 | + |
| 121 | +EDUs are formatted the same way as they are in C-S sync, with the addition of the `room_id` field |
| 122 | +for room-scoped EDUs (`m.typing` and `m.receipt`). `room_id` is not present in the C-S API because |
| 123 | +sync nests EDUs inside a room object, but appservices get a flat list of events in all rooms. |
| 124 | + |
| 125 | +### Expectations of when an EDU should be pushed to an appservice |
| 126 | + |
| 127 | +It is not clear at face value what should be pushed to an appservice. Appservices claim |
| 128 | +namespaces of users which registers "interest" in the rooms where those users reside, as |
| 129 | +well as claiming namespaces of rooms for explicit interest. However, not all EDUs are |
| 130 | +associated with a single room (presence, etc). |
| 131 | + |
| 132 | +If the EDU is capable of being associated to a particular room (i.e. `m.typing` and `m.receipt`), |
| 133 | +it should be sent to the appservice under the same rules as regular events (interest in the room |
| 134 | +means sending it). For EDUs which are not associated with a particular room, the appservice |
| 135 | +receives the EDU if it contextually *would* apply. For example, a presence update for a user an |
| 136 | +appservice shares a room with (or is under the appservice's namespace) would be sent to the |
| 137 | +appservice. |
| 138 | + |
| 139 | +For `m.receipt`, private read receipts (`m.read.private`) should only be sent for users within the |
| 140 | +appservice's namespaces. Normal read receipts and threaded read receipts are always sent. |
| 141 | + |
| 142 | +## Potential issues |
| 143 | + |
| 144 | +Determining which EDUs to transmit to the appservice could lead to quite some overhead on the |
| 145 | +homeserver side. Additionally, more network traffic is produced, potentially straining the local |
| 146 | +network and the appservice more. As such, appservices have to opt-in to receive EDUs. |
| 147 | + |
| 148 | +## Security considerations |
| 149 | + |
| 150 | +The homeserver needs to accurately determine which EDUs to send to the appservice, as to not leak |
| 151 | +any unnecessary metadata about users. Particularly `m.presence` could be tricky, as no `room_id` is present in |
| 152 | +that EDU. |
| 153 | + |
| 154 | +## Unstable prefix |
| 155 | + |
| 156 | +In the transaction body, instead of `ephemeral`, `de.sorunome.msc2409.ephemeral` is used. |
| 157 | + |
| 158 | +In the registration file, instead of `receive_ephemeral`, `de.sorunome.msc2409.push_ephemeral` is used. |
0 commit comments