Discord.js交互解析失败:AI图片生成机器人无法发送图片
问题描述
开发基于OpenAI的Discord图片生成机器人,运行index.js测试命令时,图片生成成功且URL已在控制台输出,但无法将图片发送至Discord。报错DiscordAPIError[10062]: Unknown interaction,调用回调接口返回405: Method Not Allowed。
相关代码
index.js
const fs = require('node:fs'); const path = require('node:path'); const { Client, Collection, Events, GatewayIntentBits } = require('discord.js'); const { token } = require('./config.json'); const client = new Client({ intents: [GatewayIntentBits.Guilds] }); client.commands = new Collection(); const foldersPath = path.join(__dirname, 'commands'); const commandFolders = fs.readdirSync(foldersPath); for (const folder of commandFolders) { const commandsPath = path.join(foldersPath, folder); const commandFiles = fs.readdirSync(commandsPath).filter((file) => file.endsWith('.js')); for (const file of commandFiles) { const filePath = path.join(commandsPath, file); const command = require(filePath); if ('data' in command && 'execute' in command) { client.commands.set(command.data.name, command); } else { console.log(`[WARNING] The command at ${filePath} is missing a required "data" or "execute" property.`); } } } client.once(Events.ClientReady, (readyClient) => { console.log(`Ready! Logged in as ${readyClient.user.tag}`); }); client.on(Events.InteractionCreate, async (interaction) => { if (!interaction.isChatInputCommand()) return; const command = interaction.client.commands.get(interaction.commandName); if (!command) { console.error(`No command matching ${interaction.commandName} was found.`); return; } try { await command.execute(interaction); } catch (error) { console.error(error); if (interaction.replied || interaction.deferred) { await interaction.followUp({ content: 'There was an error while executing this command!', ephemeral: true }); } else { await interaction.reply({ content: 'There was an error while executing this command!', ephemeral: true }); } } }); client.login(token);
commands/generate_images.js
const { SlashCommandBuilder } = require("discord.js"); const OpenAI = require("openai"); const openai = new OpenAI({ apiKey: "sk-proj-my-api-key", }); module.exports = { data: new SlashCommandBuilder() .setName("generate-images") .setDescription("Generate High Quality AI Images Using The Best Model!") .addStringOption((option) => option .setName("prompt") .setDescription("Prompt") .setRequired(true) ), async execute(interaction) { const promptInput = interaction.options.getString("prompt"); if (!promptInput) { interaction.reply("Please provide a prompt."); return; } try { const response = await openai.images.generate({ model: "dall-e-3", prompt: promptInput, n: 1, size: "1024x1024", }); console.log("Response:", response); interaction.reply(response.data); } catch (error) { console.error(error); interaction.reply("An error occurred while generating the image."); } }, };
报错信息
throw new DiscordAPIError(data, "code" in data ? data.code : data.error, status, method, url, requestData); ^ DiscordAPIError[10062]: Unknown interaction at handleErrors (C:\Users\Acer\Desktop\discord-bot\node_modules\@discordjs\rest\dist\index.js:722:13) at processTicksAndRejections (node:internal/process/task_queues:96:5) at async BurstHandler.runRequest (C:\Users\Acer\Desktop\discord-bot\node_modules\@discordjs\rest\dist\index.js:826:23) at async _REST.request (C:\Users\Acer\Desktop\discord-bot\node_modules\@discordjs\rest\dist\index.js:1266:22) at async ChatInputCommandInteraction.reply (C:\Users\Acer\Desktop\discord-bot\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: 'Unknown interaction', code: 10062 }, code: 10062, status: 404, method: 'POST', url: 'https://discord.com/api/v10/interactions/1231599602235605074/aW50ZXJhY3Rpb246MTIzMTU5OTYwMjIzNTYwNTA3NDpTQ0d2WjZUUENrbmVabHJzY29rSDZ2SmFrUVpCbTdoODZqZUcwQ3VWa0JFU3RoUHpYMHJpZzl6cXFHTnVJN1dycUNicXJTVFhZNzFMRDFoZkF4aW9pbm9XSlkzNkNTSndzakJhV09rWVp5cklKeUhVRVF2MThoeEJ0a2xlOEJvaw/callback' }
回调接口返回结果
{ "message": "405: Method Not Allowed", "code": 0 }
问题分析与解决方案
核心原因
- 交互超时:OpenAI生成图片的请求耗时较长,超过Discord交互3秒的响应时限,导致Discord判定交互失效,返回
Unknown interaction。 - 回复格式错误:直接将
response.data(OpenAI返回的图片数据数组)传递给interaction.reply(),会导致请求体中content字段为undefined,不符合Discord API要求,触发405错误。
解决步骤
1. 提前延迟交互响应
调用OpenAI API前,先执行interaction.deferReply()告知Discord机器人正在处理,避免超时。处理完成后用interaction.editReply()发送最终结果。
2. 正确格式化回复内容
从OpenAI响应中提取图片URL,构造符合Discord要求的回复内容(可直接发送链接或嵌入消息)。
修改后的generate_images.js代码
const { SlashCommandBuilder } = require("discord.js"); const OpenAI = require("openai"); const openai = new OpenAI({ apiKey: "sk-proj-my-api-key", }); module.exports = { data: new SlashCommandBuilder() .setName("generate-images") .setDescription("生成高质量AI图片!") .addStringOption((option) => option .setName("prompt") .setDescription("图片描述") .setRequired(true) ), async execute(interaction) { const promptInput = interaction.options.getString("prompt"); if (!promptInput) { await interaction.reply("请提供图片描述。"); return; } try { // 延迟响应,避免超时 await interaction.deferReply(); const response = await openai.images.generate({ model: "dall-e-3", prompt: promptInput, n: 1, size: "1024x1024", }); console.log("Response:", response); // 提取图片URL并构造回复 const imageUrl = response.data[0].url; await interaction.editReply({ content: imageUrl }); // 可选:用嵌入消息展示图片 // await interaction.editReply({ // embeds: [{ // title: "生成的图片", // image: { url: imageUrl } // }] // }); } catch (error) { console.error(error); // 根据交互状态选择回复方式 if (interaction.deferred) { await interaction.editReply("生成图片时出错了。"); } else { await interaction.reply("生成图片时出错了。"); } } }, };
额外注意事项
- 所有异步操作必须添加
await,避免未完成就执行后续代码。 - 确认Discord机器人拥有发送消息、嵌入内容的权限。
内容的提问来源于stack exchange,提问作者Ayan Shekhar
相关产品推荐
相关产品推荐

