src/interactions/commands/bug/modals.ts (view raw)
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 |
import { bugs, db } from "@/database";
import { getGuild } from "@/utils/queries";
import type { Client, ModalSubmitInteraction } from "discord.js";
import { eq, sql } from "drizzle-orm";
import {
INPUT_IDS,
MODAL_IDS,
VALIDATION,
constructContainer,
} from "./_shared";
export async function handleNewBugModal(
client: Client,
interaction: ModalSubmitInteraction,
) {
if (!interaction.guildId) return;
const title = interaction.fields.getTextInputValue(INPUT_IDS.TITLE);
const description = interaction.fields.getTextInputValue(
INPUT_IDS.DESCRIPTION,
);
const affected = interaction.fields.getStringSelectValues(INPUT_IDS.AFFECTED);
const media = interaction.fields.getUploadedFiles(INPUT_IDS.MEDIA);
await interaction.deferReply({ flags: ["Ephemeral"] });
const [{ count }] = await db
.select({ count: sql<number>`COUNT(*)`.mapWith(Number) })
.from(bugs)
.where(eq(bugs.guildId, interaction.guildId));
const bugNumber = count + 1;
const paddedNumber = bugNumber.toString().padStart(4, "0");
const bug = await db
.insert(bugs)
.values({
guildId: interaction.guildId,
bugNumber: bugNumber,
authorId: interaction.user.id,
status: "open",
title: title,
description: description,
projects: [...affected],
sent: false,
messageId: null,
threadId: null,
createdAt: new Date(),
updatedAt: new Date(),
closedAt: null,
})
.returning();
// TODO)) media uploads to s3
const container = await constructContainer(bug[0], interaction.user.id);
if (!container) return;
const { data, exists } = await getGuild(interaction.guildId);
if (!exists) return;
const channelId = data.bug_channel_id;
if (!channelId) return;
const channel = await interaction.guild?.channels.fetch(channelId);
if (!channel || !channel.isSendable()) return;
// send message
// TODO)) buttons
const message = await channel.send({
components: [container],
flags: ["IsComponentsV2"],
});
// thread
function truncateTitle(title: string, maxLength: number): string {
return title.length > maxLength
? `${title.substring(0, maxLength)}...`
: title;
}
const threadName = `#${paddedNumber} ${truncateTitle(title, VALIDATION.THREAD_NAME_MAX_LENGTH)}`;
const thread = await message.startThread({
name: threadName,
autoArchiveDuration: 1440,
});
// save & update user
await db
.update(bugs)
.set({ messageId: message.id, threadId: thread.id, sent: true })
.where(eq(bugs.id, bug[0].id));
thread.send(
"Use this space to discuss the bug, provide additional details, or ask questions.",
);
interaction.editReply(
`Bug #${paddedNumber} created successfully! Find it here: ${message.url}`,
);
}
|