如何获取特定频道内指定用户的全部消息并生成Embed
解决方案:Discord Bot 用户消息提取与 Embed 生成
场景回顾
当玩家触发命令后,Bot 会创建名为 newchannel 的临时频道,频道内的对话是固定流程:
- Bot: Hello, what's your name.
- User: BaconSoda479
- Bot: When is your birthday
- User: 21/06/1999
- Bot: Do you like this bot?
- User: Yes
需求目标
要把该用户的这三条回复提取出来,发送到指定频道并生成结构化的 Embed,格式如下:
User: BaconSoda479
Birthday: 21/06/1999
Opinion: Yes
现有思路的小问题
你提到的通过「第n条消息索引」直接获取内容的方式,比如 ${client.channels.get(newchannel.id).second.message},其实存在风险——如果频道里出现额外消息(比如系统自动发送的频道创建提示),索引就会错位,导致取到错误的内容。我推荐两种更可靠的实现方式:
方式一:用消息收集器(最健壮)
创建临时频道后,启动一个消息收集器,专门捕获目标用户的回复,这样能精准拿到我们需要的三条消息:
// 假设已经创建好 newchannel 对象,并且知道触发命令的用户是 commandUser const userResponses = []; // 创建消息收集器:只收集目标用户的非Bot消息,最多收集3条 const collector = newchannel.createMessageCollector({ filter: msg => msg.author.id === commandUser.id && !msg.author.bot, max: 3, time: 60000 // 可选:设置超时时间,比如1分钟内没回复就停止收集 }); // 每次收集到用户消息就存入数组 collector.on('collect', msg => { userResponses.push(msg.content); }); // 收集完成(或超时)后生成Embed并发送 collector.on('end', () => { // 解构数组,得到三个变量 const [username, birthday, opinion] = userResponses; // 创建Embed(这里以Discord.js v13+为例) const infoEmbed = new Discord.MessageEmbed() .setTitle('用户信息收集结果') .setColor('#0099ff') .addField('User', username, true) .addField('Birthday', birthday, true) .addField('Opinion', opinion, true); // 发送到指定频道,替换成你的目标频道ID const targetChannel = client.channels.cache.get('YOUR_TARGET_CHANNEL_ID'); if (targetChannel) { targetChannel.send({ embeds: [infoEmbed] }); } // 可选:完成后删除临时频道 newchannel.delete().catch(err => console.log('删除临时频道失败:', err)); });
方式二:通过消息历史获取(适合固定无干扰场景)
如果你能确保临时频道里只有Bot和用户的6条对话,没有其他额外消息,可以通过拉取频道消息历史来获取:
// 拉取频道最近的6条消息 newchannel.messages.fetch({ limit: 6 }) .then(messages => { // 消息历史默认是倒序的,反转后变成正序(Bot→User→Bot→User...) const sortedMessages = Array.from(messages.values()).reverse(); // 提取用户的三条回复(索引1、3、5) const username = sortedMessages[1].content; const birthday = sortedMessages[3].content; const opinion = sortedMessages[5].content; // 生成并发送Embed const infoEmbed = new Discord.MessageEmbed() .addField('User', username) .addField('Birthday', birthday) .addField('Opinion', opinion); client.channels.cache.get('YOUR_TARGET_CHANNEL_ID').send({ embeds: [infoEmbed] }); }) .catch(err => console.error('获取消息历史出错:', err));
关键注意事项
- 如果你用的是 Discord.js v12 及更早版本,发送Embed的方式是直接传
embed: infoEmbed而不是embeds: [infoEmbed]; - 消息收集器的方式更推荐,因为它能应对各种意外情况(比如用户中途发送了无关消息,或者系统有额外提示);
- 记得在代码里替换
YOUR_TARGET_CHANNEL_ID为你实际要发送的频道ID。
内容的提问来源于stack exchange,提问作者user8965201
相关产品推荐
相关产品推荐

