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

如何用discord.py实现Discord机器人的按钮式确认提示?

解决Discord机器人命令确认按钮的返回值问题

要实现confirmationPrompt()根据按钮点击返回True/False,核心是利用异步任务结果传递机制(asyncio.Future),因为按钮回调函数无法直接向外层函数返回值。以下是具体实现方案:

方案一:使用View + asyncio.Future(推荐)

这种方式符合discord.py的组件设计规范,代码结构清晰且易扩展:

import asyncio
import discord
from discord import app_commands

async def confirmationPrompt(interaction: discord.Interaction, warning: str, timeout: int = 60) -> bool:
    class ConfirmationButtons(discord.ui.View):
        def __init__(self):
            super().__init__(timeout=timeout)
            # 初始化Future对象,用于存储按钮点击结果
            self.future = asyncio.Future()

        @discord.ui.button(label='✅', style=discord.ButtonStyle.success)
        async def confirm(self, interaction: discord.Interaction, button: discord.ui.Button):
            # 限制仅发起命令的用户可操作
            if interaction.user != interaction.message.interaction.user:
                await interaction.response.send_message("只有发起命令的用户可以确认!", ephemeral=True)
                return
            # 设置Future结果为True,停止View监听
            self.future.set_result(True)
            await interaction.response.edit_message(content="已确认", embed=None, view=None)
            self.stop()

        @discord.ui.button(label='❌', style=discord.ButtonStyle.danger)
        async def cancel(self, interaction: discord.Interaction, button: discord.ui.Button):
            if interaction.user != interaction.message.interaction.user:
                await interaction.response.send_message("只有发起命令的用户可以取消!", ephemeral=True)
                return
            # 设置Future结果为False,停止View监听
            self.future.set_result(False)
            await interaction.response.edit_message(content="已取消", embed=None, view=None)
            self.stop()

        async def on_timeout(self):
            # 超时自动设置结果为False,并更新消息
            self.future.set_result(False)
            await interaction.edit_original_response(content="确认超时", embed=None, view=None)

    view = ConfirmationButtons()
    embed = discord.Embed(title=f"Are you sure you want to {warning}")
    await interaction.response.send_message(embed=embed, view=view)
    
    # 等待Future返回结果,返回给外层函数
    result = await view.future
    return result

关键逻辑说明

  1. 在ConfirmationButtons类中初始化asyncio.Future对象,作为结果传递的容器
  2. 按钮点击时,通过self.future.set_result()设置对应结果,并调用self.stop()停止View的交互监听
  3. 实现on_timeout方法,处理用户未点击的超时场景,自动返回False
  4. 外层函数等待view.future完成,将结果返回

方案二:使用wait_for监听交互事件

如果不想自定义View,也可以直接监听按钮交互事件,代码更直接但结构较零散:

import asyncio
import discord
from discord import app_commands

async def confirmationPrompt(interaction: discord.Interaction, warning: str, timeout: int = 60) -> bool:
    embed = discord.Embed(title=f"Are you sure you want to {warning}")
    # 创建按钮组件
    confirm_btn = discord.ui.Button(label='✅', style=discord.ButtonStyle.success)
    cancel_btn = discord.ui.Button(label='❌', style=discord.ButtonStyle.danger)
    view = discord.ui.View()
    view.add_item(confirm_btn)
    view.add_item(cancel_btn)
    
    msg = await interaction.response.send_message(embed=embed, view=view)
    
    # 定义交互检查逻辑:仅匹配当前消息和发起命令的用户
    def check(btn_interaction: discord.Interaction):
        return btn_interaction.message.id == msg.id and btn_interaction.user == interaction.user
    
    try:
        # 等待按钮交互事件
        btn_interaction = await interaction.client.wait_for('interaction', check=check, timeout=timeout)
        if btn_interaction.component.label == '✅':
            await btn_interaction.response.edit_message(content="已确认", embed=None, view=None)
            return True
        else:
            await btn_interaction.response.edit_message(content="已取消", embed=None, view=None)
            return False
    except asyncio.TimeoutError:
        # 超时处理
        await interaction.edit_original_response(content="确认超时", embed=None, view=None)
        return False

两种方案对比

  • 方案一(View+Future):更符合discord.py组件设计模式,便于后续扩展(如添加更多按钮、自定义样式),代码可维护性更高
  • 方案二(wait_for):代码更简洁直接,但需要手动处理事件监听和检查逻辑,扩展性较差

内容的提问来源于stack exchange,提问作者3LL KNJ

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.12 23:38:20