all repos — stealth-developers @ 850ad778d793cddde0eb43ab1444dc59aed8a59b

bot(bug-reports): retain original attachments
vi did:web:vt3e.cat
Sat, 04 Jul 2026 19:48:15 +0100
commit

850ad778d793cddde0eb43ab1444dc59aed8a59b

parent

9385c7facbc68f038e5629ebf0e56690739695bd

M apps/bot/src/feats/bugs/buttons.tsapps/bot/src/feats/bugs/buttons.ts

@@ -1,7 +1,7 @@

import { option } from "@purrkit/router"; import db, { bugs, eq, getActor } from "@stealth-developers/db"; -import { errorMessage, getTextChannel } from "@/lib"; +import { errorMessage, getTextChannel, logger } from "@/lib"; import { useGetData } from "@/middleware"; import { buildReportModal, constructBugContainer } from "./shared";

@@ -67,26 +67,33 @@ if (!originalActor) {

return errorMessage(interaction, "Failed to fetch original bug author."); } - const container = await constructBugContainer(updatedBug, originalActor); - if (!container) return; - const channel = await getTextChannel("1520861689048993843"); if (!channel) return errorMessage(interaction, "Failed to find bug report channel."); + let message; if (updatedBug.messageId) { try { - const message = await channel.messages.fetch(updatedBug.messageId); + message = await channel.messages.fetch(updatedBug.messageId); + } catch (err) { + logger.error(err, "error fetching discord message"); + } + } + + const container = await constructBugContainer(updatedBug, originalActor, undefined, message); + if (!container) return; + + if (message) { + try { await message.edit({ components: [container], }); } catch (err) { - console.error("error updating discord message:", err); + logger.error(err, "error updating discord message"); } } - const paddedNumber = updatedBug.bugNumber.toString().padStart(4, "0"); await interaction.editReply({ - content: `Bug #${paddedNumber} status updated to **${status}** successfully.`, + content: `Status updated to **${newStatus}** successfully.`, }); }, });
M apps/bot/src/feats/bugs/modals.tsapps/bot/src/feats/bugs/modals.ts

@@ -2,7 +2,7 @@ import { option } from "@purrkit/router";

import db, { bugs, eq, getActor, sql } from "@stealth-developers/db"; import { AttachmentBuilder } from "discord.js"; -import { errorMessage, getTextChannel } from "@/lib"; +import { errorMessage, getTextChannel, logger } from "@/lib"; import { useGetData } from "@/middleware"; import { constructBugContainer } from "./shared";

@@ -153,20 +153,28 @@

const originalActor = await getActor(updatedBug.actorId); if (!originalActor) return errorMessage(interaction, "Failed to fetch original bug author."); - const container = await constructBugContainer(updatedBug, originalActor); - if (!container) return; - - const channel = await getTextChannel("1512924775842840767"); + const channel = await getTextChannel("1520861689048993843"); if (!channel) return errorMessage(interaction, "Failed to find bug report channel."); + let message; if (updatedBug.messageId) { try { - const message = await channel.messages.fetch(updatedBug.messageId); + message = await channel.messages.fetch(updatedBug.messageId); + } catch (err) { + logger.error(err, "error fetching discord message"); + } + } + + const container = await constructBugContainer(updatedBug, originalActor, undefined, message); + if (!container) return; + + if (message) { + try { await message.edit({ components: [container], }); } catch (err) { - console.error("error updating discord message:", err); + logger.error(err, "error updating discord message"); } }
M apps/bot/src/feats/bugs/shared.tsapps/bot/src/feats/bugs/shared.ts

@@ -10,6 +10,7 @@ FileUploadBuilder,

LabelBuilder, MediaGalleryBuilder, MediaGalleryItemBuilder, + Message, ModalBuilder, SectionBuilder, StringSelectMenuBuilder,

@@ -195,6 +196,7 @@ export async function constructBugContainer(

bug: Bug, actor: Actor, file?: AttachmentBuilder, + existingMessage?: Message, ): Promise<ContainerBuilder | undefined> { const affected = bug.affectedProjects[0]; if (!affected) return undefined;

@@ -216,11 +218,51 @@ if (icon) section.setThumbnailAccessory(icon);

const buttons = await constructButtons(bug); - const gallery = file - ? new MediaGalleryBuilder().addItems( - new MediaGalleryItemBuilder().setURL(`attachment://${file.name}`), - ) - : undefined; + let gallery: MediaGalleryBuilder | undefined = undefined; + + if (file) { + gallery = new MediaGalleryBuilder().addItems( + new MediaGalleryItemBuilder().setURL(`attachment://${file.name}`), + ); + } else if (existingMessage) { + const oldContainer = existingMessage.components[0] as any; + if (oldContainer) { + const subComponents = oldContainer.components || oldContainer.data?.components || []; + const oldGallery = subComponents.find( + (c: any) => + c.items !== undefined || + c.type === 11 || + (c.constructor && c.constructor.name.includes("MediaGallery")), + ); + + if (oldGallery) { + const itemsToLoop = + oldGallery.items || oldGallery.components || oldGallery.data?.items || []; + const extractedUrls: string[] = []; + + for (const item of itemsToLoop) { + const url = item.url ?? item.data?.url ?? item.media?.url ?? item.data?.media?.url; + if (url) extractedUrls.push(url); + } + + if (extractedUrls.length > 0) { + gallery = new MediaGalleryBuilder(); + for (const url of extractedUrls) { + gallery.addItems(new MediaGalleryItemBuilder().setURL(url)); + } + } + } + } + + if (!gallery) { + const attachment = existingMessage.attachments.first(); + if (attachment && attachment.url) { + gallery = new MediaGalleryBuilder().addItems( + new MediaGalleryItemBuilder().setURL(attachment.url), + ); + } + } + } const container = new ContainerBuilder(); container.addSectionComponents(section);