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

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.20 00:25:29