基于discord.js实现表情交互活动签到列表面板的bot开发求助
discord.js 可直接复用的交互嵌入式活动面板实现
零额外存储的核心逻辑
- 直接复用discord.js自带的表情反应用户列表做统计,不需要搭建数据库,大幅降低实现复杂度
- 用户添加/移除表情时自动触发面板刷新,实时更新参与人数和成员列表
- 固定按「参与数/100」格式展示统计值,数值下方自动列出所有参与成员昵称
可直接抄用的代码
所有需要自定义的配置项单独放在最开头,修改内容只需要改动这部分,后续核心逻辑不需要调整,避免卡壳:
// 自定义配置区 const activityOptions = [ { emoji: '👍', optionName: '确定参与' }, { emoji: '👎', optionName: '不参与' }, { emoji: '🤷', optionName: '待定' } ]; const MAX_PARTICIPANT_LIMIT = 100; // 固定显示的分母,修改数值直接改这里
发送活动面板的逻辑,直接接入你已有的斜杠命令触发流程即可:
// 触发后发送活动面板 async function launchActivityPanel(interaction) { // 初始化嵌入式面板 const activityEmbed = new EmbedBuilder() .setTitle('活动参与统计') .setDescription('点击对应表情选择你的参与状态,统计值会实时更新'); // 给每个选项加初始占位内容 const initialFields = activityOptions.map(option => ({ name: `${option.emoji} ${option.optionName}`, value: `0/${MAX_PARTICIPANT_LIMIT}\n暂无成员参与` })); activityEmbed.addFields(initialFields); // 发送面板,获取消息本体用于后续编辑 const panel = await interaction.reply({ embeds: [activityEmbed], fetchReply: true }); // 给每个选项加上对应表情反应 for (const option of activityOptions) { await panel.react(option.emoji); } }
全局监听表情变化的逻辑,放在bot初始化完成后的事件监听块即可:
// 表情变化触发的统一处理逻辑(加/删表情都会触发) async function refreshPanelOnReactionChange(reaction, user) { // 跳过非活动面板的消息,不做多余处理 if (reaction.message.partial) await reaction.message.fetch(); const matchedOption = activityOptions.find(opt => opt.emoji === reaction.emoji.toString()); if (!matchedOption) return; // 跳过bot自身的反应,不把bot计入统计 if (user.bot) return; // 拉取所有点击该表情的真实成员 const reactionUsers = await reaction.users.fetch(); const realParticipants = reactionUsers.filter(u => !u.bot); const participantCount = realParticipants.size; const participantList = realParticipants.map(u => u.globalName || u.username).join('\n') || '暂无成员参与'; // 更新面板的对应字段,不改动其他选项的内容 const currentEmbed = EmbedBuilder.from(reaction.message.embeds[0]); const targetFieldIndex = currentEmbed.data.fields.findIndex(field => field.name.startsWith(matchedOption.emoji)); currentEmbed.data.fields[targetFieldIndex] = { name: `${matchedOption.emoji} ${matchedOption.optionName}`, value: `${participantCount}/${MAX_PARTICIPANT_LIMIT}\n${participantList}` }; // 直接编辑原面板,不发新消息 await reaction.message.edit({ embeds: [currentEmbed] }); } // 同时绑定加表情、删表情的事件,保证实时更新 client.on('messageReactionAdd', refreshPanelOnReactionChange); client.on('messageReactionRemove', refreshPanelOnReactionChange);
新手避坑提示
- 运行前先去Discord开发者门户的bot设置页,打开「Server Members Intent」「Message Content Intent」两个权限开关,重启bot即可解决拉取反应用户报错的问题
- 如果使用服务器自定义表情,只要把配置区里的emoji字符串换成对应表情的id即可,不需要修改核心逻辑
- 全程不需要手动存储参与数据,所有数据来自Discord原生的反应记录,不会出现数据不同步的问题
内容的提问来源于stack exchange,提问作者Stribbits
相关产品推荐
相关产品推荐

