如何在 Discord.py 中限制按钮仅由特定角色用户点击

本文详解如何在 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 拥有线稿上色优化、图片重绘、人物姿势检测、涂鸦完善等功能

相关推荐
SAP上海工博云署几秒前
2026年中小企业SAP服务商选型技术解析
大数据·运维·数据库·人工智能·信息可视化·运维开发·信息与通信
涛声依旧-底层原理研究所几秒前
Node.js在高并发低延迟场景中的优势
java·人工智能·python·node.js
RestCloud1 分钟前
版本迭代丨谷云科技ETLCloud V4.2版本更新速览
数据库·doris·etl·etlcloud·数据集成平台·datahub·ftp处理
凯丨11 分钟前
200 行 Python 训练一个 GPT:Karpathy 的极简主义 AI 教育实验
人工智能·python·gpt
Adair_z11 分钟前
[SEO艺术重读] 第13篇 SEO教育与研究
java·网络·数据库
Mr. zhihao11 分钟前
BM25 混合检索详解:为什么向量检索不够,还要加一个关键词检索
python·rag·bm25
悟乙己12 分钟前
python DoWhy 库使用案例: SaaS 公司的客服案例
开发语言·python
不爱吃糖の糖糖15 分钟前
RAG 04:向量数据库与索引算法
数据库·算法
逍遥德18 分钟前
PostgreSQL --- JSON 函数详解
数据库·sql·postgresql·json
Larcher18 分钟前
后续:上次的优化又崩了?这次是 SQLite WAL 把 Codex 直接卡死了
数据库·人工智能·github