import { SlashCommandBuilder, EmbedBuilder, PermissionFlagsBits, MessageFlags } from "discord.js" import type { ChatInputCommandInteraction, APIEmbedField } from "discord.js" import dbGuildInit from "@/utils/dbGuildInit" import dbGuild from "@/schemas/guild" import { t } from "@/utils/i18n" const parseObject = (obj: object, prefix = ""): { name: string, value: object | string | boolean }[] => { const fields: { name: string, value: object | string | boolean }[] = [] for (const [key, value] of Object.entries(obj)) { if (value !== null && typeof value === "object") fields.push(...parseObject(value as object, `${prefix}${key}.`)) else { let newValue: string if (typeof value === "boolean") newValue = value ? "True" : "False" else if (value === null || value === undefined) newValue = "None" else newValue = String(value) fields.push({ name: `${prefix}${key}`, value: newValue }) } } return fields } export const data = new SlashCommandBuilder() .setName("database") .setDescription("Communicate with the database") .setDescriptionLocalizations({ fr: "Communiquer avec la base de données" }) .setDefaultMemberPermissions(PermissionFlagsBits.Administrator) .addSubcommand(subcommand => subcommand .setName("info") .setDescription("Returns information about the current guild") .setNameLocalizations({ fr: "info" }) .setDescriptionLocalizations({ fr: "Retourne les informations sur le serveur actuel" }) ) .addSubcommand(subcommand => subcommand .setName("init") .setDescription("Force initialize an entry for the current guild in the database") .setNameLocalizations({ fr: "init" }) .setDescriptionLocalizations({ fr: "Initialiser de force une entrée pour le serveur actuel dans la base de données" }) ) .addSubcommand(subcommand => subcommand .setName("edit") .setDescription("Modify parameters for the current guild") .setNameLocalizations({ fr: "modifier" }) .setDescriptionLocalizations({ fr: "Modifier les paramètres pour le serveur actuel" }) .addStringOption(option => option .setName("key") .setDescription("Key to modify") .setNameLocalizations({ fr: "cle" }) .setDescriptionLocalizations({ fr: "Clé à modifier" }) .setRequired(true) ) .addStringOption(option => option .setName("value") .setDescription("Value to set") .setNameLocalizations({ fr: "valeur" }) .setDescriptionLocalizations({ fr: "Valeur à définir" }) .setRequired(true) ) ) export async function execute(interaction: ChatInputCommandInteraction) { if (interaction.user !== interaction.client.application.owner) return interaction.reply({ content: t(interaction.locale, "database.owner_only"), flags: MessageFlags.Ephemeral }) const guild = interaction.guild if (!guild) return interaction.reply({ content: t(interaction.locale, "database.server_only"), flags: MessageFlags.Ephemeral }) let guildProfile = await dbGuild.findOne({ guildId: guild.id }) const subcommand = interaction.options.getSubcommand(true) if (subcommand === "info") { if (!guildProfile) return interaction.reply({ content: t(interaction.locale, "common.database_not_found"), flags: MessageFlags.Ephemeral }) const fields = parseObject(guildProfile.toObject()) const embed = new EmbedBuilder() .setTitle(t(interaction.locale, "database.info_title")) .setDescription(t(interaction.locale, "database.guild_info", { name: guildProfile.guildName, id: guildProfile.guildId })) .setThumbnail(guildProfile.guildIcon) .setTimestamp() //.addFields(fields as APIEmbedField[]) // Limit the number of fields to 25 .addFields(fields.slice(0, 25) as APIEmbedField[]) return interaction.reply({ embeds: [embed] }) } else if (subcommand === "init") { if (guildProfile) return interaction.reply({ content: t(interaction.locale, "database.already_exists", { name: guildProfile.guildName }), flags: MessageFlags.Ephemeral }) guildProfile = await dbGuildInit(guild) return interaction.reply({ content: t(interaction.locale, "database.initialized", { name: guildProfile.guildName }), flags: MessageFlags.Ephemeral }) } else if (subcommand === "edit") { if (!guildProfile) return interaction.reply({ content: t(interaction.locale, "common.database_not_found"), flags: MessageFlags.Ephemeral }) const key = interaction.options.getString("key", true) const value = interaction.options.getString("value", true) let oldValue: string = guildProfile.get(key) as string if (!oldValue) oldValue = t(interaction.locale, "common.none") guildProfile.set(key, value) guildProfile.markModified(key) await guildProfile.save().catch(console.error) return interaction.reply({ content: t(interaction.locale, "database.updated", { name: guildProfile.guildName, key, oldValue, value }), flags: MessageFlags.Ephemeral }) } }