使用 REST API 实现 Discord 机器人
我正在尝试制作自己的 discord 机器人(在 discord.js v13 中)。我找到了有关此主题的官方 discord.js 指南 和 他们的示例代码 ,并且我正在尝试使用/重用那里的代码来构建我自己的机器人。
这个想法是在斜杠命令
“item”
之后获取用户输入(因此
/item:firebrand
),将该用户输入传递到URL(这允许您从后端/API获取有关该项目的信息)并使用收到的响应来填充嵌入的各个字段,这些字段被发送回用户。
我能够传递用户输入并将其添加到 URL,从而返回可用的链接,但在创建嵌入之前代码会中断。我在代码中输入了一些
console.log
命令,以查看哪里出了问题。
在下面的代码中查看
console.log
的位置。
-
控制台日志 1:
{"items":[{"id":14,"name":"Frost Brand","type":"1-h wpn","constlevel":4,"mainlevel":1,"mpath":"W1","gemcost":"5W","screenshot":"/items/14/screenshot"}],"similarity":-0
- 控制台日志 2: https://dom5api.illwiki.com/items?match=fuzzy&name=frostbrand
-
控制台日志 3:
[object Object]
-
控制台日志 4:
[object Object]
-
控制台日志 5:
undefined
- TypeError:无法读取未定义的属性(读取“length”)
我猜我之所以收到 TypeError 是因为
{ list } 为
undefined
。这可能是因为
itemSearchResult.body
返回了
[object Object]
作为响应,但我不知道如何修复它。
const { SlashCommandBuilder } = require('@discordjs/builders');
const { MessageEmbed } = require('discord.js');
const { request } = require('undici');
const { ITEM_URL, BASE_URL } = require('../utils/utils');
module.exports = {
data: new SlashCommandBuilder()
.setName('item')
.setDescription('Replies with information about an item')
.addStringOption(option => option.setName('item_name').setDescription('Enter the name of the item')),
async execute(interaction) {
async function getJSONResponse(body) {
let fullBody = '';
for await (const data of body) {
fullBody += data.toString();
console.log(`Console log 1: `+fullBody);
}
return JSON.parse(fullBody);
}
const itemName = interaction.options.getString('item_name');
const itemSearchResult = await request(ITEM_URL + encodeURIComponent(itemName));
console.log(`Console log 2: `+ITEM_URL + encodeURIComponent(itemName));
console.log(`Console log 3: `+itemSearchResult.body);
console.log(`Console log 4: `+itemSearchResult.body.toString())
const { list } = await getJSONResponse(itemSearchResult.body);
console.log(`Console log 5: `+list)
if (!list.length) {
await interaction.reply(`No results found for **${itemName}**.`);
}
const [answer] = list;
const itemEmbed = new MessageEmbed()
.setColor('#000000')
.setTitle(answer.name)
.setURL('X')
.setAuthor({ name: 'Author' })
.setDescription('Lot of hassle, but hey, it was working!')
.setImage(BASE_URL + answer.screenshot)
.setTimestamp()
.setFooter({ text: 'A small step for X, a giant leap for X' });
await interaction.reply({ embeds: [itemEmbed] });
},
};
我尝试在网上和 StackOverflow 上搜索错误消息/类似情况,但一无所获。非常感谢您的帮助!
正如您在回答中提到的,返回的对象中没有
list
项。它应该是
items
。此外,您收到
[object Object]
是因为您隐式将返回的对象强制转换为字符串(即
console.log(`Console log 3: `+itemSearchResult.body`)
。
我回答的原因是您可以摆脱那个丑陋的
getJSONResponse()
函数并使用内置的
body mixin
来简化您的代码:
async execute(interaction) {
const itemName = interaction.options.getString('item_name');
const { body } = await request(ITEM_URL + encodeURIComponent(itemName));
const { items } = await body.json();
if (!items.length)
await interaction.reply(`No results found for **${itemName}**.`);
const [answer] = items;
const itemEmbed = new MessageEmbed()
.setColor('#000000')
.setTitle(answer.name)
.setAuthor({ name: 'Author' })
.setDescription('Lot of hassle, but hey, it was working!')
.setImage(BASE_URL + answer.screenshot)
.setTimestamp()
.setFooter({ text: 'A small step for X, a giant leap for X' });
await interaction.reply({ embeds: [itemEmbed] });
},
让朋友看看我的代码并帮忙。
问题出在
const { list } = await getJSONResponse(itemSearchResult.body);
,因为 API 没有传递列表。
有效/正确的代码是:
const itemName = interaction.options.getString('item_name');
const itemSearchResult = await request(ITEM_URL + encodeURIComponent(itemName));
const response = await getJSONResponse(itemSearchResult.body);
const items = response.items;
const firstItem = response.items[0];