From 642be26313bd69fbb563a3fbe2dabb4679e62f79 Mon Sep 17 00:00:00 2001 From: Cadence Ember Date: Tue, 26 Mar 2024 01:10:29 +1300 Subject: [PATCH] Enumerate child rooms with hierarchy endpoint --- d2m/actions/create-space.js | 14 +++++++++++--- matrix/api.js | 14 ++++++++++++++ types.d.ts | 17 +++++++++++++++++ 3 files changed, 42 insertions(+), 3 deletions(-) diff --git a/d2m/actions/create-space.js b/d2m/actions/create-space.js index a7390ed..3bad2a1 100644 --- a/d2m/actions/create-space.js +++ b/d2m/actions/create-space.js @@ -3,6 +3,7 @@ const assert = require("assert").strict const {isDeepStrictEqual} = require("util") const DiscordTypes = require("discord-api-types/v10") +const Ty = require("../../types") const reg = require("../../matrix/read-registration") const passthrough = require("../../passthrough") @@ -181,9 +182,16 @@ async function syncSpaceFully(guildID) { const spaceDiff = ks.diffKState(spaceKState, guildKState) await createRoom.applyKStateDiffToRoom(spaceID, spaceDiff) - const childRooms = ks.kstateToState(spaceKState).filter(({type, content}) => { - return type === "m.space.child" && "via" in content - }).map(({state_key}) => state_key) + /** @type {string[]} room IDs */ + let childRooms = [] + /** @type {string | undefined} */ + let nextBatch = undefined + do { + /** @type {Ty.HierarchyPagination} */ + const res = await api.getHierarchy(spaceID, {from: nextBatch}) + childRooms.push(...res.rooms.map(room => room.room_id)) + nextBatch = res.next_batch + } while (nextBatch) for (const roomID of childRooms) { const channelID = select("channel_room", "channel_id", {room_id: roomID}).pluck().get() diff --git a/matrix/api.js b/matrix/api.js index baa5d96..82b1c10 100644 --- a/matrix/api.js +++ b/matrix/api.js @@ -121,6 +121,19 @@ function getJoinedMembers(roomID) { return mreq.mreq("GET", `/client/v3/rooms/${roomID}/joined_members`) } +/** + * @param {string} roomID + * @param {{from?: string, limit?: any}} pagination + * @returns {Promise>} + */ +function getHierarchy(roomID, pagination) { + let path = `/client/v1/rooms/${roomID}/hierarchy` + if (!pagination.from) delete pagination.from + if (!pagination.limit) pagination.limit = 50 + path += `?${new URLSearchParams(pagination)}` + return mreq.mreq("GET", path) +} + /** * @param {string} roomID * @param {string} eventID @@ -239,6 +252,7 @@ module.exports.getEventForTimestamp = getEventForTimestamp module.exports.getAllState = getAllState module.exports.getStateEvent = getStateEvent module.exports.getJoinedMembers = getJoinedMembers +module.exports.getHierarchy = getHierarchy module.exports.getRelations = getRelations module.exports.sendState = sendState module.exports.sendEvent = sendEvent diff --git a/types.d.ts b/types.d.ts index 2788f60..68430d9 100644 --- a/types.d.ts +++ b/types.d.ts @@ -257,6 +257,18 @@ export namespace R { export type EventRedacted = { event_id: string } + + export type Hierarchy = { + avatar_url?: string + canonical_alias?: string + children_state: {} + guest_can_join: boolean + join_rule?: string + name?: string + num_joined_members: number + room_id: string + room_type?: string + } } export type Pagination = { @@ -264,3 +276,8 @@ export type Pagination = { next_batch?: string prev_match?: string } + +export type HierarchyPagination = { + rooms: T[] + next_batch?: string +}