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

discord.js开发Discord机器人调用Steam API嵌入消息报EMBED_FIELD_VALUE错

问题描述
  • 开发场景:基于discord.js开发Discord机器人,需求为调用Steam API获取游戏实时在线人数,将返回数据嵌入消息发送到频道
  • 故障现象:代码运行时直接崩溃,终端抛出RangeError [EMBED_FIELD_VALUE]: MessageEmbed field values must be non-empty strings错误
  • 原实现代码:
const gtaUrl = 'https://api.steampowered.com/ISteamUserStats/GetNumberOfCurrentPlayers/v1/?key=KEY&format=json&appid=271590'
let gtaData ='';
request(gtaUrl,function(err,res,body){
    if(!err&&res.statusCode<400){
        gtaData +=body;
    }
})
const exampleEmbed =  new MessageEmbed()
.setColor('#0099ff')
.setTitle('Showing concurrent player numbers for some games')
.setDescription('the game')
.setThumbnail('https://i.imgur.com/FNviTdG.jpeg')
.addFields(
    { name: 'tf2 ', value: gtaData },
)
.addField('Inline field title', 'Some value here', true)
.setImage('https://i.imgur.com/AfFp7pu.png')
.setTimestamp()
message.channel.send({ embeds: [exampleEmbed] });
  • 完整报错栈:
if (!allowEmpty && data.length === 0) throw new error(errorMessage);
RangeError [EMBED_FIELD_VALUE]: MessageEmbed field values must be non-empty strings.
at Util.verifyString (D:\Code\discordBot\node_modules\discord.js\src\util\Util.js:428:49)
at MessageEmbed.normalizeField (D:\Code\discordBot\node_modules\discord.js\src\structures\MessageEmbed.js:544:19)
at D:\Code\discordBot\node_modules\discord.js\src\structures\MessageEmbed.js:565:14
at Array.map ()
at MessageEmbed.normalizeFields (D:\Code\discordBot\node_modules\discord.js\src\structures\MessageEmbed.js:564:8)
at MessageEmbed.addFields (D:\Code\discordBot\node_modules\discord.js\src\structures\MessageEmbed.js:328:42)
at steamStatus (D:\Code\discordBot\src\bot.js:112:3)
at process.processTicksAndRejections (node:internal/process/task_queues:95:5) {
[Symbol(code)]: 'EMBED_FIELD_VALUE'
}
根因分析

你的判断完全准确:

  1. 基于回调的request请求是异步非阻塞逻辑,JavaScript主线程不会等待接口返回、回调执行完成,就会直接往下执行构造MessageEmbed、发送消息的逻辑
  2. 构造嵌入消息时,gtaData还是初始化的空字符串,触发discord.js的字段非空校验,直接抛出错误
  3. 原逻辑存在额外缺陷:未对Steam返回的JSON数据做解析格式化,即使拿到数据直接塞原始JSON字符串可读性也很差,同时缺少请求异常处理分支,接口报错时会直接崩溃
修复方法

使用async/await语法改写异步逻辑,等接口请求完成、数据处理完毕后,再构造嵌入消息发送。Node.js 18及以上版本内置了fetchAPI,不需要额外安装第三方请求库,修复后代码如下:

// 注意:包裹该逻辑的函数必须添加async关键字
async function sendSteamPlayerEmbed(message) {
    const gtaUrl = 'https://api.steampowered.com/ISteamUserStats/GetNumberOfCurrentPlayers/v1/?key=KEY&format=json&appid=271590'
    try {
        // 等待接口请求完成
        const res = await fetch(gtaUrl)
        if (!res.ok) throw new Error(`接口请求异常,状态码:${res.status}`)
        // 解析返回的JSON数据,提取需要的在线人数字段
        const playerData = await res.json()
        const playerCount = playerData.response.player_count

        // 确认数据拿到后再构造嵌入消息
        const exampleEmbed =  new MessageEmbed()
        .setColor('#0099ff')
        .setTitle('Showing concurrent player numbers for some games')
        .setDescription('Steam游戏实时在线人数')
        .setThumbnail('https://i.imgur.com/FNviTdG.jpeg')
        .addFields(
            { name: 'GTA5 实时在线人数', value: `${playerCount}` },
            // 其他游戏的查询字段可按相同逻辑追加
        )
        .addField('数据更新时间', new Date().toLocaleString(), true)
        .setImage('https://i.imgur.com/AfFp7pu.png')
        .setTimestamp()
        // 执行发送操作
        message.channel.send({ embeds: [exampleEmbed] });
    } catch (err) {
        console.error('获取Steam数据失败:', err)
        message.channel.send('获取游戏在线人数失败,请稍后再试')
    }
}

// 调用函数传入message对象即可
sendSteamPlayerEmbed(message)

如果你使用的是Node.js 18以下版本,可以先安装node-fetch包实现相同逻辑,也可以将原有request回调封装为Promise版本再用await等待结果,核心规则不变:必须等接口数据返回、处理完成后,再构造嵌入对象、执行发送操作。

内容的提问来源于stack exchange,提问作者Constantine Jon

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.28 15:21:20