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

Discord.py按钮UI重启后交互失效,Windows正常但Linux/Mac异常

Discord机器人持久化按钮跨系统失效问题修复

你的问题核心是代码里同时混用了discord.Client和commands.Bot两个实例,还额外定义了VerifyViewBot类,导致持久化视图的注册逻辑混乱。Windows下偶然能工作是因为事件循环的执行顺序巧合,而Linux/Mac的事件循环调度更严格,直接暴露了实例冲突的问题。

问题分析

  • 你初始化了client = discord.Client(...)和bot = commands.Bot(...)两个独立的机器人实例,还定义了继承自commands.Bot的VerifyViewBot,这三个实例互相独立,视图注册的操作没关联到真正处理交互的实例上。
  • on_ready事件里同时调用bot.add_view和await bot.setup_hook(),但bot实例的setup_hook并没有被正确绑定到启动流程中,跨系统的事件循环差异导致注册逻辑失效。

修复方案

简化代码,只使用一个commands.Bot实例,在其setup_hook中注册持久化视图,用标准的命令装饰器替代on_message处理命令:

import discord
import config
from discord.ext import commands
from discord.ui import View, Button

# 初始化Bot实例,统一管理所有逻辑
intents = discord.Intents.all()
intents.message_content = True
bot = commands.Bot(command_prefix=config.PREFIX, intents=intents, help_command=None)

class VerifyButton(View):
    def __init__(self):
        # timeout=None 确保视图持久化
        super().__init__(timeout=None)

    @Button(label="Click me!", style=discord.ButtonStyle.green, custom_id='verify_button')
    async def click(self, interaction: discord.Interaction, button: Button):
        role_id = config.ROLE
        role = interaction.guild.get_role(role_id)
        
        if role in interaction.user.roles:
            await interaction.user.remove_roles(role)
            await interaction.response.send_message("已取消验证", ephemeral=True)
        else:
            await interaction.user.add_roles(role)
            await interaction.response.send_message("验证成功", ephemeral=True)

# 在setup_hook中注册持久化视图,启动时自动加载
@bot.event
async def setup_hook():
    bot.add_view(VerifyButton())

@bot.event
async def on_ready():
    print(f'已登录为 {bot.user}')

# 用标准命令装饰器替代on_message处理命令
@bot.command(name="verify")
async def send_verify_message(ctx):
    embed = discord.Embed(title="验证!", description="阅读规则后点击按钮完成验证!")
    await ctx.send(embed=embed, view=VerifyButton())

# 启动机器人
bot.run(config.TOKEN)

关键改动说明

  1. 移除所有冗余的机器人实例,只保留一个commands.Bot实例作为核心,避免实例冲突。
  2. 将setup_hook绑定到bot实例的事件上,确保机器人启动时就完成持久化视图的注册,这是discord.py官方推荐的持久化视图注册方式。
  3. 改用@bot.command()装饰器处理验证命令,替代on_message的手动判断,代码更规范且避免冲突。
  4. 优化了角色判断逻辑,直接用role in interaction.user.roles替代ID列表遍历,更简洁高效。

这样修改后,无论在Windows、Linux还是Mac系统下,机器人重启后持久化按钮都能正常响应交互。

内容的提问来源于stack exchange,提问作者Mizuka_owo

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.27 03:20:26