Discord.js v14工单命令报错求助:ReferenceError等问题
错误原因与解决方案
1. 变量名错误(create/close未定义)
代码构建按钮行时,错误引用了未声明的create和close变量,实际应使用之前创建的按钮实例ticketButton和ticketCloseButton:
// 错误写法 const row = new ActionRowBuilder().addComponents(create); const row1 = new ActionRowBuilder().addComponents(close); // 正确写法 const row = new ActionRowBuilder().addComponents(ticketButton); const row1 = new ActionRowBuilder().addComponents(ticketCloseButton);
2. 未正确获取消息对象处理按钮交互
代码中使用未定义的response调用awaitMessageComponent,需先保存发送的消息对象,再在该对象上监听按钮交互:
// 保存发送的工单创建消息 const sentEmbed = await channel1.send({ embeds: [embed1], components: [row] }); // 在该消息上监听按钮点击 const confirmation = await sentEmbed.awaitMessageComponent();
3. Discord.js v14频道类型错误
创建工单频道时,v14不再支持字符串类型,需使用ChannelType.GuildText,且需先导入该枚举:
// 顶部导入ChannelType const { ..., ChannelType } = require("discord.js"); // 创建频道时的正确写法 const channel = await interaction.guild.channels.create({ name: `${interaction.member.user.username} | ticket`, type: ChannelType.GuildText, parent: ticketFolder.id, });
4. 未定义变量替换
代码中错误使用了message、guild、Guildmember等未声明变量,全部替换为interaction相关对象:
// 错误写法 const channel = await message.guild.channels.create(...) id: guild.roles.everyone id: guild.roles.cache.find(...) setAuthor({ name: Guildmember.user.tag, ... }) // 正确写法 const channel = await interaction.guild.channels.create(...) id: interaction.guild.roles.everyone id: interaction.guild.roles.cache.find(role => role.name === 'Moderator') setAuthor({ name: interaction.member.user.tag, iconURL: interaction.member.user.displayAvatarURL() })
5. 延迟回复需添加await
interaction.deferReply()是异步操作,必须添加await,否则会导致Discord API认为交互超时,引发Unknown interaction错误:
// 错误写法 interaction.deferReply() // 正确写法 await interaction.deferReply({ ephemeral: true }); // 可选添加ephemeral让回复仅自己可见
6. 修复作用域与判断条件错误
- 关闭工单的判断条件中,错误使用了
confirmation.customId,应改为confirmation1.customId - 确保工单频道变量
channel在后续代码中处于正确作用域内
修正后的完整代码
const { SlashCommandBuilder, PermissionFlagsBits, EmbedBuilder, ButtonStyle, ButtonBuilder, ActionRowBuilder, ChannelType } = require("discord.js"); module.exports = { data: new SlashCommandBuilder() .setName('create-ticket') .setDescription('Creates a ticket') .setDefaultMemberPermissions(PermissionFlagsBits.ManageMessages) .addChannelOption(option => option.setName('channel') .setDescription('The channel you want to send it to') .setRequired(true) ) .addChannelOption(option => option.setName('ticket-folder') .setDescription('The folder where tickets will be created') .setRequired(true) ), permissionsRequired: [PermissionFlagsBits.ManageMessages], botPermissions: [PermissionFlagsBits.ManageMessages], async execute(interaction) { const channel1 = interaction.options.getChannel('channel'); const ticketFolder = interaction.options.getChannel('ticket-folder'); // 创建工单嵌入与按钮 const embed1 = new EmbedBuilder() .setTitle('Create a ticket') .setDescription(`Tap on the button below to create a ticket`) .setTimestamp() .setColor('Green'); const ticketButton = new ButtonBuilder() .setCustomId('create') .setLabel('Create') .setStyle(ButtonStyle.Success) .setEmoji('📩'); const row = new ActionRowBuilder().addComponents(ticketButton); const sentEmbed = await channel1.send({ embeds: [embed1], components: [row] }); // 监听创建按钮点击 const confirmation = await sentEmbed.awaitMessageComponent(); if (confirmation.customId === 'create') { // 创建工单频道 const channel = await interaction.guild.channels.create({ name: `${interaction.member.user.username} | ticket`, type: ChannelType.GuildText, parent: ticketFolder.id, permissionOverwrites: [ { id: interaction.guild.roles.everyone, deny: ['ViewChannel'], }, { id: interaction.member.user.id, allow: ['ViewChannel', 'SendMessages'], }, { id: interaction.guild.roles.cache.find(role => role.name === 'Moderator')?.id || '', allow: ['ManageChannels', 'ManageMessages', 'ViewChannel'], }, ], }); // 创建工单成功嵌入与关闭按钮 const embed2 = new EmbedBuilder() .setTitle('Ticket Created') .setDescription(`${interaction.member.user.username} has created a ticket!\nTap on the close button to close the ticket`) .setTimestamp() .setAuthor({ name: interaction.member.user.tag, iconURL: interaction.member.user.displayAvatarURL() }) .setColor('#FF0000'); const ticketCloseButton = new ButtonBuilder() .setCustomId('close') .setLabel('Close') .setStyle(ButtonStyle.Danger) .setEmoji('❌'); const row1 = new ActionRowBuilder().addComponents(ticketCloseButton); const sentTicketEmbed = await channel.send({ embeds: [embed2], components: [row1] }); // 监听关闭按钮点击 const confirmation1 = await sentTicketEmbed.awaitMessageComponent(); if (confirmation1.customId === 'close') { const channelDeleteEmbed = new EmbedBuilder() .setTitle('Closing Ticket') .setDescription('The ticket will close in 5 seconds') .setColor('#FF0000') .setTimestamp(); await channel.send({ embeds: [channelDeleteEmbed] }); setTimeout(() => { channel.delete(); }, 5000); } } // 回复命令发起者 await interaction.editReply({ content: 'Ticket embed sent successfully!', ephemeral: true }); } };
内容的提问来源于stack exchange,提问作者Sum.
相关产品推荐
相关产品推荐

