-
Notifications
You must be signed in to change notification settings - Fork 413
MSC2946: Spaces Summary #2946
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
MSC2946: Spaces Summary #2946
Changes from 27 commits
059f324
14eb56c
aea5336
7618ed6
6e051d5
619c100
104cf78
8f6fb9d
200147c
f2457cf
1430661
09b0848
7b2f3dc
6224859
211e5e6
725277e
0fd8d8d
dee9040
a3b62a8
f28ad9b
d911c82
74f12d5
8b1fe00
8fdbfb1
f145fa3
f9c00a5
9c2e85a
760cda8
a5ad9a4
4c10e02
ad5af4d
dba41f9
8a968eb
b379c42
27f526c
c142433
af8c7b0
bcde9e0
328ae81
518db51
3b0051f
5cd8270
797dda4
105fd93
a7a08eb
094de30
c0a63ab
3d7769f
5627721
7d0c8f6
420d698
5cd0db4
14bdc42
00d3d67
e39eac3
6823998
5a5a404
0174348
545ff90
42ba46e
dee3b2d
a9803c3
e9592ff
8978562
622f8ed
6ad9ead
482597e
41bfaa5
f6f41b1
828c076
7fd45e5
902a124
bf5f84d
b43333a
c74adf7
fe5a9a7
a9f6cf6
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,215 @@ | ||
| ## MSC2946: Spaces Summary | ||
|
|
||
| This MSC depends on [MSC1772](https://github.com/matrix-org/matrix-doc/pull/1772), which | ||
| describes why a Space is useful: | ||
|
|
||
| > Collecting rooms together into groups is useful for a number of purposes. Examples include: | ||
| > | ||
| > * Allowing users to discover different rooms related to a particular topic: for example "official matrix.org rooms". | ||
| > * Allowing administrators to manage permissions across a number of rooms: for example "a new employee has joined my company and needs access to all of our rooms". | ||
| > * Letting users classify their rooms: for example, separating "work" from "personal" rooms. | ||
| > | ||
| > We refer to such collections of rooms as "spaces". | ||
|
|
||
| This MSC attempts to solve how a member of a space discovers rooms in that space. This | ||
| is useful for quickly exposing a user to many aspects of an entire community, using the | ||
| examples above, joining the "official matrix.org rooms" space might suggest joining a few | ||
| rooms: | ||
|
|
||
| * A room to discuss development of the Matrix Spec. | ||
| * An announcements room for news related to matrix.org. | ||
| * An off-topic room for members of the space. | ||
|
|
||
| ## Proposal | ||
|
|
||
| A new client-server API (and corresponding server-server API) is added which allows | ||
| for querying for the rooms and spaces contained within a space. This allows a client | ||
| to efficiently display a hierarchy of rooms to a user (i.e. without having | ||
| to walk the full state of the space). | ||
|
|
||
| ### Client-server API | ||
|
|
||
| An endpoint is provided to walk the space tree, starting at the provided room ID | ||
| ("the root room"), and visiting other rooms/spaces found via `m.space.child` | ||
| events. It recurses into the children and into their children, etc. | ||
|
|
||
| Example request: | ||
|
|
||
| ```jsonc | ||
| POST /_matrix/client/r0/rooms/{roomID}/spaces | ||
richvdh marked this conversation as resolved.
Outdated
Show resolved
Hide resolved
clokep marked this conversation as resolved.
Outdated
Show resolved
Hide resolved
clokep marked this conversation as resolved.
Outdated
Show resolved
Hide resolved
|
||
|
|
||
clokep marked this conversation as resolved.
Show resolved
Hide resolved
|
||
| { | ||
| "max_rooms_per_space": 5, | ||
| "suggested_only": true | ||
| } | ||
| ``` | ||
|
|
||
| or: | ||
|
|
||
| ```text | ||
| GET /_matrix/client/r0/rooms/{roomID}/spaces? | ||
| max_rooms_per_space=5& | ||
| suggested_only=true | ||
| ``` | ||
|
|
||
| Example response: | ||
clokep marked this conversation as resolved.
Outdated
Show resolved
Hide resolved
|
||
|
|
||
| ```jsonc | ||
| { | ||
| "rooms": [ | ||
| { | ||
| "room_id": "!ol19s:bleecker.street", | ||
| "avatar_url": "mxc://bleecker.street/CHEDDARandBRIE", | ||
| "guest_can_join": false, | ||
| "name": "CHEESE", | ||
| "num_joined_members": 37, | ||
| "topic": "Tasty tasty cheese", | ||
| "world_readable": true, | ||
| "creation_ts": 1432735824653, | ||
| "room_type": "m.space" | ||
| }, | ||
| { ... } | ||
| ], | ||
| "events": [ | ||
richvdh marked this conversation as resolved.
Outdated
Show resolved
Hide resolved
|
||
| { | ||
| "type": "m.space.child", | ||
| "state_key": "!efgh:example.com", | ||
| "content": { | ||
| "via": ["example.com"], | ||
| "suggested": true | ||
| }, | ||
| "room_id": "!ol19s:bleecker.street", | ||
| "sender": "@alice:bleecker.street" | ||
| }, | ||
| { ... } | ||
| ] | ||
| } | ||
| ``` | ||
|
|
||
| Request params: | ||
|
|
||
| * **`suggested_only`**: Optional. If `true`, return only child events and rooms where the | ||
| `m.space.child` event has `suggested: true`. Defaults to `false`. | ||
|
|
||
| For the POST request, must be a boolean. For GET, must be either `true` or `false`, | ||
| case-sensitive. | ||
clokep marked this conversation as resolved.
Outdated
Show resolved
Hide resolved
|
||
| * **`max_rooms_per_space`**: Optional: a client-defined limit to the maximum | ||
| number of children to return per space. Doesn't apply to the root space (ie, | ||
| the `room_id` in the request). | ||
|
|
||
| Server implementations may also have an internal limit (recommended as 50) | ||
| (which *does* apply to the root room); attempts to exceed this limit are | ||
clokep marked this conversation as resolved.
Outdated
Show resolved
Hide resolved
|
||
| ignored. Must be a non-negative integer. | ||
|
|
||
| Response fields: | ||
|
|
||
| * **`rooms`**: for each room/space, starting with the root room, a | ||
| summary of that room. The fields are the same as those returned by | ||
| `/publicRooms` (see | ||
| [spec](https://matrix.org/docs/spec/client_server/r0.6.0#post-matrix-client-r0-publicrooms)), | ||
| with the addition of: | ||
| * **`room_type`**: the value of the `m.type` field from the | ||
| room's `m.room.create` event, if any. | ||
clokep marked this conversation as resolved.
Outdated
Show resolved
Hide resolved
|
||
| * **`creation_ts`**: the value of the `origin_server_ts` field from the | ||
| room's `m.room.create` event. This is required for sorting of rooms as specified | ||
| in [MSC1772](https://github.com/matrix-org/matrix-doc/pull/1772). | ||
| * **`events`**: `m.space.child` events of the returned rooms. For each event, only the | ||
|
||
| following fields are returned: `type`, `state_key`, `content`, `room_id`, | ||
| `sender`. | ||
clokep marked this conversation as resolved.
Outdated
Show resolved
Hide resolved
|
||
|
|
||
clokep marked this conversation as resolved.
Outdated
Show resolved
Hide resolved
|
||
| #### Algorithm | ||
|
|
||
| 1. Start at the "root" room (the provided room ID). | ||
| 2. Generate a summary and add it to `rooms`. | ||
| 3. Add any `m.space.child` events in the room to `events`. | ||
| 4. Recurse into the targets of the `m.space.child` events, generate a summary for | ||
| each room and add it to `rooms`, also add any `m.space.child` events of the room | ||
| to `events`. | ||
| 5. Recurse into grandchildren, etc. until either all discovered rooms have been | ||
| inspected, or the server-side limit on the number of rooms is reached. | ||
clokep marked this conversation as resolved.
Outdated
Show resolved
Hide resolved
|
||
|
|
||
| Other notes: | ||
|
|
||
| * If the user doesn't have permission to view/peek the root room (including if | ||
| that room does not exist), a 403 error is returned with `M_FORBIDDEN`. Any | ||
| inaccessible children are simply omitted from the result (though the `m.space.child` | ||
| events that point to them are still returned). | ||
| * There could be loops in the returned child events - clients should handle this | ||
| gracefully. | ||
| * Similarly, note that a child room might appear multiple times (e.g. also be a | ||
| grandchild). | ||
| * `suggested_only` applies transitively. | ||
|
|
||
| For example, if a space A has child space B which is *not* suggested, and space | ||
| B has suggested child room C, and the client makes a summary request for A with | ||
| `suggested_only=true`, neither B **nor** C will be returned. | ||
|
|
||
| Similarly, if a space A has child space B which is suggested, and space B has | ||
| suggested child room C which is suggested, and the client makes a summary request | ||
| for A with `suggested_only=true`, both B and C will be returned. | ||
| * The current implementation doesn't honour `order` fields in child events, as | ||
| suggested in [MSC1772](https://github.com/matrix-org/matrix-doc/pull/1772). | ||
clokep marked this conversation as resolved.
Outdated
Show resolved
Hide resolved
|
||
| * `m.space.child` with an invalid `via` (invalid is defined as missing, not an | ||
| array or an empty array) are ignored. | ||
|
|
||
| ### Server-server API | ||
clokep marked this conversation as resolved.
Outdated
Show resolved
Hide resolved
|
||
|
|
||
| Much the same interface as the Client-Server API. | ||
|
|
||
| Example request: | ||
|
|
||
| ```jsonc | ||
| POST /_matrix/federation/v1/spaces/{roomID} | ||
clokep marked this conversation as resolved.
Outdated
Show resolved
Hide resolved
|
||
| { | ||
| "exclude_rooms": ["!a:b", "!b:c"], | ||
| "max_rooms_per_space": 5, | ||
| "suggested_only": true | ||
| } | ||
| ``` | ||
|
|
||
| The response has the same shape as the Client-Server API. | ||
clokep marked this conversation as resolved.
Outdated
Show resolved
Hide resolved
|
||
|
|
||
| Request params are the same as the Client-Server API, with the addition of: | ||
|
|
||
| * **`exclude_rooms`**: Optional. A list of room IDs that can be omitted | ||
| from the response. | ||
|
|
||
| This is largely the same as the Client-Server API, but differences are: | ||
|
|
||
| * The calling server can specify a list of spaces/rooms to omit from the | ||
| response (via `exclude_rooms`). | ||
| * `max_rooms_per_space` applies to the root room as well as any returned | ||
| children. | ||
| * If the target server is not a member of any discovered children (so | ||
| would have to send another request over federation to inspect them), no | ||
| attempt is made to recurse into them - they are simply omitted from the | ||
| response. | ||
| * If the target server is not a member of the root room, an empty | ||
| response is returned. | ||
| * Currently, no consideration is given to room membership: the spaces/rooms | ||
| must be world-readable (ie, peekable) for them to appear in the results. | ||
|
|
||
| ## Potential issues | ||
|
|
||
| To reduce complexity, only a limited number of rooms are returned for a room, | ||
| no effort is made to paginate the results. Proper pagination is left to a future | ||
| MSC. | ||
clokep marked this conversation as resolved.
Outdated
Show resolved
Hide resolved
|
||
|
|
||
| ## Alternatives | ||
|
|
||
| An initial version of this followed both `m.space.child` and `m.space.parent` events, | ||
| but this is unnecessary to provide the expected user experience. | ||
|
|
||
| ## Security considerations | ||
|
|
||
| None. | ||
clokep marked this conversation as resolved.
Outdated
Show resolved
Hide resolved
|
||
|
|
||
| ## Unstable prefix | ||
|
|
||
| During development of this feature it will be available at unstable endpoints. | ||
|
|
||
| The client-server API will be: | ||
| `/_matrix/client/unstable/org.matrix.msc2946/rooms/{roomID}/spaces` | ||
|
|
||
| The server-server API will be: | ||
| `/_matrix/federation/unstable/org.matrix.msc2946/spaces/{roomID}` | ||
Uh oh!
There was an error while loading. Please reload this page.