// All texts for embed, menu, command name and description, ... are in French because I am, but translate it in your language :) const { SlashCommandBuilder, StringSelectMenuBuilder, ActionRowBuilder, ComponentType, EmbedBuilder } = require("discord.js"); let configClient = require('../../../Config/client.json') // I use my config file only for embed color, but you can remove this line if you want module.exports = { data: new SlashCommandBuilder() .setName('help') .setDescription('› Renvoie la liste des commandes'), async execute(interaction, client) { // In this emojis object, make sure all values start in UpperCase, so not 'example' or 'EXAMPLE', but 'Example', else it not works const emojis = { Public: '🌍', Economie: '💰', Niveaux: '🆙', Test: '🧪', Bot: '🤖' } const directories = [ ...new Set(client.commands.map((cmd) => cmd.folder)) ] const categories = directories.map((dir) => { const getCommands = client.commands.filter((cmd) => cmd.folder === dir).map((cmd) => { return { name: cmd.data.name, description: cmd.data.description || 'Aucune description pour la commande ' + cmd.data.name } }) return { directory: dir, commands: getCommands } }) const embed = new EmbedBuilder() .setColor(configClient.colors.default) .setDescription(`🫧 | Choisissez une catégorie de commandes via le menu ci-dessous`) .setAuthor({name: interaction.user.username + ' | ' + interaction.user.id, iconURL: interaction.user.displayAvatarURL({dynamic: true})}) .setTimestamp() let array = [] let a = [...client.commands.values()].forEach(({folder}) => { array.push(folder) }); const array2 = Array.from(new Set(array)) const component = (state) => [ new ActionRowBuilder().addComponents( new StringSelectMenuBuilder() .setCustomId('help-menu') .setPlaceholder('Choisissez une catégorie...') .setDisabled(state) .addOptions( array2.map((f) => { return { label: f, value: f.toLowerCase(), description: `Catégorie des commandes : ${f}`, emoji: emojis[f] ?? null } }) ) ) ] const initialMessage = await interaction.reply({ embeds: [embed], components: component(false) }) const filter = (interaction) => interaction.user.id === interaction.member.id const collector = interaction.channel.createMessageComponentCollector({ filter, componentType: ComponentType.StringSelect }) collector.on('collect', async(interaction) => { const [directory] = interaction.values const category = categories.find( (x) => x.directory.toLowerCase() === directory ) const categoryEmbed = new EmbedBuilder() .setColor(configClient.colors.default) .setDescription(`🫧 | Liste des commandes de la catégorie ${directory}`) .setAuthor({name: interaction.user.username + ' | ' + interaction.user.id, iconURL: interaction.user.displayAvatarURL({dynamic: true})}) .setTimestamp() .addFields( category.commands.map(({name, description}) => { return { name: `\`/${name}\``, value: `\`\`\`${description}\`\`\``, inline: true } }) ) interaction.update({embeds: [categoryEmbed]}) }) collector.on('end', () => { initialMessage.edit({components: component(true)}) }) } }