NodeJS TypeError:无法读取undefined的属性(阅读“leave”)||Disocrd.JS V.14

cgh8pdjw  于 2023-05-06  发布在  Node.js
关注(0)|答案(1)|浏览(219)

这是我的代码:

const { SlashCommandBuilder } = require('@discordjs/builders');
const { EmbedBuilder, ActionRowBuilder, StringSelectMenuBuilder, ButtonBuilder } = require('discord.js');

module.exports = {
    data: new SlashCommandBuilder()
        .setName('servers')
        .setDescription('Displays a dropdown menu with all the servers the bot is in.'),
        async execute(interaction) {

        if (interaction.user.id !== '759753313553743893') {
            return interaction.reply({ content: 'You are not authorized to use this command!', ephemeral: true });
        }

        // Fetch all the guilds the bot is in
        const guilds = await interaction.client.guilds.fetch();

        // Create an object with guild IDs as properties and guild names as values
        const guildList = {};
        guilds.forEach(guild => {
            guildList[guild.id] = guild.name;
        });

        // Create the options for the select menu
        const serverOptions = Object.keys(guildList).map(guildID => ({ label: guildList[guildID], value: guildID }));

        // Create the select menu
        const serverMenu = new StringSelectMenuBuilder()
            .setCustomId('server_menu')
            .setPlaceholder('Select a server')
            .addOptions(serverOptions);

        // Create the initial embed message with the select menu
        const initialEmbed = new EmbedBuilder()
            .setTitle('Server List')
            .setDescription('Please select a server from the dropdown menu.')
            .setColor('#00ff00')
            .setFooter({ text: 'Server Management System' })
            .setTimestamp();

        const row = new ActionRowBuilder().addComponents(serverMenu);

        const initialMessage = await interaction.reply({ embeds: [initialEmbed], components: [row], fetchReply: true, ephemeral: true });

        // Create the button that will kick the bot from the selected server
        const kickButton = new ButtonBuilder()
            .setCustomId('kick_button')
            .setLabel('Kick bot')
            .setStyle('Danger');

        // Listen for the select menu to be interacted with
        const filter = (interaction) => {
            return interaction.customId === 'server_menu';
        };
        const collector = interaction.channel.createMessageComponentCollector({ filter, time: 15000 });

        collector.on('collect', async (interaction) => {
            // Get the selected server ID and guild object
            const selectedServer = interaction.values[0];
            const guild = interaction.client.guilds.cache.get(selectedServer);

            // Edit the embed message with the selected server's name and the kick button
            const updatedEmbed = new EmbedBuilder()
                .setTitle(guild.name)
                .setDescription('Do you want to kick the bot from this server?')
                .setColor('#ff0000')
                .setFooter({ text: 'Server Management System' })
                .setTimestamp();

            const row = new ActionRowBuilder().addComponents(kickButton);

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

        // Listen for the kick button to be interacted with
        const buttonFilter = (interaction) => {
            return interaction.customId === 'kick_button';
        };
        const buttonCollector = interaction.channel.createMessageComponentCollector({ buttonFilter, time: 15000 });

        buttonCollector.on('collect', async (interaction) => {
            // Get the selected server ID and guild object
            const selectedServer = interaction.message.embeds[0].title;
            const guildID = Object.keys(guildList).find(id => guildList[id] === selectedServer);
            const guild = await interaction.client.guilds.fetch(guildID);
            if (guild) {
                // Leave the guild
                await guild.leave();
            
                // Reply to the interaction with a success message
                await interaction.update({ content: `The bot has been kicked from ${selectedServer}.`, embeds: [], components: [], ephemeral: true });
            } else {
                // If the guild is not found, reply to the interaction with an error message
                await interaction.update({ content: `Could not find ${selectedServer}.`, embeds: [], components: [], ephemeral: true });
            }
        })
    }
}

这是一个命令,有一个下拉列表,其中包含机器人加入的所有服务器。当我选择一个特定的服务器时,它会问我是否要从服务器中踢出它。但当我点击按钮“踢”它返回我这个错误在终端:

C:\Users\kalam\OneDrive\Υπολογιστής\Botanser\Commands\Moderation\servers.js:76
            await guild.leave();
                        ^

TypeError: Cannot read properties of undefined (reading 'leave')

我的意图:

  • const { Guilds, GuildMembers, GuildMessages, MessageContent, DirectMessages, GuildVoiceStates } = GatewayIntentBits;
  • intents: [Guilds, GuildMembers, GuildMessages, MessageContent, DirectMessages, GuildVoiceStates]
    任何答案都将被接受。提前感谢!
lp0sw83n

lp0sw83n1#

您遇到问题的原因是由于guild未定义。特别是在以下行:

const guild = interaction.client.guilds.cache.find(guild => guild.name === selectedServer);

使用client.guilds.fetch()方法可能更符合您的利益,因为这样可以保证它的存在。* (只要客户端仍在服务器中。)*
下面是一个例子:

const guild = await interaction.client.guilds.fetch(<guild_id>)
if (guild) {
    // whatever ...
}

我建议不要存储嵌入后可能需要的值。使用一个物品会更有好处(在大多数情况下,更实用),所有当前可用的公会都可以作为属性进行选择。ID是存储公会信息的更好方法,因为ID是唯一的,与其他公会不同。

文档链接

获取:https://discord.js.org/#/docs/discord.js/main/class/GuildManager?scrollTo=fetch

相关问题