运行Discord按钮交互代码报TypeError: createButtonCollector不是函数
问题原因排查
抛出TypeError: mybuttonsmsg.createButtonCollector is not a function错误的核心原因有3个:
- 没有正确初始化discord-buttons(即disbut)库,未将库绑定到Discord客户端实例,导致Message原型上没有被挂载
createButtonCollector方法 - 使用的discord.js版本为v13及以上:disbut是适配discord.js v12的第三方组件库,v13及以上版本的discord.js已经原生支持按钮交互,原生Message对象本身就没有
createButtonCollector这个方法 - 代码存在多处语法错误,导致发送的消息对象结构异常,无法调用对应的收集器方法
解决方法
方案1:继续使用discord.js v12 + disbut库
前置修正
首先在初始化Discord客户端的代码后面,添加disbut的初始化逻辑:
const Discord = require('discord.js') const client = new Discord.Client() // 新增这一行,绑定disbut到客户端 require('discord-buttons')(client)
修正后完整代码
const embed = new Discord.MessageEmbed() .setAuthor('完成验证即可查看完整服务器') .setDescription('你现在需要完成验证才能解锁服务器全部内容。验证方式为发送命令 `!verify`,如果命令无响应,可以私信@Fontanero。如果机器人处于离线状态,请等待机器人重启。如果问题持续存在,请联系任意管理员。') const botonrole = new disbut.MessageButton() .setStyle('blurple') .setLabel('<a:verify:884959804550963242> 完成验证') .setID('boton_click') const row = new disbut.MessageActionRow() // 修正:不要把按钮包在对象里,直接传实例 .addComponents(botonrole); // 修正:components是复数,接收数组格式 const mybuttonsmsg = await message.channel.send({ components: [row], embed: embed }) // 过滤器逻辑不变 const collector = mybuttonsmsg.createButtonCollector((button) => button.clicker.user.id === message.author.id, { time: 60000 }); collector.on("collect", async (b) => { console.log(b.id) if (b.id == "boton_click") { // deferred之后用editReply回复,设置ephemeral为true仅触发用户可见 await b.reply.defer({ ephemeral: true }) await b.reply.edit(`你已成功完成验证`) const role = b.guild.roles.cache.get('884901954243924008') const member = b.clicker.member // 异步操作加await await member.roles.add(role) } })
方案2(更推荐):升级到discord.js v13+ 使用原生按钮交互
新版discord.js已经完全原生支持组件交互,无需引入第三方disbut库,也不需要调用createButtonCollector,直接使用原生的交互事件监听即可,代码更稳定,维护性更强。
修正后核心逻辑代码
const { MessageEmbed, MessageActionRow, MessageButton } = require('discord.js') // 构造Embed和按钮逻辑不变 const embed = new MessageEmbed() .setAuthor('完成验证即可查看完整服务器') .setDescription('你现在需要完成验证才能解锁服务器全部内容。验证方式为发送命令 `!verify`,如果命令无响应,可以私信@Fontanero。如果机器人处于离线状态,请等待机器人重启。如果问题持续存在,请联系任意管理员。') const botonrole = new MessageButton() .setStyle('PRIMARY') // 原生对应blurple的样式为PRIMARY .setLabel('<a:verify:884959804550963242> 完成验证') .setCustomId('boton_click') // 原生用customId而非ID const row = new MessageActionRow() .addComponents(botonrole); const mybuttonsmsg = await message.channel.send({ embeds: [embed], components: [row] }) // 用原生的消息组件收集器 const collector = mybuttonsmsg.createMessageComponentCollector({ filter: i => i.user.id === message.author.id, time: 60000 }) collector.on('collect', async (i) => { if (i.customId === 'boton_click') { await i.deferReply({ ephemeral: true }) const role = i.guild.roles.cache.get('884901954243924008') await i.member.roles.add(role) await i.editReply(`你已成功完成验证`) } })
内容的提问来源于stack exchange,提问作者user16856829
相关产品推荐
相关产品推荐

