Discord.js v14报错TypeError: interaction.reply不是函数求修复
问题分析与修复方案
错误根源
- 变量名冲突:
collector.on('end', (interaction) => {...})里的参数名interaction和外部的交互对象重名,此处的interaction实际是收集到的组件交互数组,自然没有reply方法。 - 交互对象误用:在
collect事件的取消逻辑中,错误引用外部的interaction.customId,应使用当前收集到的交互对象i;同时初始交互已完成回复,直接调用interaction.reply会触发重复回复错误。 - 组件构造器混用:代码同时使用了Discord.js v14新构造器(如
ActionRowBuilder)和旧版构造器(如MessageActionRow),v14要求统一使用新Builder类。
修复后的完整代码
} else if (interaction.customId == "close-ticket") { const guild = client.guilds.cache.get(interaction.guildId); const chan = guild.channels.cache.get(interaction.channelId); const row = new ActionRowBuilder() .addComponents( new ButtonBuilder() .setCustomId('confirm-close') .setLabel('Κλείσε το ticket!') .setStyle(ButtonStyle.Danger), new ButtonBuilder() .setCustomId('no') .setLabel('Ακύρωση!') .setStyle(ButtonStyle.Secondary), ); const verif = await interaction.reply({ content: 'Είστε βέβαιοι ότι θέλετε να κλείσετε το ticket σας;', components: [row], fetchReply: true }); // v14需用ComponentType指定组件类型 const collector = interaction.channel.createMessageComponentCollector({ componentType: ComponentType.Button, time: 10000 }); collector.on('collect', async i => { // 校验操作权限,仅允许发起关闭请求的用户操作 if (i.user.id !== interaction.user.id) { return i.reply({ content: '只有发起关闭请求的人才能操作!', ephemeral: true }); } if (i.customId == 'confirm-close') { await interaction.editReply({ content: `Το ticket έκλεισε απο τον/την: <@!${interaction.user.id}>`, components: [] }); await chan.edit({ name: `closed-${chan.name}`, permissionOverwrites: [ { id: chan.topic, // 直接使用channel topic中的用户ID,避免缓存未命中 deny: [PermissionsBitField.Flags.ViewChannel], }, { id: config.rolesupport, allow: [PermissionsBitField.Flags.ViewChannel], }, { id: interaction.guild.roles.everyone, deny: [PermissionsBitField.Flags.ViewChannel], }, ], }); // 使用v14的EmbedBuilder构造消息嵌入 const embed = new EmbedBuilder() .setColor('#429cf5') .setAuthor({ name: 'Ticket', iconURL: client.config.serverlogo }) .setDescription('Πατήστε το `🗑️Διαγραφή του ticket!`, για να διαγράψετε το ticket!') .setFooter({ text: client.config.servername, iconURL: client.config.serverlogo }) .setTimestamp(); const deleteRow = new ActionRowBuilder() .addComponents( new ButtonBuilder() .setCustomId('delete-ticket') .setLabel('Διαγραφή του ticket!') .setEmoji('🗑️') .setStyle(ButtonStyle.Danger), ); await chan.send({ embeds: [embed], components: [deleteRow] }); collector.stop(); } else if (i.customId == 'no') { // 发送临时消息告知取消,避免刷屏 await i.reply({ content: 'Η κατάργηση του ticket σας ακυρώθηκε !', ephemeral: true }); collector.stop(); } }); collector.on('end', (collected) => { // 修改参数名避免与外部交互对象冲突 if (collected.size < 1) { // 初始交互已回复,使用editReply更新内容 interaction.editReply({ content: 'Η κατάργηση του ticket σας ακυρώθηκε !', components: [] }).catch(err => console.error('超时回复失败:', err)); } });
核心修复点
- 修正
end事件参数名,避免覆盖外部交互对象; - 在
collect事件中统一使用当前收集到的交互对象i处理回复,添加操作权限校验; - 替换所有旧版组件构造器为v14标准构造器(
EmbedBuilder、ActionRowBuilder等),并适配新的参数格式; - 指定
componentType: ComponentType.Button(需提前导入ComponentType); - 优化用户ID获取逻辑,直接使用频道topic中的ID,避免缓存依赖。
内容的提问来源于stack exchange,提问作者Red.1111
相关产品推荐
相关产品推荐

