基于discord.py开发生态机器人:按钮菜单功能实现求助
Discord.py 多功能菜单按钮实现方案
完全不需要改用JavaScript,discord.py的UI组件足以实现你需要的功能。下面是针对你的需求的完整修改方案:
核心修改点
- 修复按钮交互方法中的拼写错误(
interaction.responce→interaction.response) - 扩展
Menu类,添加三个目标按钮 - 实现每个按钮对应的功能逻辑
- 优化SQL查询方式,避免字符串格式化带来的注入风险
修改后的完整代码
import discord from discord.ext import commands import sqlite3 from config import settings bot = commands.Bot(command_prefix=settings['prefix'], intents=discord.Intents.all()) bot.remove_command('help') # 数据库连接初始化 connection = sqlite3.connect('server.db') cursor = connection.cursor() @bot.event async def on_ready(): cursor.execute("""CREATE TABLE IF NOT EXISTS users( name TEXT, id INT, cash BIGINT, rep INT, lvl INT )""") for guild in bot.guilds: for member in guild.members: # 使用参数化查询代替字符串格式化 cursor.execute("SELECT id FROM users WHERE id = ?", (member.id,)) if cursor.fetchone() is None: cursor.execute("INSERT INTO users VALUES (?, ?, ?, ?, ?)", (str(member), member.id, 0, 0, 1)) connection.commit() print('已登录为 {0.user}'.format(bot)) @bot.event async def on_member_join(member): cursor.execute("SELECT id FROM users WHERE id = ?", (member.id,)) if cursor.fetchone() is None: cursor.execute("INSERT INTO users VALUES (?, ?, ?, ?, ?)", (str(member), member.id, 0, 0, 1)) connection.commit() @bot.command(aliases=['balance', 'cash']) async def __balance(ctx, member: discord.Member = None): target = member or ctx.author cursor.execute("SELECT cash FROM users WHERE id = ?", (target.id,)) cash = cursor.fetchone()[0] await ctx.send(embed=discord.Embed( description=f"""Баланс **{target}** короче **{cash}**""" )) class Menu(discord.ui.View): def __init__(self): super().__init__(timeout=None) # 设置超时为None,让按钮长期有效 @discord.ui.button(label="Balance", style=discord.ButtonStyle.green) async def show_balance(self, button: discord.ui.Button, interaction: discord.Interaction): # 查询当前交互用户的余额 cursor.execute("SELECT cash FROM users WHERE id = ?", (interaction.user.id,)) cash = cursor.fetchone()[0] embed = discord.Embed(description=f"""Баланс **{interaction.user}** короче **{cash}**""") await interaction.response.send_message(embed=embed, ephemeral=True) # ephemeral=True仅用户可见 @discord.ui.button(label="Games", style=discord.ButtonStyle.blurple) async def show_games(self, button: discord.ui.Button, interaction: discord.Interaction): # 游戏功能占位,后续可扩展 embed = discord.Embed(title="游戏菜单", description="即将推出各类小游戏!") await interaction.response.send_message(embed=embed, ephemeral=True) @discord.ui.button(label="Profile", style=discord.ButtonStyle.red) async def show_profile(self, button: discord.ui.Button, interaction: discord.Interaction): # 查询用户的个人资料信息 cursor.execute("SELECT cash, rep, lvl FROM users WHERE id = ?", (interaction.user.id,)) data = cursor.fetchone() cash, rep, lvl = data # 生成带用户头像的Embed embed = discord.Embed(title=f"{interaction.user.name} 的个人资料", color=discord.Color.blue()) embed.set_thumbnail(url=interaction.user.display_avatar.url) embed.add_field(name="余额", value=str(cash), inline=True) embed.add_field(name="声望", value=str(rep), inline=True) embed.add_field(name="等级", value=str(lvl), inline=True) await interaction.response.send_message(embed=embed, ephemeral=True) @bot.command() async def menu(ctx): view = Menu() await ctx.reply("请选择操作:", view=view) bot.run(settings['token'])
关键功能说明
- Balance按钮:点击后查询当前用户的余额,发送仅用户可见的Embed消息
- Profile按钮:获取用户的头像、余额、声望、等级信息,生成美观的个人资料Embed
- Games按钮:预留了游戏菜单入口,你可以在这个方法中添加各类小游戏逻辑
- 持久化按钮:通过
timeout=None让菜单按钮不会过期,除非手动关闭
内容的提问来源于stack exchange,提问作者Venzo
相关产品推荐
相关产品推荐

