discord.py 持久化按钮重启后失效问题求助
问题排查与修复
你的Verify按钮重启后失效,核心原因是未在机器人启动时注册持久化视图,同时代码还存在几处语法/逻辑错误,以下是具体修复步骤:
核心问题与修复点
- 注册持久化视图:机器人启动后必须显式注册带有
timeout=None的视图,否则重启后无法识别之前发送的持久化按钮。 - 修复视图初始化错误:原代码中
__init__方法格式错误,且未传入并保存client实例,导致按钮回调无法访问数据库。 - 修正数据库更新逻辑:
replace_one方法参数格式错误,需明确查询条件与更新文档。 - 移除无效参数传递:创建view时传入的
role=role_id_int无意义,角色ID已存储在数据库中,无需在视图中保存。
修正后的完整代码
import discord from discord import app_commands import re import asyncio class buttonHandler(discord.ui.View): def __init__(self, client): super().__init__(timeout=None) self.client = client # 保存client实例,用于数据库操作 @discord.ui.button(label="Verify", style=discord.ButtonStyle.primary, custom_id='persistent_view:primary') async def buttons_verify(self, interaction: discord.Interaction, button: discord.ui.Button): db = self.client.mongoConnect["zbot"] collection = db["Verify"] verify_data = collection.find_one({"_id": interaction.guild_id}) # 处理未配置的情况 if not verify_data: await interaction.response.send_message("服务器未配置验证角色", ephemeral=True) return role = interaction.guild.get_role(verify_data['roles']) # 处理角色不存在的情况 if not role: await interaction.response.send_message("配置的验证角色已不存在", ephemeral=True) return if role not in interaction.user.roles: await interaction.user.add_roles(role) await interaction.response.send_message("Welcome to the server", ephemeral=True) else: await interaction.response.send_message("Already Verified", ephemeral=True) class rules(commands.Cog): def __init__(self, client: commands.Bot): self.client = client @app_commands.command(name="rules", description="(Admin only)add rules and make a reaction please please add a role named Member for this to work") async def self_role(self, interaction: discord.Interaction, channel: str, role: str): db = self.client.mongoConnect["zbot"] collection = db["Verify"] # 提取纯ID数字 role_id_int = int(re.sub(r'[^0-9]', '', role)) channel_id_int = int(re.sub(r'[^0-9]', '', channel)) target_channel = self.client.get_channel(channel_id_int) # 校验频道是否存在 if not target_channel: await interaction.response.send_message("指定频道不存在", ephemeral=True) return await interaction.response.send_message("请输入规则内容") def check(m): return m.author == interaction.user and m.channel == interaction.channel try: msg = await self.client.wait_for('message', timeout=120.0, check=check) except asyncio.TimeoutError: await interaction.followup.send("超时未输入内容,操作取消", ephemeral=True) return # 发送带持久化按钮的消息 view = buttonHandler(self.client) await target_channel.send(msg.content, view=view) # 更新数据库 if not await collection.find_one({"_id": interaction.guild_id}): newData = {"_id": interaction.guild_id, "roles": role_id_int} await collection.insert_one(newData) else: await collection.replace_one( {"_id": interaction.guild_id}, {"roles": role_id_int} ) await interaction.followup.send("规则消息已发送,验证按钮配置完成", ephemeral=True) # 机器人启动时注册持久化视图 @client.event async def on_ready(): await client.add_view(buttonHandler(client)) print(f"Logged in as {client.user}")
额外注意事项
- 确保使用**discord.py 2.0+**版本,持久化视图仅在该版本及以上支持
- 机器人需拥有
Manage Roles权限才能为用户添加角色 - 发送规则消息的频道,机器人需具备发送消息的权限
内容的提问来源于stack exchange,提问作者Zeph108
相关产品推荐
相关产品推荐

