diff --git a/changelog.d/13208.feature b/changelog.d/13208.feature
new file mode 100644
index 0000000000..b0c5f090ee
--- /dev/null
+++ b/changelog.d/13208.feature
@@ -0,0 +1 @@
+Add a `room_type` field in the responses for the list room and room details admin API. Contributed by @andrewdoh.
\ No newline at end of file
diff --git a/docs/admin_api/rooms.md b/docs/admin_api/rooms.md
index d4873f9490..9aa489e4a3 100644
--- a/docs/admin_api/rooms.md
+++ b/docs/admin_api/rooms.md
@@ -59,6 +59,7 @@ The following fields are possible in the JSON response body:
- `guest_access` - Whether guests can join the room. One of: ["can_join", "forbidden"].
- `history_visibility` - Who can see the room history. One of: ["invited", "joined", "shared", "world_readable"].
- `state_events` - Total number of state_events of a room. Complexity of the room.
+ - `room_type` - The type of the room taken from the room's creation event; for example "m.space" if the room is a space. If the room does not define a type, the value will be `null`.
* `offset` - The current pagination offset in rooms. This parameter should be
used instead of `next_token` for room offset as `next_token` is
not intended to be parsed.
@@ -101,7 +102,8 @@ A response body like the following is returned:
"join_rules": "invite",
"guest_access": null,
"history_visibility": "shared",
- "state_events": 93534
+ "state_events": 93534,
+ "room_type": "m.space"
},
... (8 hidden items) ...
{
@@ -118,7 +120,8 @@ A response body like the following is returned:
"join_rules": "invite",
"guest_access": null,
"history_visibility": "shared",
- "state_events": 8345
+ "state_events": 8345,
+ "room_type": null
}
],
"offset": 0,
@@ -151,7 +154,8 @@ A response body like the following is returned:
"join_rules": "invite",
"guest_access": null,
"history_visibility": "shared",
- "state_events": 8
+ "state_events": 8,
+ "room_type": null
}
],
"offset": 0,
@@ -184,7 +188,8 @@ A response body like the following is returned:
"join_rules": "invite",
"guest_access": null,
"history_visibility": "shared",
- "state_events": 93534
+ "state_events": 93534,
+ "room_type": null
},
... (98 hidden items) ...
{
@@ -201,7 +206,8 @@ A response body like the following is returned:
"join_rules": "invite",
"guest_access": null,
"history_visibility": "shared",
- "state_events": 8345
+ "state_events": 8345,
+ "room_type": "m.space"
}
],
"offset": 0,
@@ -238,7 +244,9 @@ A response body like the following is returned:
"join_rules": "invite",
"guest_access": null,
"history_visibility": "shared",
- "state_events": 93534
+ "state_events": 93534,
+ "room_type": "m.space"
+
},
... (48 hidden items) ...
{
@@ -255,7 +263,9 @@ A response body like the following is returned:
"join_rules": "invite",
"guest_access": null,
"history_visibility": "shared",
- "state_events": 8345
+ "state_events": 8345,
+ "room_type": null
+
}
],
"offset": 100,
@@ -290,6 +300,8 @@ The following fields are possible in the JSON response body:
* `guest_access` - Whether guests can join the room. One of: ["can_join", "forbidden"].
* `history_visibility` - Who can see the room history. One of: ["invited", "joined", "shared", "world_readable"].
* `state_events` - Total number of state_events of a room. Complexity of the room.
+* `room_type` - The type of the room taken from the room's creation event; for example "m.space" if the room is a space.
+ If the room does not define a type, the value will be `null`.
The API is:
@@ -317,7 +329,8 @@ A response body like the following is returned:
"join_rules": "invite",
"guest_access": null,
"history_visibility": "shared",
- "state_events": 93534
+ "state_events": 93534,
+ "room_type": "m.space"
}
```
diff --git a/synapse/storage/databases/main/room.py b/synapse/storage/databases/main/room.py
index 13d6a1d5c0..d6d485507b 100644
--- a/synapse/storage/databases/main/room.py
+++ b/synapse/storage/databases/main/room.py
@@ -175,7 +175,7 @@ class RoomWorkerStore(CacheInvalidationWorkerStore):
rooms.creator, state.encryption, state.is_federatable AS federatable,
rooms.is_public AS public, state.join_rules, state.guest_access,
state.history_visibility, curr.current_state_events AS state_events,
- state.avatar, state.topic
+ state.avatar, state.topic, state.room_type
FROM rooms
LEFT JOIN room_stats_state state USING (room_id)
LEFT JOIN room_stats_current curr USING (room_id)
@@ -596,7 +596,8 @@ class RoomWorkerStore(CacheInvalidationWorkerStore):
SELECT state.room_id, state.name, state.canonical_alias, curr.joined_members,
curr.local_users_in_room, rooms.room_version, rooms.creator,
state.encryption, state.is_federatable, rooms.is_public, state.join_rules,
- state.guest_access, state.history_visibility, curr.current_state_events
+ state.guest_access, state.history_visibility, curr.current_state_events,
+ state.room_type
FROM room_stats_state state
INNER JOIN room_stats_current curr USING (room_id)
INNER JOIN rooms USING (room_id)
@@ -646,6 +647,7 @@ class RoomWorkerStore(CacheInvalidationWorkerStore):
"guest_access": room[11],
"history_visibility": room[12],
"state_events": room[13],
+ "room_type": room[14],
}
)
diff --git a/tests/rest/admin/test_room.py b/tests/rest/admin/test_room.py
index 230dc76f72..2526136ff8 100644
--- a/tests/rest/admin/test_room.py
+++ b/tests/rest/admin/test_room.py
@@ -21,7 +21,7 @@ from parameterized import parameterized
from twisted.test.proto_helpers import MemoryReactor
import synapse.rest.admin
-from synapse.api.constants import EventTypes, Membership
+from synapse.api.constants import EventTypes, Membership, RoomTypes
from synapse.api.errors import Codes
from synapse.handlers.pagination import PaginationHandler
from synapse.rest.client import directory, events, login, room
@@ -1130,6 +1130,8 @@ class RoomTestCase(unittest.HomeserverTestCase):
self.assertIn("guest_access", r)
self.assertIn("history_visibility", r)
self.assertIn("state_events", r)
+ self.assertIn("room_type", r)
+ self.assertIsNone(r["room_type"])
# Check that the correct number of total rooms was returned
self.assertEqual(channel.json_body["total_rooms"], total_rooms)
@@ -1229,7 +1231,11 @@ class RoomTestCase(unittest.HomeserverTestCase):
def test_correct_room_attributes(self) -> None:
"""Test the correct attributes for a room are returned"""
# Create a test room
- room_id = self.helper.create_room_as(self.admin_user, tok=self.admin_user_tok)
+ room_id = self.helper.create_room_as(
+ self.admin_user,
+ tok=self.admin_user_tok,
+ extra_content={"creation_content": {"type": RoomTypes.SPACE}},
+ )
test_alias = "#test:test"
test_room_name = "something"
@@ -1306,6 +1312,7 @@ class RoomTestCase(unittest.HomeserverTestCase):
self.assertEqual(room_id, r["room_id"])
self.assertEqual(test_room_name, r["name"])
self.assertEqual(test_alias, r["canonical_alias"])
+ self.assertEqual(RoomTypes.SPACE, r["room_type"])
def test_room_list_sort_order(self) -> None:
"""Test room list sort ordering. alphabetical name versus number of members,
@@ -1630,7 +1637,7 @@ class RoomTestCase(unittest.HomeserverTestCase):
self.assertIn("guest_access", channel.json_body)
self.assertIn("history_visibility", channel.json_body)
self.assertIn("state_events", channel.json_body)
-
+ self.assertIn("room_type", channel.json_body)
self.assertEqual(room_id_1, channel.json_body["room_id"])
def test_single_room_devices(self) -> None:
|