feat(thread-discovery): implement separate endpoint for fetching threads and update channel loading logic

This commit is contained in:
MythEclipse
2026-05-13 21:22:05 +07:00
parent 0b8111de81
commit 95cb8b837a
4 changed files with 85 additions and 16 deletions
+24 -15
View File
@@ -73,33 +73,42 @@ export class VoiceController {
const guild = this.getGuild(guildId);
await guild.channels.fetch().catch(() => null);
const channels = [...guild.channels.cache.values()].filter((channel) =>
["GUILD_TEXT", "GUILD_PUBLIC_THREAD", "GUILD_PRIVATE_THREAD"].includes(
channel.type,
),
);
return guild.channels.cache
.filter((channel) => channel.type === "GUILD_TEXT")
.map((channel) => ({
id: channel.id,
name: channel.name,
type: channel.type,
}))
.sort((a, b) => a.name.localeCompare(b.name));
}
async listThreads(guildId: string): Promise<ChannelSummary[]> {
const guild = this.getGuild(guildId);
await guild.channels.fetch().catch(() => null);
const threads: ChannelSummary[] = [];
for (const channel of guild.channels.cache.values()) {
const threadParent = channel as typeof channel & {
threads?: { fetch: (options: { archived: boolean; limit: number }) => Promise<any> };
};
if (!threadParent.threads?.fetch) continue;
for (const archived of [false, true]) {
const fetched = await threadParent.threads.fetch({ archived, limit: 100 }).catch(() => null);
if (!fetched?.threads) continue;
channels.push(...fetched.threads.values());
for (const thread of fetched.threads.values()) {
threads.push({
id: thread.id,
name: `${channel.name} / ${thread.name}`,
type: thread.type,
});
}
}
}
return Array.from(new Map(channels.map((channel) => [channel.id, channel])).values())
.map((channel) => {
const parentName = channel.isThread?.() ? channel.parent?.name : null;
return {
id: channel.id,
name: parentName ? `${parentName} / ${channel.name}` : channel.name,
type: channel.type,
};
})
return Array.from(new Map(threads.map((thread) => [thread.id, thread])).values())
.sort((a, b) => a.name.localeCompare(b.name));
}
+8
View File
@@ -114,6 +114,14 @@ export function startWebserver(
}
});
app.get("/api/guilds/:guildId/threads", async (req, res, next) => {
try {
res.json(await voiceController.listThreads(req.params.guildId));
} catch (error) {
next(error);
}
});
app.post("/api/connect", async (req, res, next) => {
try {
const { guildId, channelId } = req.body as {