新闻中心

优化 Discord.py 视图中的交互检查逻辑

2025-10-28
浏览次数:
返回列表

优化 discord.py 视图中的交互检查逻辑

本文深入探讨了 `discord.py` 中 `discord.ui.View` 类的 `interaction_check` 方法的正确使用,以解决因过度限制导致部分按钮无法响应的问题。通过分析原始代码的逻辑缺陷,文章提供了一种分按钮定制交互检查的解决方案,确保不同功能按钮(如“确认”和“撤销”)能独立根据其业务逻辑(用户ID匹配或角色权限)进行权限验证,从而提升交互组件的灵活性和用户体验。

理解 discord.ui.View 和 interaction_check

在 discord.py 中,discord.ui.View 提供了一种构建交互式组件(如按钮、选择菜单)的方式,使其能够附加到消息上。View 类中的 interaction_check 方法是一个强大的工具,用于在任何组件的交互回调被触发之前,对交互进行全局性的预检查。如果 interaction_check 返回 False,则相应的组件回调将不会执行,并且可以向用户发送一条错误消息。

其基本作用是为视图中的所有组件定义一个通用的权限或条件。然而,不当的 interaction_check 逻辑可能导致某些按钮的功能被意外阻止,即使这些按钮在其自身的逻辑中包含了正确的权限检查。

遇到的问题:interaction_check 的过度限制

考虑以下场景:一个 View 包含“确认 (Acknowledge)”和“撤销 (Revoke)”两个按钮。

  • “确认”按钮应仅由特定用户(通过 user_id 参数传入)点击。
  • “撤销”按钮应仅由具有特定角色的用户点击。

原始的 interaction_check 实现如下:

async def interaction_check(self, interaction: discord.Interaction) -> bool:
    userid = int(self.user_id)
    if interaction.user.id == userid and interaction.data["custom_id"] == "acknowledge":
        return True
    else:
        await interaction.response.send_message("你无权使用此按钮。", ephemeral=True)
        return False

此代码段的逻辑是:只有当交互用户ID与 self.user_id 匹配,并且 被点击的按钮 custom_id 为 "acknowledge" 时,才允许交互继续。否则,无论点击哪个按钮,都会发送一条错误消息并阻止交互。

Pinokio Pinokio

Pinokio是一款开源的AI浏览器,可以安装运行各种AI模型和应用

Pinokio 232 查看详情 Pinokio

问题分析: 当用户点击“撤销”按钮时,interaction.data["custom_id"] 将是 "revoke"。此时,interaction.user.id == userid and interaction.data["custom_id"] == "acknowledge" 这个条件将评估为 False(因为 interaction.data["custom_id"] 不等于 "acknowledge")。因此,interaction_check 会立即返回 False,阻止“撤销”按钮的回调函数执行,即使“撤销”按钮内部有自己的角色检查逻辑。这就是导致“撤销”按钮无法工作的根本原因。

解决方案:分按钮定制 interaction_check 逻辑

为了解决这个问题,我们需要优化 interaction_check 的逻辑,使其能够区分不同的按钮,并应用相应的检查,或者在某些情况下允许交互通过,以便按钮自身的逻辑能够处理权限。

核心思想是:

  1. “确认”按钮: 仍然需要验证交互用户的ID是否与 self.user_id 匹配。
  2. “撤销”按钮: interaction_check 不应阻止它。它的角色权限验证应该在其自身的 @discord.ui.button 回调函数中处理。

以下是修改后的 MyView 类和 interaction_check 方法:

import discord
from discord import Embed, app_commands
from discord.app_commands import Choice

class MyView(discord.ui.View):
    def __init__(self, user_id: str):
        super().__init__(timeout=None) # Consider adding a timeout
        self.user_id = user_id

    async def interaction_check(self, interaction: discord.Interaction) -> bool:
        """
        根据按钮的 custom_id 进行条件检查,以允许不同按钮执行其特定的权限逻辑。
        """
        button_custom_id = interaction.data.get("custom_id")

        # 对于 "acknowledge" 按钮,执行用户ID匹配检查
        if button_custom_id == "acknowledge":
            if interaction.user.id == int(self.user_id):
                return True
            else:
                await interaction.response.send_message("你无权确认此消息。", ephemeral=True)
                return False

        # 对于 "revoke" 按钮,允许其通过 interaction_check,
        # 具体的角色权限检查将在其自身的异步回调函数中完成。
        elif button_custom_id == "revoke":
            return True 

        # 对于其他未明确处理的按钮,默认拒绝交互
        else:
            await interaction.response.send_message("你无权使用此按钮。", ephemeral=True)
            return False

    @discord.ui.button(label="Acknowledge", emoji="<:check:1135773225423491122>", style=discord.ButtonStyle.grey, custom_id="acknowledge")
    async def menu1(self, interaction: discord.Interaction, button: discord.ui.Button):
        # 这里的 interaction_check 已经确保只有授权用户才能点击此按钮
        new_embed = Embed.from_dict(interaction.message.embeds[0].to_dict())
        new_embed.set_footer(text=f'Sent by {interaction.user.name}     |     Acknowledged: ✔')
        await interaction.response.edit_message(embed=new_embed)
        button.disabled = True
        await interaction.message.edit(view=self)

    @discord.ui.button(label="Revoke", emoji="<:Cross:1135773287880867900>", style=discord.ButtonStyle.grey, custom_id="revoke")
    async def menu2(self, interaction: discord.Interaction, button: discord.ui.Button):
        # interaction_check 允许此按钮的回调执行,现在在此处进行角色检查
        user = interaction.guild.get_member(interaction.user.id)
        # 建议使用配置或环境变量存储角色ID,而非硬编码
        role_headquarters_id = 994233392478560297
        role_first_line_supervisors_id = 994233182532685825

        role1 = discord.utils.get(interaction.guild.roles, id=role_headquarters_id)
        role2 = discord.utils.get(interaction.guild.roles, id=role_first_line_supervisors_id)

        # 确保角色存在,避免NoneType错误
        if role1 and role2 and (role1 in user.roles or role2 in user.roles):
            await interaction.response.send_message(f"**惩罚已由 {interaction.user.mention} 撤销**", ephemeral=False)
            await interaction.message.delete()
        else:
            await interaction.response.send_message("你没有所需的角色来使用此按钮。", ephemeral=True)

# 你的机器人命令部分 (保持不变)
# @bot.tree.command(name="infract")
# ... (省略,与问题内容相同)

代码解释:

  1. 在修改后的 interaction_check 中,我们首先获取被点击按钮的 custom_id。
  2. 如果 custom_id 是 "acknowledge",则执行原始的用户ID匹配逻辑。
  3. 如果 custom_id 是 "revoke",我们直接 return True。这意味着 interaction_check 不会阻止“

以上就是优化 Discord.py 视图中的交互检查逻辑的详细内容,更多请关注其它相关文章!


# 这就是  # 吉林电脑网站建设  # 花卉网站建设规划书  # seo推广如何做秒收录  # 南昌企业营销推广  # 四平网站优化软件  # 网站优化排名参数  # 网站优化设计色彩  # 企业网络营销推广成功的  # 东莞网站优化方法  # 丹东网站关键词推广  # 将是  # 相关文章  # 所需  # 编码  # 将在  # 是一个  # 自己的  # 使其  # 可用性  # 回调  # 权限验证  # 环境变量  # ai  # 工具  # 回调函数  # edge  # app 


相关栏目: 【 科技资讯46185 】 【 网络学院92790


相关推荐: Pandas DataFrame 高效批量赋值:告别循环与笛卡尔积误区  2025俄罗斯Yandex最新入口 官方网站地址及浏览器下载指南  Angular Material 垂直步进器:实现底部到顶部排序的教程  Shopware订单对象中获取产品自定义字段的正确方法  React中useState与局部变量:理解组件状态管理与渲染机制  AO3中文官网链接_AO3网页版稳定镜像站  微信网页版官方入口直达 微信网页版网页版登录使用方法  漫蛙2网页版漫画入口 漫蛙漫画在线官方登录  Win11文件资源管理器卡顿怎么修 Win11重置资源管理器进程优化响应速度【修复方法】  文本文档写html代码怎么运行_文本文档html代码运行步骤【教程】  在Go Martini框架中高效服务动态生成图像的实践指南  优化HTML表单样式:解决输入框焦点跳动与元素间距问题  一加Ace 6T实拍样张首次公布!李杰:主摄实力完全看齐4K档性能旗舰  12306几点到几点不能订票? | 官方最新系统维护时间全解析  Golang并发任务中错误如何聚合_Golang goroutine error收集方式  Excel函数批量查找替换超快方法_Excel用REPLACE和FIND函数秒级替换  实现分段式页面滚动导航:CSS与J*aScript教程  win11如何卸载Windows更新补丁 Win11解决更新导致系统不稳定的问题【修复】  css子元素高度不一致导致布局错位怎么办_使用align-items:stretch解决高度差异  从J*aScript对象中精确提取指定属性的教程  微博网页版官方账号登录 微博网页版内容浏览使用指南  PPT平滑切换怎么做 PPT炫酷“平滑”切换动画制作教程【必学】  Go调试环境为何无法启动_Go调试器启动失败原因与解决策略  在Typer应用中优雅地处理和重组任意命令行参数  css卡片内容溢出如何处理_使用overflow隐藏或scroll显示内容  黑猫投诉统一入口官网 消费者权益保护投诉平台  Safari浏览器输入栏卡顿如何解决 Safari搜索建议与缓存清理  sublime如何优雅地处理行尾空格_sublime自动清理多余空白字符配置  痛风发作了怎么办? 快速止痛和后期饮食调理  夸克AO3官网入口_AO3镜像网站2025推荐  如何在Python中使用Optional类型处理可变对象并避免Pylint警告  《噬血代码2》新预告片发布 展示游戏剧情  网易大神账号申诉需要多久_网易大神账号申诉流程说明  sublime如何配置Go语言开发环境_sublime搭建Golang编译运行系统  msn官网入口地址手机版 msn官方网站手机最新链接  谷歌浏览器一键优化方案_谷歌浏览器直达主页极速不卡版  sublime怎么预览Markdown渲染效果_Markdown Preview插件 for sublime教程  Win11网速慢怎么解决 Win11网络设置优化解除限速  XML中包含HTML标签导致解析错误? 正确嵌入非XML数据的两种方法  飞书妙记怎样用语音转文字速记_飞书妙记用语音转文字速记【速记方法】  必由学登录入口 必由学官方网站在线访问链接  sublime侧边栏怎么增强功能_SideBarEnhancements for sublime安装与配置  QQ邮箱登录首页官网地址2026 QQ邮箱官方网页入口  J*aScript类型检查_j*ascript代码规范  Golang如何使用new_Go new分配内存机制讲解  Windows电脑怎么截图最方便_系统自带截图工具的5种神仙用法【技巧】  KFC早餐时段怎么领特惠代码_KFC早餐订餐优惠代码获取与使用说明  天猫双十一预售商品怎么退款_天猫双十一预售退款操作指南  EMS快递官网app_中国邮政速递物流手机客户端  Eclipse怎么运行工程_Eclipse工程运行配置说明 

搜索