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

discord.py中斜杠命令触发Unknown interaction(404)错误的求助

discord.py中斜杠命令触发Unknown interaction(404)错误的求助

兄弟,这个bug卡一周确实够闹心的!我之前也踩过类似的坑,帮你捋捋核心问题——你遇到的Unknown interaction(404),根源是对Discord交互的响应时机太晚,再加上同步代码阻塞了事件循环,双重坑叠一起了。

问题出在哪?

Discord对斜杠命令有个硬要求:必须在3秒内对交互做出响应(要么直接发消息,要么用defer告诉Discord“我正在处理,稍后给结果”)。如果超过3秒没任何动作,Discord会直接把这个交互标记为“已失效”,之后再调用defer或者followup自然就会报404。

看你现在的代码逻辑:

# 先同步调用外部API(耗时操作)
response = retrieval.conversation_manager.get_response(text_to_send)
# 才告诉Discord我要处理
await interaction.response.defer()

这完全搞反了!同步的requests请求会直接卡住整个bot的事件循环,等API返回结果时,早就超过3秒的窗口了,Discord已经不认这个交互了,哪怕你后面发普通字符串也没用。

怎么修复?

按这几步来,保证解决问题:

  1. 先defer,抢占3秒窗口
    只要通过了频道权限检查,第一件事就是调用defer,把交互的超时时间延长到15分钟,给后续操作争取时间。

  2. 把同步请求改成异步
    同步的requests会阻塞asyncio事件循环,导致bot整个卡住,必须换成异步HTTP库aiohttp,让事件循环能正常处理其他任务。

  3. 调整代码顺序
    权限检查 → 立即defer → 处理耗时逻辑 → 用followup发结果

修改后的代码示例

main.py 关键部分修改

@tree.command(name="name", description="description")
async def faaq(
    interaction: discord.Interaction,
    text_to_send: str,
):
    # 先做频道检查,这个很快,不会超时
    if interaction.channel_id != settings.CHANNEL_ID:
        await interaction.response.send_message(
            "This command can't be used in this channel.", ephemeral=True
        )
        return
    
    # 关键!立即defer,必须在3秒内执行
    await interaction.response.defer(ephemeral=True)
    
    # 现在再去调用异步的API请求
    response = await retrieval.conversation_manager.get_response(text_to_send)
    
    # 用followup发送最终结果
    await interaction.followup.send(f"{response}", ephemeral=True)

retrieval.py 改成异步版本

import aiohttp
import settings
import asyncio

headers = {
    "x-api-key": settings.CHATPDF_API_KEY,
    "Content-Type": "application/json",
}

async def qa_bot(question):
    data = {
        "sourceId": settings.SOURCE_ID,
        "messages": [
            {
                "role": "user",
                "content": question,
            }
        ],
    }
    
    # 用aiohttp做异步请求,不阻塞事件循环
    async with aiohttp.ClientSession() as session:
        async with session.post(
            "https://api.chatpdf.com/v1/chats/message",
            headers=headers,
            json=data
        ) as response:
            if response.status == 200:
                result = await response.json()
                return result["content"]
            else:
                print("Status:", response.status)
                print("Error:", await response.text())
                return "抱歉,获取回答时出现错误,请稍后再试。"

class ConversationManager:
    async def get_response(self, query):
        response = await qa_bot(query)
        return response

conversation_manager = ConversationManager()

# 本地测试的CLI也改成异步
async def test_cli():
    while True:
        user_input = input("User: ")
        if user_input.lower() == "exit":
            print("Bot: Goodbye!")
            break
        response = await conversation_manager.get_response(user_input)
        print("Bot:", response)

if __name__ == "__main__":
    asyncio.run(test_cli())

额外提醒

  • 测试的时候,一定要确保defer是第一个和交互相关的操作(除了快速的权限检查),哪怕你后面sleep30秒再发消息,也不会再报404了。
  • defer的时候可以传ephemeral=True,这样后续的followup默认也是临时消息,不用重复传参。

备注:内容来源于stack exchange,提问作者doordashcon

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.04.21 09:08:02