我如何构建一个用一组新按钮回复的不和谐按钮

how do I Build a discord button that replies with a new set of button

我希望它位于您输入斜杠命令示例的位置:“/bank”,它会显示 2 个不同的按钮“offense”“defense”,然后当您单击其中一个按钮时它会弹出另一个按钮设置要点击的按钮。现在它可以在我做 /bank 的地方工作,它会用进攻和防守两个按钮回复,它会回复你点击了哪个按钮被点击。但我想用另一个设置按钮回复。

//这是我的按钮命令 bank.js

const { SlashCommandBuilder } = require('@discordjs/builders');
const { MessageActionRow, MessageButton, MessageEmbed } = require('discord.js');

module.exports = {
    data: new SlashCommandBuilder()
        .setName('bank')
        .setDescription('Replies with some buttons!'),
    async execute(interaction) {
        const row = new MessageActionRow()
            .addComponents(
                new MessageButton()
                    .setCustomId('offense')
                    .setLabel('Offense')
                    .setStyle('SUCCESS'),

                    new MessageButton()
                    .setCustomId(' defense')
                    .setLabel('Defense')
                    .setStyle('DANGER'),
            );

            const embed = new MessageEmbed()
            .setColor('#0099ff')
            .setTitle('Map: BANK ')
            .setURL('https://discord.js.org')
            .setImage('https://i.imgur.com/s54Riow.jpeg')
            .setDescription('Choose your team shitter');

            await interaction.reply({  ephemeral: true, embeds: [embed], components: [row] });

    },
};

这是我的 interactionCreate.js


module.exports = {
    name: 'interactionCreate',
    async execute(interaction, client) {
        if(interaction.isButton())
        interaction.reply("you clicked" + interaction.customId);
        console.log(interaction);

        if (!interaction.isCommand()) return;
        if (!interaction.isButton()) return;

        const command = client.command.get(interaction.commandName);
        if(!command) return;

        try{
            await command.execute(interaction);
        }catch(error){
            console.error(error);
            await interaction.reply({content : "There was an error while executing action"})
        }

        console.log(`${interaction.user.tag} in #${interaction.channel.name} triggered an interaction.`);
    },
};

这是我的index.js

// Require the necessary discord.js classes
const fs = require('node:fs');
const path = require('node:path');
const { Client, Collection, Intents } = require('discord.js');
const { token } = require('./config.json');

const client = new Client({ intents: [Intents.FLAGS.GUILDS] });

client.commands = new Collection();

// command files 
const commandsPath = path.join(__dirname, 'commands');
const commandFiles = fs.readdirSync(commandsPath).filter(file => file.endsWith('.js'));

for (const file of commandFiles) {
    const filePath = path.join(commandsPath, file);
    const command = require(filePath);
    client.commands.set(command.data.name, command);
}

// event files
const eventsPath = path.join(__dirname, 'events');
const eventFiles = fs.readdirSync(eventsPath).filter(file => file.endsWith('.js'));

for (const file of eventFiles) {
    const filePath = path.join(eventsPath, file);
    const event = require(filePath);
    if (event.once) {
        client.once(event.name, (...args) => event.execute(...args));
    } else {
        client.on(event.name, (...args) => event.execute(...args));
    }
}
// When the client is ready, run this code (only once)
client.once('ready', c => {
    console.log(`Ready! Logged in as ${c.user.tag}`);
});

// When any message is sent in any channel it'll all be logged into the terminal
client.on('message', async msg => {
    if(!msg.content.startsWith(config.prefix)) return;

    var command = msg.content.substring(1);

    if(!client.commands.has(command)) return;

    try{
        await client.commands.get(command).execute(msg);
    } catch(error) {
        console.error(error);
        await msg.reply({content: "there was an error", epthemeral: true})
    }
});

// interaction files
client.on('interactionCreate', async interaction => {
    if (!interaction.isCommand()) return;

    const command = client.commands.get(interaction.commandName);

    if (!command) return;

    try {
        await command.execute(interaction);
    } catch (error) {
        console.error(error);
        await interaction.reply({ content: 'There was an error while executing this command!', ephemeral: true });
    }
});

// Login to Discord with your client's token
client.login(token);

这是我的部署-commands.js

const fs = require('node:fs');
const path = require('node:path');
const { REST } = require('@discordjs/rest');
const { Routes } = require('discord-api-types/v9');
const { clientId, guildId, token } = require('./config.json');

const commands = [];
const commandFiles = fs.readdirSync('./commands').filter(file => file.endsWith('.js'));


for (const file of commandFiles) {
    const command = require(`./commands/${file}`);
    commands.push(command.data.toJSON());
}

const rest = new REST({ version: '9' }).setToken(token);

(async () => {
    try {
        console.log('Started refreshing application (/) commands.');

        await rest.put(
            Routes.applicationGuildCommands(clientId, guildId),
            { body: commands },
        );

        console.log('Successfully reloaded application (/) commands.');
    } catch (error) {
        console.error(error);
    }
})();

我们将在您收集按钮的 interactionCreate.js 内部工作。

我们需要update the interaction with the new message. docs

我注意到您的 index.jsinteractionCreate.js 中有重复代码。这是您 运行 斜杠命令的地方。作为建议,您可能希望删除 interactionCreate.js 中的 if (!interaction.isCommand()) return; 并删除 index.js 侦听器。只是让一个文件处理 interactionCreate 事件。我将在示例中这样做。

此外,您将来可能会发现问题,因为在 blank.js 中,交互 customId 内部有一个 space。

一个监听器的例子

const { MessageButton, MessageActionRow } = require('discord.js');

module.exports = {
    name: 'interactionCreate',
    async execute(interaction, client) {
        if (interaction.isCommand()) { // Checks if the interaction is a command and runs the `
        const command = client.command.get(interaction.commandName);
        if(!command) return;

        try{
            await command.execute(interaction);
        }catch(error){
            console.error(error);
            await interaction.reply({content : "There was an error while executing action"})
        }

        console.log(`${interaction.user.tag} in #${interaction.channel.name} triggered an interaction.`);
        return;

    } else if (interaction.isButton()) { // Checks if the interaction is a button
        interaction.reply("you clicked" + interaction.customId);
        console.log(interaction);

        if (interaction.customId === 'offense') { // Check for the customId of the button
            console.log(`${interaction.user.tag} in #${interaction.channel.name} clicked the offense button.`);
        
            const ActionRow = new MessageActionRow().setComponents(new MessageButton() // Create the button inside of an action Row
              .setCustomId('CustomId')
              .setLabel('Label')
              .setStyle('PRIMARY'));
        
            return interaction.update({ // update the interaction with the new action row
              content: 'Hey',
              components: [ActionRow],
              ephemeral: true
            });
        
        }
    }
    },
};

同原例子

module.exports = {
    name: 'interactionCreate',
    async execute(interaction, client) {
        if(interaction.isButton()) {
        interaction.reply("you clicked" + interaction.customId);
        console.log(interaction);


        if (interaction.customId === 'offense') { // Check for the customId of the button
            console.log(`${interaction.user.tag} in #${interaction.channel.name} clicked the offense button.`);
        
            const ActionRow = new MessageActionRow().setComponents(new MessageButton() // Create the button inside of an action Row
              .setCustomId('CustomId')
              .setLabel('Label')
              .setStyle('PRIMARY'));
        
            return interaction.update({ // update the interaction with the new action row
              content: 'Hey',
              components: [ActionRow],
              ephemeral: true
            });
        
        }
        return;
    }

        if (!interaction.isCommand()) return;
        if (!interaction.isButton()) return;

        const command = client.command.get(interaction.commandName);
        if(!command) return;

        try{
            await command.execute(interaction);
        }catch(error){
            console.error(error);
            await interaction.reply({content : "There was an error while executing action"})
        }

        console.log(`${interaction.user.tag} in #${interaction.channel.name} triggered an interaction.`);
    },
};

如果您需要获取原始邮件中发送的嵌入,您可以使用 <interaction>.embeds 获取嵌入,然后根据您的喜好进行编辑。

现在 如果您不想编辑交互并回复新消息请记住,如果您的原始消息是短暂的,您不能删除它。您可以使用 replying methods.

说明

我们正在检查 customId that was used when building the button. After we create an action row and add the new message button. Then we are updating 具有不同组件的原始邮件内容。

如果您运行遇到任何问题,请随时发表评论