Discord.js:选择菜单的选项后如何将该菜单禁用?
解决方法
前置修复
原有代码存在事件重复注册问题:clickMenu事件监听器被写在命令的execute执行函数内,每次用户调用poem命令都会新增一个监听器,长期运行会出现内存泄漏、单次点击多次响应的问题,需要将该事件监听器移到客户端初始化逻辑中全局仅注册一次,通过菜单ID判断是否为诗歌选择菜单再执行对应逻辑。
禁用菜单实现逻辑
用户选中菜单选项后,获取原携带菜单的消息,修改选择菜单的disabled属性为true,再编辑原消息即可完成禁用,也可同步修改占位符提示用户已完成选择。
修改后完整代码
const { MessageMenuOption, MessageMenu, MessageActionRow } = require("discord-buttons") // 全局注册一次clickMenu监听器,不要放在execute函数内 const registerMenuListener = (client, Discord) => { client.on('clickMenu', async (menu) => { // 仅处理诗歌选择菜单的点击 if (menu.id !== 'Poem Menu') return; let selectedEmbed = null; if (menu.values[0] == 'ECF') { selectedEmbed = new Discord.MessageEmbed() .setTitle("Eagles Can Fly") .setDescription("\nMonkeys can climb\nCrickets can leap\nHorses can race\nOwls can seek\nCheetahs can run\nEagles can fly\nPeople can try\nBut that's about it.") .setColor('#FF8CC5') } else if (menu.values[0] == 'ALS') { selectedEmbed = new Discord.MessageEmbed() .setTitle("Amy Likes Spiders") .setDescription("You know what I heard about Amy?\nAmy likes spiders.\nIcky, wriggly, hairy, ugly spiders!\nThat's why I'm not friends with her.\n\nAmy has a cute singing voice.\nI heard her singing my favorite love song.\nEvery time she sang the chorus, my heart would pound to the rhythm of the words.\nBut she likes spiders.\nThat's why I'm not friends with her.\n\nOne time, I hurt my leg really bad.\nAmy helped me up and took me to the nurse.\nI tried not to let her touch me.\nShe likes spiders, so her hands are probably gross.\nThat's why I'm not friends with her.\n\nAmy has a lot of friends.\nI always see her talking to people.\nShe probably talks about spiders.\nWhat if her friends start to like spiders too?\nThat's why I'm not friends with her.\n\nIt doesn't matter if she has other hobbies.\nIt doesn't matter if she keeps it private.\nIt doesn't matter if it doesn't hurt anyone.\n\nIt's gross.\nShe's gross.\nThe world is better off without spider lovers.\n\nAnd I'm gonna tell everyone.") .setColor('#FF8CC5') } else if (menu.values[0] == 'BY') { selectedEmbed = new Discord.MessageEmbed() .setTitle("Because You") .setDescription("Tomorrow will be brighter with me around\nBut when today is dim, I can only look down.\nMy looking is a little more forward\nBecause you look at me.\n\nWhen I want to say something, I say it with a shout!\nBut my truest feelings can never come out.\nMy words are a little less empty\nBecause you listen to me.\n\nWhen something is above me, I reach for the stars.\nBut when I feel small, I don't get very far.\nMy standing is a little bit taller\nBecause you sit with me.\n\nI believe in myself with all of my heart.\nBut what do I do when it's torn all apart?\nMy faith is a little bit stronger\nBecause you trusted me.\n\nMy pen always puts my feelings to the test.\nI'm not a good writer, but my best is my best.\nMy poems are a little bit dearer\nBecause you think of me.") .setColor('#FF8CC5') } await menu.reply.defer(); // 新增:禁用原有菜单 const originalComponents = menu.message.components; originalComponents.forEach(row => { row.components.forEach(component => { if (component.custom_id === 'Poem Menu') { component.setDisabled(true); component.setPlaceholder('已选择诗歌,菜单已禁用'); } }); }); await menu.message.edit({ components: originalComponents }); // 发送选中的诗歌 menu.channel.send(selectedEmbed); }) } module.exports = { name: "poem", description: "Hear one of Natuski's poems!", // 客户端初始化时调用一次registerMenuListener即可,无需每次执行命令都注册 registerMenuListener, async execute(client, message, args, Discord) { let poem1 = new MessageMenuOption() .setLabel('Eagles Can Fly') .setValue('ECF') .setDescription('') let poem2 = new MessageMenuOption() .setLabel('Amy Likes Spiders') .setValue('ALS') .setDescription('') let poem3 = new MessageMenuOption() .setLabel('Because You') .setValue('BY') .setDescription('') let poemMenu = new MessageMenu() .setID('Poem Menu') .setPlaceholder('Select Poem') .setMaxValues(1) .setMinValues(1) .addOption(poem1) .addOption(poem2) .addOption(poem3) let row = new MessageActionRow() .addComponent(poemMenu) await message.channel.send("A poem? O-Ok, which one would you like?", { components: [row] }); } }
如果你不想调整事件注册的位置,也可以直接在原有clickMenu逻辑中添加上述禁用菜单的代码段即可实现需求,同时记得删除原有代码中打错的await menu.reply.d冗余语句。
内容的提问来源于stack exchange,提问作者Pepega Pingu
相关产品推荐
相关产品推荐

