如何修改Discord Bot实现OpenAI与DisTube功能互斥?
解决Discord机器人指令与OpenAI功能冲突问题
问题描述
使用OpenAI API和DisTube开发的Discord机器人,在用户发送带指定前缀(如?)的音乐指令(如?play)时,会同时执行音乐指令和OpenAI聊天回复。需要实现带前缀的有效指令仅触发音乐功能,禁用AI回复,且不通过分频道解决。
问题根源
当前代码的messageCreate事件中,先执行OpenAI聊天逻辑,再处理指令逻辑。只要消息带前缀且符合频道/提及条件,就会先触发AI回复,再执行指令,导致两者同时运行。
解决方案
调整messageCreate事件中的逻辑顺序:先处理指令,匹配到有效指令则直接返回,不执行后续AI逻辑;仅当消息不是有效指令时,才触发OpenAI聊天功能。
修改后的完整messageCreate事件代码
client.on('messageCreate', async message => { if (message.author.bot || !message.guild) return; // 优先处理带前缀的指令 if (message.content.startsWith(prefix)) { const args = message.content.slice(prefix.length).trim().split(/ +/g); const command = args.shift().toLowerCase(); const cmd = client.commands.get(command) || client.commands.get(client.aliases.get(command)); if (cmd) { // 执行有效指令并跳过AI逻辑 if (cmd.inVoiceChannel && !message.member.voice.channel) { return message.channel.send(`${client.emotes.error} | You must be in a voice channel!`); } try { await cmd.run(client, message, args); } catch (e) { console.error(e); message.channel.send(`${client.emotes.error} | Error: \`${e}\``); } return; // 终止后续代码执行 } } // 仅处理非指令类的AI聊天请求 if (!CHANNELS.includes(message.channelId) && !message.mentions.users.has(client.user.id)) return; await message.channel.sendTyping(); const sendTypingInterval = setInterval(() => { message.channel.sendTyping(); }, 5000); let conversation = []; conversation.push({ role: 'system', content: "I'm A Friendly Chatbot And Here For Help :)" }) let prevMessages = await message.channel.messages.fetch({ limit: 10 }); prevMessages.reverse(); prevMessages.forEach((msg) => { if (msg.author.bot && msg.author.id !== client.user.id) return; const username = msg.author.username.replace(/\s+/g, '_').replace(/[^\w\s]/gi, ''); if (msg.author.id === client.user.id) { conversation.push({ role: 'assistant', name: username, content: msg.content, }); return; } conversation.push({ role: 'user', name: username, content: msg.content, }); }) const response = await openai.chat.completions .create({ model: 'gpt-3.5-turbo', messages: conversation, }) .catch((error) => console.error('OpenAI Error:\n', error)); clearInterval(sendTypingInterval); if(!response) { message.reply('I Have Some Trouble With OpenAI API. Try Again In A Moment.'); return; } const responseMessage = response.choices[0].message.content; const chunkSizeLimit = 2000; for (let i = 0; i < responseMessage.length; i += chunkSizeLimit) { const chunk = responseMessage.substring(i, i + chunkSizeLimit); await message.reply(chunk); } });
关键修改点
- 逻辑顺序调换:将指令处理逻辑移至OpenAI逻辑之前,确保指令优先执行。
- 终止后续执行:匹配到有效指令并执行后,通过
return直接终止事件回调,避免进入AI逻辑。 - AI触发条件调整:移除原有的前缀判断,AI仅处理非指令消息(如提及机器人的消息、指定频道内的普通聊天)。
效果验证
- 发送带前缀的有效音乐指令(如
?play):机器人仅执行音乐播放功能,无AI回复。 - 发送普通聊天消息或提及机器人的消息:正常触发OpenAI聊天回复。
- 发送带前缀的无效指令(如
?invalid):会触发AI回复,符合预期。
内容的提问来源于stack exchange,提问作者bemreq
相关产品推荐
相关产品推荐

