Discord机器人调用editReply触发InteractionAlreadyReplied错误求助
问题分析与解决方案
错误原因
- 未捕获OpenAI API请求错误:代码中
openai.createCompletion请求未被包裹在try-catch中,一旦API请求失败(如密钥无效、网络问题),会抛出未处理的Promise错误直接导致机器人崩溃。 - catch块回复逻辑未适配交互状态:错误发生时直接调用
followUp,未考虑交互当前的状态,可能因重复操作触发InteractionAlreadyReplied错误。
修复步骤
- 将所有异步操作(包括OpenAI请求)放入
try块,确保所有错误都能被捕获。 - 移除重复的
responseMessage变量定义,避免作用域混淆。 - 在
catch块中根据交互的deferred或replied状态选择合适的回复方式:- 若交互已延迟回复但未完成,使用
editReply修改延迟的回复。 - 若交互已完成回复,使用
followUp发送追加消息。
- 若交互已延迟回复但未完成,使用
修改后的代码
module.exports = { data: new SlashCommandBuilder() .setName("chat-gpt") .setDescription("chat-gpt-3") .addStringOption(option => option.setName('prompt') .setDescription('Ask Anything') .setRequired(true)), async execute(interaction, client) { const prompt = interaction.options.getString('prompt'); await interaction.deferReply(); const configuration = new Configuration({ apiKey: "nvm", }); const openai = new OpenAIApi(configuration); try { const response = await openai.createCompletion({ model: 'text-davinci-003', prompt: prompt, max_tokens: 2048, temperature: 0.7, top_p: 1, frequency_penalty: 0.0, presence_penalty: 0.0, }); const responseMessage = response.data.choices[0].text; if (responseMessage.length >= 2000) { const attachment = new AttachmentBuilder(Buffer.from(responseMessage, 'utf-8'), { name: 'chatgpt-response.txt' }); const limitexceed = new EmbedBuilder() .setTitle(`Reached 2000 characters`) .setDescription(`Sorry, but you have already reached the limit of 2000 characters`) .setColor(`#FF6961`); await interaction.editReply({ embeds: [limitexceed], files: [attachment] }); } else { const responded = new EmbedBuilder() .setTitle(`You said: ${prompt}`) .setDescription(`\`\`\`${responseMessage}\`\`\``) .setColor(`#77DD77`); await interaction.editReply({ embeds: [responded] }); } } catch (error) { console.error(error); // 根据交互状态选择回复方式 if (interaction.deferred && !interaction.replied) { await interaction.editReply({ content: `Error: ${error.message}` }); } else if (interaction.replied) { await interaction.followUp({ content: `Error: ${error.message}` }); } } return; }, };
额外说明
- 确保你的Discord.js版本支持
interaction.deferred和interaction.replied属性(v14及以上版本均支持)。 - 生产环境中不要硬编码API密钥,建议使用环境变量管理敏感信息。
内容的提问来源于stack exchange,提问作者Darcel
相关产品推荐
相关产品推荐

