diff --git a/backend/src/utils/MessageBuffer.ts b/backend/src/utils/MessageBuffer.ts index 06000d87..e2ae4b64 100644 --- a/backend/src/utils/MessageBuffer.ts +++ b/backend/src/utils/MessageBuffer.ts @@ -1,5 +1,6 @@ import { StrictMessageContent } from "../utils"; import Timeout = NodeJS.Timeout; +import { calculateEmbedSize } from "./calculateEmbedSize"; type ConsumeFn = (part: StrictMessageContent) => void; @@ -18,6 +19,7 @@ export interface MessageBufferOpts { } const MAX_CHARS_PER_MESSAGE = 2000; +const MAX_EMBED_LENGTH_PER_MESSAGE = 6000; const MAX_EMBEDS_PER_MESSAGE = 10; /** @@ -76,8 +78,16 @@ export class MessageBuffer { } if (content.embeds) { - if (chunk.content.embeds && chunk.content.embeds.length + content.embeds.length > MAX_EMBEDS_PER_MESSAGE) { - this.startNewChunk(contentType); + if (chunk.content.embeds) { + if (chunk.content.embeds.length + content.embeds.length > MAX_EMBEDS_PER_MESSAGE) { + this.startNewChunk(contentType); + } else { + const existingEmbedsLength = chunk.content.embeds.reduce((sum, embed) => sum + calculateEmbedSize(embed), 0); + const embedsLength = content.embeds.reduce((sum, embed) => sum + calculateEmbedSize(embed), 0); + if (existingEmbedsLength + embedsLength > MAX_EMBED_LENGTH_PER_MESSAGE) { + this.startNewChunk(contentType); + } + } } if (chunk.content.embeds == null) chunk.content.embeds = []; diff --git a/backend/src/utils/calculateEmbedSize.ts b/backend/src/utils/calculateEmbedSize.ts new file mode 100644 index 00000000..124aa03b --- /dev/null +++ b/backend/src/utils/calculateEmbedSize.ts @@ -0,0 +1,17 @@ +import { MessageEmbedOptions } from "discord.js"; + +function sumStringLengthsRecursively(obj: any): number { + if (obj == null) return 0; + if (typeof obj === "string") return obj.length; + if (Array.isArray(obj)) { + return obj.reduce((sum, item) => sum + sumStringLengthsRecursively(item), 0); + } + if (typeof obj === "object") { + return Array.from(Object.values(obj)).reduce((sum: number, item) => sum + sumStringLengthsRecursively(item), 0); + } + return 0; +} + +export function calculateEmbedSize(embed: MessageEmbedOptions): number { + return sumStringLengthsRecursively(embed); +}