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

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
}

问题分析与解决方案

核心原因

  1. 交互超时:OpenAI生成图片的请求耗时较长,超过Discord交互3秒的响应时限,导致Discord判定交互失效,返回Unknown interaction。
  2. 回复格式错误:直接将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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.25 10:19:43