本文详解如何在 discord.py 的 discord.ui.Button 中实现基于角色的访问控制,通过运行时检查用户角色权限来动态启用或禁用按钮交互,而非错误地使用命令装饰器。 本文详解如何在 discord.py 的 `discord.ui.button` 中实现基于角色的访问控制,通过运行时检查用户角色权限来动态启用或禁用按钮交互,而非错误地使用命令装饰器。在 Discord.py 的 UI 系统(discord.ui.View / discord.ui.Button)中,@commands.has_role() 这类装饰器完全不适用------它仅作用于 commands.Bot 的命令上下文(如 @bot.command()),而按钮回调函数属于异步事件处理器,运行在 Interaction 上下文中,无命令权限系统介入。若强行添加该装饰器,不仅无效,还会导致运行时异常或静默失败。? 正确做法是:在按钮回调内部主动检查用户是否拥有指定角色,并根据结果决定是否执行业务逻辑;若权限不足,则调用 interaction.response.defer(ephemeral=True) 向用户返回不可见的响应(避免"此交互已过期"错误),并可选发送私密提示。以下是修正后的完整示例(含关键注释与健壮性增强):import discordfrom discord import ui, Interactionfrom datetime import datetime, timedeltaimport pytzimport timeclass SimpleView(discord.ui.View): def init(self): self.start_time = None self.stop_time = None super().init(timeout=None) @discord.ui.button(label="?? ENTRATA", style=discord.ButtonStyle.green, custom_id="btn_entrata") async def entrata(self, interaction: Interaction, button: ui.Button): # ? 检查用户是否拥有 "??♂? FUORI SERVIZIO" 角色(请替换为实际角色ID) target_role_id = 123456789012345678 # ← 替换为你的角色ID(整数!) role = interaction.guild.get_role(target_role_id) if not role or role not in interaction.user.roles: await interaction.response.send_message( "? 你没有权限使用此按钮:需拥有 `??♂? FUORI SERVIZIO` 角色。", ephemeral=True ) return # ? 权限通过:执行业务逻辑 orario_it = datetime.now(pytz.timezone('Europe/Rome')) orario = orario_it.strftime('%H:%M') data = orario_it.strftime('%Y-%m-%d') # 补充缺失的 data 变量定义 SimpleView.start_time = time.time() channel = interaction.client.get_channel(1214495527924928522) if not channel: await interaction.response.send_message("?? 目标频道不可用,请联系管理员。", ephemeral=True) return embed = discord.Embed(color=0x23a559) embed.set_thumbnail(url="https://shft.cl/img/c/cdn.discordapp.com-101395680655364460.webp") embed.add_field(name="?? ENTRATA ??", value="", inline=False) embed.add_field(name="NOME:", value=f"{interaction.user.mention}", inline=True) embed.add_field(name="", value="", inline=True) embed.add_field(name="DATA:", value=f"{data}", inline=True) embed.add_field(name="ORARIO:", value=f"{orario}", inline=True) embed.set_footer(text="ARMERIA200") await channel.send(embed=embed) await interaction.response.send_message( f"***SEI ENTRATO IN SERVIZIO ALLE: {orario}.***", ephemeral=True ) @discord.ui.button(label="?? USCITA", style=discord.ButtonStyle.red, custom_id="btn_uscita") async def uscita(self, interaction: Interaction, button: ui.Button): # ? 检查 "??♂? IN SERVIZIO" 角色(同样替换为真实ID) target_role_id = 987654321098765432 # ← 替换为你的角色ID role = interaction.guild.get_role(target_role_id) if not role or role not in interaction.user.roles: await interaction.response.send_message( "? 你没有权限使用此按钮:需拥有 `??♂? IN SERVIZIO` 角色。", ephemeral=True ) return # ? 执行退出逻辑 orario_it = datetime.now(pytz.timezone('Europe/Rome')) orario = orario_it.strftime('%H:%M') data = orario_it.strftime('%Y-%m-%d') if SimpleView.start_time is None: await interaction.response.send_message( "?? 你尚未执行'ENTRATA'操作,无法计算服务时长。", ephemeral=True ) return SimpleView.stop_time = time.time() elapsed_time = SimpleView.stop_time - SimpleView.start_time time_d = timedelta(seconds=int(elapsed_time)) channel = interaction.client.get_channel(1215061241270374400) if not channel: await interaction.response.send_message("?? 目标频道不可用,请联系管理员。", ephemeral=True) return embed = discord.Embed(color=0xda373c) embed.set_thumbnail(url="https://shft.cl/img/c/cdn.discordapp.com-101395680655364460.webp") embed.add_field(name="?? USCITA ??", value="", inline=False) embed.add_field(name="NOME:", value=f"{interaction.user.mention}", inline=True) embed.add_field(name="DATA:", value=f"{data}", inline=True) embed.add_field(name="ORARIO:", value=f"{orario}", inline=True) embed.add_field(name="TEMPO IN SERVIZIO:", value=f"{time_d}", inline=True) embed.set_footer(text="ARMERIA200") await channel.send(embed=embed) await interaction.response.send_message( f"***SEI USCITO DI SERVIZIO ALLE: {orario}, DOPO: {time_d}***", ephemeral=True )? 关键注意事项: 稿定AI 拥有线稿上色优化、图片重绘、人物姿势检测、涂鸦完善等功能
相关推荐
baidu_340998822 小时前
C#怎么实现图片缩略图生成 C#如何批量生成图片的缩略图指定尺寸保持比例不变形【图像】qq_372906932 小时前
CSS如何引入CSS预加载器配置_优化样式编译流程提升效率2401_897190552 小时前
CSS如何使用currentColor关键字_让颜色自动继承父级属性qq_342295822 小时前
HTML怎么创建评论区域_HTML嵌套评论语义结构【详解】Absurd5872 小时前
mysql如何配置临时账号权限_mysql带期限的用户授权a1117762 小时前
jetpack5.0配置对应版本的torch和 torchvisionNavicat中国2 小时前
Navicat 视频简介 | 数据管理之数据编辑器Lyyaoo.3 小时前
【JAVA基础面经】JVM的内存模型Java后端的Ai之路4 小时前
Text-to-SQL与智能问数完全指南:基本概念、核心原理、Python实战教学及企业项目落地