基于Discord.js+MongoDB的宝可梦盒子命令:解决‘Cannot send an empty message’错误
问题解决:Discord类宝可梦命令的Embed展示与数据库逻辑问题
问题概述
开发Discord上的好友捕捉类宝可梦命令时遇到两个核心问题:
- 每次捕捉新用户会生成单独数据库条目(当前逻辑正确,但可优化)
- 无法生成Embed展示用户捕捉盒子,反复触发
Cannot send an empty message错误
原核心代码
捕捉逻辑
// Check if the Forgemon exists in the database. let nameBox = await fmBoxSchema.findOne({ User: user, Username: user.username, Guild: interaction.guild.id, name: fmTarget.forgemon }); // Forgemon is not caught yet, add it to the data if (!nameBox) { nameBox = new fmBoxSchema({ User: user, Username: user.username, Guild: interaction.guild.id, name: fmTarget.forgemon, caught: 0, }); await nameBox.save(); // Set the Forgemon's "caught" count. nameBox.caught = 1; await nameBox.save(); }
盒子展示逻辑
// Get the user's Pokémon from the database. const userForgemon = await fmBoxSchema.findOne({ User }); // Create a message that lists the user's Pokémon. let message = "```"; if (userForgemon) { for (const [name, caught] of Object.entries(userForgemon)) { message += `${name} - Caught ${caught} times\n`; } } else { message = "You have not caught any Pokémon yet."; } message += "```"; // Send the message to the user. let userPFP = user.displayAvatarURL(); boxEmbed = new EmbedBuilder() .setTitle(`${user.username}'s Box.`) .setThumbnail(userPFP) .setDescription(message) interaction.reply({ embed: boxEmbed })
错误信息
throw new DiscordAPIError(data, "code" in data ? data.code : data.error, status, method, url, requestData); ^ DiscordAPIError[50006]: Cannot send an empty message at handleErrors (D:\Bots\TestBot - V14\node_modules\@discordjs\rest\dist\index.js:640:13) at processTicksAndRejections (node:internal/process/task_queues:96:5) at async BurstHandler.runRequest (D:\Bots\TestBot - V14\node_modules\@discordjs\rest\dist\index.js:736:23) at async REST.request (D:\Bots\TestBot - V14\node_modules\@discordjs\rest\dist\index.js:1387:22) at async ChatInputCommandInteraction.reply (D:\Bots\TestBot - V14\node_modules\discord.js\src\structures\interfaces\InteractionResponses.js:111:5) { requestBody: { files: [], json: { type: 4, data: { content: undefined, tts: false, nonce: undefined, embeds: undefined, components: undefined, username: undefined, avatar_url: undefined, allowed_mentions: undefined, flags: undefined, message_reference: undefined, attachments: undefined, sticker_ids: undefined, thread_name: undefined } } }, rawError: { message: 'Cannot send an empty message', code: 50006 }, code: 50006, status: 400, method: 'POST', url: 'https://discord.com/api/v10/interactions/1115070713695567924/aW50ZXJhY3Rpb246MTExNTA3MDcxMzY5NTU2NzkyNDpjbHN0d2ZzTGcxRXJUMUdKMEE0WWdZRDdtR3NJTnhWN1hMSnBxblpkV3Y0bFplWUZibnBoOXhPdlVkU2ZqNVY4VGpRb0lCaUJscVVhWnZ3TmhuSHdvZlhVOWx5S2ZlN2tqa0UzNkYyUlZkTVdVYkk1c2VSS3E4MmJUVDZDVXhYNw/callback' }
问题根源与修复方案
1. 空消息错误核心原因
Discord.js v14中,interaction.reply的嵌入消息参数必须是复数形式的embeds(数组),而非单数embed。原代码中使用{ embed: boxEmbed }会导致API请求的embeds字段为undefined,被判定为空消息。
2. 数据获取逻辑错误
findOne仅返回匹配的第一条记录,无法获取用户的所有捕捉条目,必须使用find来查询全部记录。
3. 遍历逻辑冗余
直接遍历MongoDB文档的所有属性会包含_id、User等无关字段,应仅提取name和caught字段。
4. 数据库操作优化
原捕捉逻辑中两次调用save(),可合并为一次,减少数据库交互。同时建议存储用户ID而非用户对象,避免序列化问题。
修复后的代码
优化后的捕捉逻辑
// 检查目标是否已存在(建议存用户ID而非对象) let nameBox = await fmBoxSchema.findOne({ User: user.id, Guild: interaction.guild.id, name: fmTarget.forgemon }); if (!nameBox) { // 直接初始化caught为1,无需两次save nameBox = new fmBoxSchema({ User: user.id, Username: user.username, Guild: interaction.guild.id, name: fmTarget.forgemon, caught: 1 }); } else { // 已存在则次数+1 nameBox.caught += 1; } await nameBox.save();
修复后的盒子展示逻辑
// 获取用户的所有捕捉记录 const userForgemonList = await fmBoxSchema.find({ User: user.id }); let message = "```"; if (userForgemonList.length > 0) { // 遍历每条记录,仅展示需要的字段 userForgemonList.forEach(entry => { message += `${entry.name} - 已捕捉 ${entry.caught} 次\n`; }); } else { message = "你还没有捕捉任何好友哦。"; } message += "```"; const userPFP = user.displayAvatarURL(); const boxEmbed = new EmbedBuilder() .setTitle(`${user.username}的捕捉盒子`) .setThumbnail(userPFP) .setDescription(message); // 使用v14要求的embeds数组参数 interaction.reply({ embeds: [boxEmbed] });
内容的提问来源于stack exchange,提问作者Josh
相关产品推荐
相关产品推荐

