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

使用discord.py创建抽奖交互时遭遇Unknown Interaction错误

Discord抽奖机器人Unknown Interaction问题解决

问题背景

使用discord.py开发抽奖机器人时,执行/startgive命令创建抽奖,调用create_giveaway异步请求仪表盘API成功创建抽奖,但无法在服务器发送Discord消息,报错Unknown Interaction。尝试过用self.bot.loop.create_task(self.create_giveaway(data))绕过,但需要额外请求获取抽奖列表,觉得不合理。

交互命令startgive代码

@app_commands.command(name="startgive", description="starts a giveaway")
@app_commands.describe(
    duration="duration of the giveaway", 
    winners="number of winners",
    prize="the prize being given away",
)
async def startgive(self, interaction: discord.Interaction, duration: str, winners: int, prize: str):
    if interaction.user.guild_permissions.administrator:
        try:
            if (winners <= 0):
                await interaction.response.send_message("Type non-negative number of winners!", ephemeral=True)
            else:
                created_at = datetime.now()
                duration = parser.parse(duration)
                duration = duration + round(created_at.timestamp())
            
                embed = None
                try:        
                    last_id = self.giveaways.pop()['id']
                    self.id = int(last_id) + 1
                except:
                    self.id = 1

                btn = GiveawayButton(self, self.id)

                giveaway = await self.create_giveaway({
                    'guild_id': interaction.guild.id,
                    'prize': prize,
                    'entries': None,
                    'winners': None,
                    'possible_winners': winners,
                    'duration': str(datetime.fromtimestamp(duration)),
                    'created_at': str(created_at),
                    'ended': False,
                })

                giveaway['created_at'] = datetime.fromtimestamp(duration)
                giveaway['interaction'] = interaction
                giveaway['entries'] = []
                giveaway['winners'] = []
                giveaway['btn'] = btn

                embed = await self.create_embed(giveaway)
                giveaway['embed'] = embed

                await interaction.response.send_message(embed=embed, view=btn)
                self.task_launcher(giveaway, 1)
        except Exception as e:
            print(e)
            await interaction.response.send_message("Invalid time format! (1 minutes/1m)", ephemeral=True)
    else:
        await interaction.response.send_message("You don't have permissions to use this.", ephemeral=True)

create_giveaway函数代码

async def create_giveaway(self, data):
    endpoint = self.url + "/create-giveaway/"
    async with aiohttp.ClientSession() as session:
        async with session.post(endpoint, json=data) as r:
            if r.status == 200:
                await self.get_giveaways()
                return await r.json()

问题原因

Discord要求交互必须在3秒内完成响应,如果create_giveaway中的API请求耗时超过3秒,交互会话会被Discord服务器标记为过期,后续调用interaction.response.send_message就会触发Unknown Interaction错误。

解决方案

核心思路:先快速响应Discord交互,再处理API请求和发送抽奖消息。

修改后的startgive代码

@app_commands.command(name="startgive", description="starts a giveaway")
@app_commands.describe(
    duration="duration of the giveaway", 
    winners="number of winners",
    prize="the prize being given away",
)
async def startgive(self, interaction: discord.Interaction, duration: str, winners: int, prize: str):
    if not interaction.user.guild_permissions.administrator:
        await interaction.response.send_message("You don't have permissions to use this.", ephemeral=True)
        return

    if winners <= 0:
        await interaction.response.send_message("Type non-negative number of winners!", ephemeral=True)
        return

    try:
        # 先延迟响应,告诉Discord我们正在处理,避免3秒超时
        await interaction.response.defer(ephemeral=False)

        created_at = datetime.now()
        duration = parser.parse(duration)
        duration = duration + round(created_at.timestamp())
        
        try:        
            last_id = self.giveaways.pop()['id']
            self.id = int(last_id) + 1
        except:
            self.id = 1

        btn = GiveawayButton(self, self.id)

        # 调用API创建抽奖
        giveaway = await self.create_giveaway({
            'guild_id': interaction.guild.id,
            'prize': prize,
            'entries': None,
            'winners': None,
            'possible_winners': winners,
            'duration': str(datetime.fromtimestamp(duration)),
            'created_at': str(created_at),
            'ended': False,
        })

        giveaway['created_at'] = datetime.fromtimestamp(duration)
        giveaway['interaction'] = interaction
        giveaway['entries'] = []
        giveaway['winners'] = []
        giveaway['btn'] = btn

        embed = await self.create_embed(giveaway)
        giveaway['embed'] = embed

        # 用followup发送最终的抽奖消息
        await interaction.followup.send(embed=embed, view=btn)
        self.task_launcher(giveaway, 1)
    except Exception as e:
        print(e)
        # 如果处理出错,用followup发送错误提示
        await interaction.followup.send("Invalid time format! (1 minutes/1m)", ephemeral=True)

关键修改点

  1. 提前响应交互:使用await interaction.response.defer(ephemeral=False)告诉Discord机器人正在处理请求,延长交互有效期。
  2. 改用followup发送消息:处理完API请求后,用interaction.followup.send()发送最终的抽奖消息,避免过期的交互会话。
  3. 调整代码结构:把权限和参数校验提前,减少不必要的嵌套逻辑。

这样既不需要用create_task绕过,也能保证交互响应在Discord的超时限制内,同时正常完成API请求和抽奖消息发送。

内容的提问来源于stack exchange,提问作者jakuboldziej

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.16 04:55:37