Discord.js v13 REST API实现/cat、/urban命令报错排查
Discord斜杠命令问题修复方案
问题根因汇总
/cat命令崩溃:原调用的随机猫图接口返回301重定向,undici默认不跟随重定向,拿到空响应体后JSON解析直接报错;同时原有响应解析逻辑无状态码校验,异常场景直接触发进程崩溃/urban命令返回空值:Urban Dictionary接口会拦截无合法User-Agent的请求,默认请求被403拦截,无法拿到正确的JSON返回结果- 代码缺失核心依赖引入与初始化逻辑,存在隐性报错
分步修复
1. 补全缺失的基础逻辑
你贴出的代码漏了discord.js核心模块引入、客户端初始化、登录逻辑,需要在代码开头和末尾补全:
// 开头补全引入 const { Client, Intents, MessageEmbed } = require('discord.js'); // 初始化客户端,开启公会意图支持斜杠命令 const client = new Client({ intents: [Intents.FLAGS.GUILDS] }); // --- 你原有写的undici引入、斜杠命令注册、工具函数等逻辑保持不变 --- // 代码末尾补全登录 client.login("你的机器人TOKEN");
注意:你注释掉的全局命令注册写法有误,
Routes.applicationGuildCommands必须传入guildId参数,注册全局命令请使用Routes.applicationCommands(clientId)
2. 优化响应解析逻辑,解决/cat命令崩溃问题
原有getJSONResponse方法没有校验HTTP状态、没有处理空响应,重写该方法,同时给请求添加自动跟随重定向配置:
async function getJSONResponse(res) { // 先校验响应状态,非200直接抛出错误,避免硬解析非JSON内容 if (res.statusCode !== 200) { throw new Error(`接口请求异常,状态码:${res.statusCode}`); } let fullBody = ''; for await (const data of res.body) { fullBody += data.toString(); } // 空内容校验 if (!fullBody.trim()) throw new Error('接口返回空内容'); return JSON.parse(fullBody); } // /cat命令逻辑修改 if (commandName === 'cat') { // 添加maxRedirections配置允许自动跟随重定向 const catResult = await request('https://aws.random.cat/meow', { maxRedirections: 5 }); const { file } = await getJSONResponse(catResult); interaction.editReply({ files: [{ attachment: file, name: 'cat.png' }] }); }
3. 修复/urban命令返回空值问题
给Urban Dictionary的请求添加合法User-Agent请求头,避免被接口拦截:
} else if (commandName === 'urban') { const term = interaction.options.getString('term'); const query = new URLSearchParams({ term }); // 添加请求头模拟正常浏览器请求,配置重定向跟随 const dictResult = await request(`https://api.urbandictionary.com/v0/define?${query}`, { headers: { 'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/120.0.0.0 Safari/537.36' }, maxRedirections: 5 }); const { list } = await getJSONResponse(dictResult); if (!list.length) { return interaction.editReply(`未找到**${term}**的相关结果。`); } const [answer] = list; const embed = new MessageEmbed() .setColor('#EFFF00') .setTitle(answer.word) .setURL(answer.permalink) .addFields( { name: '释义', value: trim(answer.definition, 1024) }, { name: '用法示例', value: trim(answer.example, 1024) }, { name: '评分', value: `${answer.thumbs_up} 赞 · ${answer.thumbs_down} 踩`, }, ); interaction.editReply({ embeds: [embed] }); }
4. 添加全局错误捕获,避免机器人崩溃
给交互回调加try/catch包裹,接口异常时友好提示,不会直接导致进程崩溃:
client.on('interactionCreate', async interaction => { if (!interaction.isCommand()) return; const { commandName } = interaction; await interaction.deferReply(); try { // 上面写的/cat、/urban命令判断逻辑全部放在try块内 } catch (err) { console.error('命令执行失败:', err); return interaction.editReply('命令执行出现异常,请稍后重试。'); } });
内容的提问来源于stack exchange,提问作者Izuuk
相关产品推荐
相关产品推荐

