使用Discord.js开发Bot发送命令触发API错误求助
问题分析与解决方案
错误核心原因
从控制台日志能直接定位问题:你在Embed的第8个字段(索引7)里,直接把Discord.js的Presence对象(也就是代码里的userinfo.presen)传给了字段value,但Discord要求Embed的字段值必须是字符串类型,无法直接解析对象,所以抛出了类型错误。
另外你提到的UnhandledPromiseRejectionWarning,大概率是因为message.channel.send()返回的Promise没有做错误捕获处理,我们会一起解决这两个问题。
具体修复步骤
1. 把Presence对象转为可读字符串
不能直接把Presence对象塞给Embed字段,要提取其中的关键信息拼接成字符串。结合你就绪状态的配置,我们可以提取在线状态和游戏信息:
// 替换原来的{ name: "Presence", value: userinfo.presen, inline } { name: "Presence", value: `Status: ${userinfo.presen.status}\nGame: ${userinfo.presen.game?.name || "No game set"}`, inline }
这里用了可选链?.,避免Bot没有设置游戏时出现报错,提升代码健壮性。
2. 修复其他潜在类型问题
你的代码里还有几个字段是布尔值,虽然Discord.js能自动转换,但显式转为字符串更稳妥:
BOT?字段:用你定义好的status对象转成"Yes"/"No",即status[userinfo.bot]2FA?字段:同样用status[userinfo.mfa]It paid?字段:用status[userinfo.pre]Created at字段:你已经写了checkDays函数,应该用它把Date对象转成友好的字符串:checkDays(userinfo.createdat)
3. 处理Promise拒绝警告
给message.channel.send()添加错误捕获,避免控制台出现警告:
// 用.catch()捕获发送失败的情况 message.channel.send(/* Embed配置 */) .catch(err => console.error("发送用户信息Embed失败:", err)); // 如果你的命令函数是async的,也可以用try/catch async function handleUserInfoCommand(message) { try { await message.channel.send(/* Embed配置 */); } catch (err) { console.error("发送用户信息Embed失败:", err); } }
完整修复后的命令代码
const Discord = require('discord.js'); const client = new Discord.Client(); function checkDays(date) { let now = new Date(); let diff = now.getTime() - date.getTime(); let days = Math.floor(diff / 86400000); return days + (days == 1 ? " day" : " days") + " ago"; }; // 假设这是触发命令的逻辑,放在message事件里 client.on('message', message => { if (message.content === '!botinfo') { // 自定义触发命令的前缀 let inline = true; let userinfo = {}; userinfo.bot = message.client.user.bot; userinfo.createdat = message.client.user.createdAt; userinfo.discrim = message.client.user.discriminator; userinfo.id = message.client.user.id; userinfo.mfa = message.client.user.mfaEnabled; userinfo.pre = message.client.user.premium; userinfo.presen = message.client.user.presence; userinfo.tag = message.client.user.tag; userinfo.uname = message.client.user.username; userinfo.verified = message.client.user.verified; userinfo.avatar = message.client.user.avatarURL; const status = { false: "No", true: "Yes" }; // 用MessageEmbed类构建Embed,更易维护 const embed = new Discord.MessageEmbed() .setColor(3447003) .setAuthor(userinfo.uname) .setTitle(userinfo.uname) .setDescription("Info about this bot") .addFields( { name: "BOT?", value: status[userinfo.bot], inline }, { name: "Name", value: userinfo.uname, inline }, { name: "Discriminator", value: `#${userinfo.discrim}`, inline }, { name: "Client ID", value: userinfo.id, inline }, { name: "2FA?", value: status[userinfo.mfa], inline }, { name: "Premium?", value: status[userinfo.pre], inline }, { name: "Created at", value: checkDays(userinfo.createdat), inline }, { name: "Presence", value: `Status: ${userinfo.presen.status}\nGame: ${userinfo.presen.game?.name || "No game set"}`, inline } ) .setTimestamp(new Date()); // 发送并处理错误(v13+用embeds数组,v12及以下用embed字段) message.channel.send({ embeds: [embed] }) .catch(err => console.error("发送Bot信息失败:", err)); } }); // 你的就绪状态代码保持不变 client.on("ready", () => { console.log(`Listo, con ${client.users.size} usuarios, en ${client.channels.size} canales de ${client.guilds.size} servidores.`); client.user.setPresence( { status: "online", game: { name: `pp!help | Connected to ${client.guilds.size} servers and ${client.users.size} users!`, url: `https://m.youtube.com/watch?v=35XFAkwmU4c`, type: "STREAMING" } } ); }); // 记得替换成你的Bot令牌 client.login('YOUR_BOT_TOKEN');
注意:如果你的Discord.js版本是v13或更高,发送Embed需要用
embeds: [embed]格式;v12及以下用embed: embed即可。
额外提示
- 优先使用
MessageEmbed类构建Embed,比直接写字面量对象更清晰,也更容易排查问题。 - 处理Discord.js的API返回对象时,一定要注意字段的类型要求,Embed的
value只能是字符串、数字这类可序列化的类型,对象、数组都不行。
内容的提问来源于stack exchange,提问作者MarcZX10
相关产品推荐
相关产品推荐

