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

基于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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.19 13:14:55