如何在Discord.py Cog中为/sendinfo命令实现按钮持久化?
实现Discord机器人按钮持久化(Cogs架构)
1. 调整info.py中的按钮与视图
在info.py里给按钮设置唯一custom_id,将视图的timeout设为None(持久化必备),并在Cog初始化时注册视图:
import discord from discord import app_commands from discord.ext import commands # 定义持久化视图类 class InfoPersistentView(discord.ui.View): def __init__(self): # timeout设为None表示按钮永久有效 super().__init__(timeout=None) # 规则按钮(custom_id必须全局唯一) @discord.ui.button(label="Rules", style=discord.ButtonStyle.primary, custom_id="persistent_info_rules") async def rules_btn(self, interaction: discord.Interaction, button: discord.ui.Button): # 替换为你的规则展示逻辑 rule_embed = discord.Embed(title="服务器规则", description="1. 遵守社区规范\n2. 禁止刷屏", color=discord.Color.blue()) await interaction.response.send_message(embed=rule_embed, ephemeral=True) # 验证按钮(custom_id必须全局唯一) @discord.ui.button(label="Verify", style=discord.ButtonStyle.success, custom_id="persistent_info_verify") async def verify_btn(self, interaction: discord.Interaction, button: discord.ui.Button): # 替换为你的角色添加逻辑 member_role = interaction.guild.get_role(1234567890) # 改成你的Member角色ID if member_role: await interaction.user.add_roles(member_role) await interaction.response.send_message("已成功获取Member角色!", ephemeral=True) else: await interaction.response.send_message("未找到Member角色,请联系管理员", ephemeral=True) class Info(commands.Cog): def __init__(self, bot: commands.Bot): self.bot = bot # 注册持久化视图,机器人启动后自动绑定旧消息的按钮 self.bot.add_view(InfoPersistentView()) @app_commands.command(name="sendinfo", description="发送带规则/验证按钮的信息帖") async def sendinfo(self, interaction: discord.Interaction): info_embed = discord.Embed(title="欢迎加入服务器", description="点击下方按钮查看规则或完成验证", color=discord.Color.green()) # 使用持久化视图发送消息 await interaction.channel.send(embed=info_embed, view=InfoPersistentView()) await interaction.response.send_message("信息帖已发送", ephemeral=True) async def setup(bot: commands.Bot): await bot.add_cog(Info(bot))
2. 确保main.py正确加载Cog
主文件main.py只需正常加载Cog即可,无需额外修改(视图注册逻辑已放在Cog初始化中):
import discord from discord.ext import commands import os intents = discord.Intents.default() intents.message_content = True intents.members = True # 处理角色添加需要开启此权限 bot = commands.Bot(command_prefix="!", intents=intents) @bot.event async def on_ready(): await bot.tree.sync() print(f"已登录为 {bot.user}") async def load_cogs(): for filename in os.listdir("./cogs"): if filename.endswith(".py"): await bot.load_extension(f"cogs.{filename[:-3]}") async def main(): async with bot: await load_cogs() await bot.start("你的机器人令牌") if __name__ == "__main__": import asyncio asyncio.run(main())
关键注意事项
- custom_id全局唯一:每个按钮的
custom_id不能和其他视图的按钮重复,否则会触发冲突。 - 视图必须在启动时注册:通过
bot.add_view()注册视图,Cog的__init__方法是合适的时机,确保机器人启动后自动绑定历史消息的按钮。 - timeout必须设为None:如果视图有超时时间,超时后按钮会失效,持久化场景必须设置为
None。 - 无需重新发送旧消息:机器人重启后,已注册的视图会自动关联之前发送的带按钮消息,不需要重新发送信息帖。
内容的提问来源于stack exchange,提问作者DRags
相关产品推荐
相关产品推荐

