From f78a9412b888a1e9429620bff1f50d922d4d7bb2 Mon Sep 17 00:00:00 2001 From: Rory& Date: Mon, 22 Sep 2025 15:43:13 +0200 Subject: [PATCH] Implement message preloading --- src/api/routes/channels/preload-messages.ts | 72 +++++++++++++++++++ .../subconfigurations/limits/MessageLimits.ts | 1 + .../schemas/PreloadMessagesRequestSchema.ts | 21 ++++++ src/util/schemas/index.ts | 3 +- .../PreloadMessagesResponseSchema.ts | 21 ++++++ src/util/schemas/responses/index.ts | 3 +- 6 files changed, 119 insertions(+), 2 deletions(-) create mode 100644 src/api/routes/channels/preload-messages.ts create mode 100644 src/util/schemas/PreloadMessagesRequestSchema.ts create mode 100644 src/util/schemas/responses/PreloadMessagesResponseSchema.ts diff --git a/src/api/routes/channels/preload-messages.ts b/src/api/routes/channels/preload-messages.ts new file mode 100644 index 00000000..e18f33f6 --- /dev/null +++ b/src/api/routes/channels/preload-messages.ts @@ -0,0 +1,72 @@ +/* + Spacebar: A FOSS re-implementation and extension of the Discord.com backend. + Copyright (C) 2025 Spacebar and Spacebar Contributors + + This program is free software: you can redistribute it and/or modify + it under the terms of the GNU Affero General Public License as published + by the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU Affero General Public License for more details. + + You should have received a copy of the GNU Affero General Public License + along with this program. If not, see . +*/ + +import { route } from "@spacebar/api"; +import { Config, PreloadMessagesRequestSchema, Message, PreloadMessagesResponseSchema } from "@spacebar/util"; +import { Request, Response, Router } from "express"; +const router = Router(); + +router.post( + "/", + route({ + // // eslint-disable-next-line @typescript-eslint/ban-ts-comment + // // @ts-expect-error + // requestBody: "PreloadMessagesRequest", // this is broken for some reason? + responses: { + 200: { + body: "PreloadMessagesResponse", + }, + 400: { + body: "APIErrorResponse", + }, + }, + }), + async (req: Request, res: Response) => { + const body = req.body as PreloadMessagesRequestSchema; + if (body.channels.length > Config.get().limits.message.maxPreloadCount) + return res.status(400).send({ + code: 400, + message: `Cannot preload more than ${Config.get().limits.message.maxPreloadCount} channels at once.`, + }); + + const messages = ( + await Promise.all( + body.channels.map( + async (channelId) => + await Message.findOne({ + where: { channel_id: channelId }, + order: { timestamp: "DESC" }, + }), + ), + ) + ).filter((x) => x !== null) as Message[]; + + const filteredMessages = messages.map((message) => { + const x = message.toJSON(); + // https://docs.discord.food/resources/message#preload-messages - reactions are not included in the response + // eslint-disable-next-line @typescript-eslint/ban-ts-comment + // @ts-expect-error + x.reactions = undefined; + return x; + }) as PreloadMessagesResponseSchema; + + return res.status(200).send(filteredMessages); + }, +); + +export default router; diff --git a/src/util/config/types/subconfigurations/limits/MessageLimits.ts b/src/util/config/types/subconfigurations/limits/MessageLimits.ts index e61c13e1..f98e14b0 100644 --- a/src/util/config/types/subconfigurations/limits/MessageLimits.ts +++ b/src/util/config/types/subconfigurations/limits/MessageLimits.ts @@ -23,4 +23,5 @@ export class MessageLimits { maxAttachmentSize: number = 1024 * 1024 * 1024; maxBulkDelete: number = 1000; maxEmbedDownloadSize: number = 1024 * 1024 * 5; + maxPreloadCount: number = 100; } diff --git a/src/util/schemas/PreloadMessagesRequestSchema.ts b/src/util/schemas/PreloadMessagesRequestSchema.ts new file mode 100644 index 00000000..7c5145b7 --- /dev/null +++ b/src/util/schemas/PreloadMessagesRequestSchema.ts @@ -0,0 +1,21 @@ +/* + Spacebar: A FOSS re-implementation and extension of the Discord.com backend. + Copyright (C) 2025 Spacebar and Spacebar Contributors + + This program is free software: you can redistribute it and/or modify + it under the terms of the GNU Affero General Public License as published + by the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU Affero General Public License for more details. + + You should have received a copy of the GNU Affero General Public License + along with this program. If not, see . +*/ + +export interface PreloadMessagesRequestSchema { + channels: string[]; +} diff --git a/src/util/schemas/index.ts b/src/util/schemas/index.ts index 4088c158..68c38fb5 100644 --- a/src/util/schemas/index.ts +++ b/src/util/schemas/index.ts @@ -1,6 +1,6 @@ /* Spacebar: A FOSS re-implementation and extension of the Discord.com backend. - Copyright (C) 2024 Spacebar and Spacebar Contributors + Copyright (C) 2025 Spacebar and Spacebar Contributors This program is free software: you can redistribute it and/or modify it under the terms of the GNU Affero General Public License as published @@ -58,6 +58,7 @@ export * from "./MessageCreateSchema"; export * from "./MessageEditSchema"; export * from "./MfaCodesSchema"; export * from "./ModifyGuildStickerSchema"; +export * from "./PreloadMessagesRequestSchema"; export * from "./PasswordResetSchema"; export * from "./PurgeSchema"; export * from "./RefreshUrlsRequestSchema"; diff --git a/src/util/schemas/responses/PreloadMessagesResponseSchema.ts b/src/util/schemas/responses/PreloadMessagesResponseSchema.ts new file mode 100644 index 00000000..9452896e --- /dev/null +++ b/src/util/schemas/responses/PreloadMessagesResponseSchema.ts @@ -0,0 +1,21 @@ +/* + Spacebar: A FOSS re-implementation and extension of the Discord.com backend. + Copyright (C) 2025 Spacebar and Spacebar Contributors + + This program is free software: you can redistribute it and/or modify + it under the terms of the GNU Affero General Public License as published + by the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU Affero General Public License for more details. + + You should have received a copy of the GNU Affero General Public License + along with this program. If not, see . +*/ + +import { Message } from "@spacebar/util"; + +export type PreloadMessagesResponseSchema = Message[]; \ No newline at end of file diff --git a/src/util/schemas/responses/index.ts b/src/util/schemas/responses/index.ts index cf589bac..c4f5245b 100644 --- a/src/util/schemas/responses/index.ts +++ b/src/util/schemas/responses/index.ts @@ -1,6 +1,6 @@ /* Spacebar: A FOSS re-implementation and extension of the Discord.com backend. - Copyright (C) 2023 Spacebar and Spacebar Contributors + Copyright (C) 2025 Spacebar and Spacebar Contributors This program is free software: you can redistribute it and/or modify it under the terms of the GNU Affero General Public License as published @@ -49,6 +49,7 @@ export * from "./InstanceStatsResponse"; export * from "./LocationMetadataResponse"; export * from "./MemberJoinGuildResponse"; export * from "./OAuthAuthorizeResponse"; +export * from "./PreloadMessagesResponseSchema"; export * from "./RefreshUrlsResponse"; export * from "./SettingsProtoUpdateResponse"; export * from "./TeamListResponse";