You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Discord.js实现表情反应切换帮助命令分页功能的问题咨询

Discord翻页式帮助命令代码修复方案

原有代码的核心问题

  • 引用对象错误:代码中写的message.reaction.id不存在,实际需要判断触发事件的反应所属消息ID,应该用reaction.message.id
  • 变量作用域错误:msg2只在第一个if分支内定义,第二个else if分支无法访问该变量
  • 监听器重复注册:每次执行execute函数都会给client新增一个全局的messageReactionAdd监听器,多次调用后会出现重复触发、内存泄漏问题
  • 缺少过滤逻辑:没有判断用户点击的表情是否为翻页箭头,也没有过滤无关消息的反应,其他消息的互动也会误触发逻辑

推荐修复方案(编辑消息实现,体验更流畅)

不需要删除原有消息重发,直接修改消息内容即可实现翻页效果,性能和用户体验更好:

async execute(message, client){
    // 提前定义所有分页内容,后续新增分页直接加在这里即可
    const pages = [
        'how are',
        'you?'
    ]
    // 定义翻页对应表情
    const prevEmoji = '◀'
    const nextEmoji = '▶'
    let currentPage = 0

    // 发送第一页内容
    const pageMsg = await message.channel.send(pages[currentPage])
    // 有多页时才添加下一页反应
    if (pages.length > 1) await pageMsg.react(nextEmoji)

    // 配置反应过滤器:仅允许触发命令的用户点击翻页箭头才生效
    const filter = (reaction, user) => {
        return !user.bot && 
               [prevEmoji, nextEmoji].includes(reaction.emoji.name) && 
               reaction.message.id === pageMsg.id &&
               user.id === message.author.id
    }

    // 创建临时反应收集器,10分钟无操作自动销毁避免内存泄漏
    const collector = pageMsg.createReactionCollector({ filter, time: 10 * 60 * 1000 })

    collector.on('collect', async (reaction, user) => {
        // 移除用户的点击痕迹,方便用户后续重复点击
        await reaction.users.remove(user.id)

        // 切换页码
        if (reaction.emoji.name === nextEmoji && currentPage < pages.length - 1) {
            currentPage++
        } else if (reaction.emoji.name === prevEmoji && currentPage > 0) {
            currentPage--
        }

        // 直接编辑消息内容更新分页
        await pageMsg.edit(pages[currentPage])

        // 调整显示的反应:第一页不显示上一页箭头,最后一页不显示下一页箭头
        if (currentPage === 0) {
            await pageMsg.reactions.cache.get(prevEmoji)?.remove()
            if (!pageMsg.reactions.cache.has(nextEmoji)) await pageMsg.react(nextEmoji)
        } else if (currentPage === pages.length - 1) {
            await pageMsg.reactions.cache.get(nextEmoji)?.remove()
            if (!pageMsg.reactions.cache.has(prevEmoji)) await pageMsg.react(prevEmoji)
        } else {
            if (!pageMsg.reactions.cache.has(prevEmoji)) await pageMsg.react(prevEmoji)
            if (!pageMsg.reactions.cache.has(nextEmoji)) await pageMsg.react(nextEmoji)
        }
    })

    // 收集器到期后移除所有反应,提示翻页已失效
    collector.on('end', () => {
        pageMsg.reactions.removeAll().catch(() => {})
    })
}

兼容原删除重发逻辑的修复版本

如果你要保留原有删除旧消息、发新消息的逻辑,可以使用下面的修复版本:

async execute(message, client){
    let currentMsg = await message.channel.send('how are')
    await currentMsg.react('▶')

    const filter = (reaction, user) => {
        return !user.bot && 
               ['◀', '▶'].includes(reaction.emoji.name) && 
               reaction.message.id === currentMsg.id &&
               user.id === message.author.id
    }

    const collector = currentMsg.createReactionCollector({ filter, time: 10 * 60 * 1000 })

    collector.on('collect', async () => {
        await currentMsg.delete()
        // 判断当前显示的是第一页还是第二页,切换到对应内容
        if (currentMsg.content === 'how are') {
            currentMsg = await message.channel.send('you?')
            await currentMsg.react('◀')
        } else {
            currentMsg = await message.channel.send('how are')
            await currentMsg.react('▶')
        }
        // 更新过滤器监听的消息ID
        collector.filter = (reaction, user) => {
            return !user.bot && 
                   ['◀', '▶'].includes(reaction.emoji.name) && 
                   reaction.message.id === currentMsg.id &&
                   user.id === message.author.id
        }
    })
}

内容的提问来源于stack exchange,提问作者Joaquin Parada

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.09.26 22:15:09