使用discord.js通过表情反应转移Discord频道embed消息报错如何解决
报错根因
你触发Cannot send an empty message报错的直接原因是消息内容为空,代码里存在两个核心逻辑错误导致:
messageReactionAdd事件的参数使用错误:该事件触发时的第一个入参是MessageReaction(反应对象),不是你以为的Message(消息对象),你直接从反应对象里解构content和embeds字段只能拿到undefined,相当于给channel.send传了空参数,触发API报错- 未做内容非空校验:即使获取到了正确的消息对象,也可能出现纯附件、纯贴纸的无内容消息,直接发送也会触发相同报错
其他存在的问题
- 未限定触发条件:当前代码只要任意用户添加任意反应就会触发转发,没有限定触发表情、监听频道,也没有过滤机器人自己的反应,会出现大量误触发
- 未处理缓存外消息:如果用户给机器人上线前发送的旧消息加反应,这部分消息不在本地缓存中,直接读取会拿不到完整数据,需要开启partial配置处理
- 过时API使用:discord.js v14及以上版本已经弃用
message.delete({timeout: xxx})的写法,需要单独用setTimeout实现延迟删除
完整修复方案
步骤1:调整Client初始化配置
开启必要的意图和partial配置:
// v13版本写法,v14可将Intents替换为对应GatewayIntentBits导入即可 const { Client, Intents } = require('discord.js') const client = new Client({ intents: [ Intents.FLAGS.GUILDS, Intents.FLAGS.GUILD_MESSAGES, Intents.FLAGS.GUILD_MESSAGE_REACTIONS // 必须开启消息反应意图 ], partials: ['MESSAGE', 'CHANNEL', 'REACTION'] // 开启partial支持缓存外的消息/反应数据拉取 })
步骤2:替换事件监听代码
client.on("messageReactionAdd", async (reaction, user) => { // 过滤机器人自己的反应 if (user.bot) return // 拉取缓存外的partial反应完整数据 if (reaction.partial) { try { await reaction.fetch() } catch (err) { console.error('反应数据拉取失败:', err) return } } // 此处替换为你要触发转发的目标表情,比如✅ const TRIGGER_EMOJI = '✅' if (reaction.emoji.name !== TRIGGER_EMOJI) return // 获取被添加反应的原消息,判断是否在监听的源频道内 const originalMsg = reaction.message if (originalMsg.channel.id !== analiseChannelID) return // 获取目标转发频道 const targetChannel = client.channels.cache.get(aprovadasChannelID) if (!targetChannel) return // 组装发送参数,只传存在的非空字段 const sendOptions = {} if (originalMsg.content.trim()) sendOptions.content = originalMsg.content if (originalMsg.embeds.length) sendOptions.embeds = originalMsg.embeds if (originalMsg.attachments.size) sendOptions.files = Array.from(originalMsg.attachments.values()) // 无有效内容时跳过发送,避免报错 if (Object.keys(sendOptions).length === 0) return // 发送消息+延迟删除 targetChannel.send(sendOptions) .then(sentMsg => setTimeout(() => sentMsg.delete(), 3000)) .catch(console.error) })
内容的提问来源于stack exchange,提问作者Maker__
相关产品推荐
相关产品推荐

