如何用discord.py制作带按钮的Discord Rich Embed消息?求资源链接
Hey there! Those buttons you're seeing on IdleRPG's embeds are Discord Message Components—Discord's official system for adding interactive elements like buttons, select menus, and more to messages. Discord.py added full support for these starting in version 2.0, so first make sure you're on a recent version of the library.
Step 1: Update discord.py
First, upgrade to the latest version to access component features:
pip install -U discord.py
Step 2: Example Implementation
Here's a complete, working example that replicates the IdleRPG-style embed with interactive buttons:
import discord from discord import appcommands from discord.ext import commands # Initialize bot with required intents bot = commands.Bot(command_prefix="!", intents=discord.Intents.default()) @bot.event async def on_ready(): print(f'Logged in as {bot.user}') # Sync slash commands (required for tree-based commands) try: synced_commands = await bot.tree.sync() print(f"Synced {len(synced_commands)} slash command(s)") except Exception as e: print(f"Command sync error: {e}") # Slash command to send an IdleRPG-style menu @bot.tree.command(name="idle_menu", description="Sends an interactive RPG menu embed") async def send_idle_menu(interaction: discord.Interaction): # Build your embed content embed = discord.Embed( title="IdleRPG Main Menu", description="Choose an option below to continue your adventure!", color=discord.Color.gold() ) embed.add_field(name="Stats", value="View your character's current stats", inline=False) embed.add_field(name="Quest", value="Start a new quest to earn rewards", inline=False) embed.set_footer(text="Click a button to proceed") # Create interactive buttons stats_button = discord.ui.Button( label="View Stats", style=discord.ButtonStyle.success, custom_id="stats_button" ) quest_button = discord.ui.Button( label="Start Quest", style=discord.ButtonStyle.danger, custom_id="quest_button" ) # Create a View container to hold the buttons menu_view = discord.ui.View() menu_view.add_item(stats_button) menu_view.add_item(quest_button) # Callback function to handle button clicks async def handle_button_click(interaction: discord.Interaction): # Use custom_id to identify which button was pressed button_id = interaction.data["custom_id"] if button_id == "stats_button": await interaction.response.send_message("Your stats: Level 10, HP 150, Gold 500", ephemeral=True) elif button_id == "quest_button": await interaction.response.send_message("You've started a quest! Defeat 5 goblins to complete it.", ephemeral=True) # Bind the callback to both buttons stats_button.callback = handle_button_click quest_button.callback = handle_button_click # Send the embed with the interactive buttons await interaction.response.send_message(embed=embed, view=menu_view) # Run the bot with your token bot.run("YOUR_BOT_TOKEN_HERE")
Key Concepts Explained
discord.ui.View: This acts as a container for all interactive components. You add buttons/menus to it and pass it alongside your embed when sending a message.discord.ui.Button: Creates a button with customizable text, color (viastyle), and a uniquecustom_idto distinguish it from other buttons in callbacks.- Callback Functions: These functions trigger when a button is clicked. Use the
custom_idto determine which button was pressed and respond appropriately. - Ephemeral Messages: The
ephemeral=Trueflag makes responses only visible to the user who clicked the button—perfect for private RPG menu interactions.
For Traditional Prefix Commands
If you prefer using prefix-based commands instead of slash commands, here's a quick adaptation:
@bot.command() async def idle_menu_prefix(ctx): # Reuse the same embed and view setup from the slash command example embed = discord.Embed( title="IdleRPG Main Menu", description="Choose an option below to continue your adventure!", color=discord.Color.gold() ) embed.add_field(name="Stats", value="View your character's current stats", inline=False) embed.add_field(name="Quest", value="Start a new quest to earn rewards", inline=False) stats_button = discord.ui.Button(label="View Stats", style=discord.ButtonStyle.success, custom_id="stats_btn") quest_button = discord.ui.Button(label="Start Quest", style=discord.ButtonStyle.danger, custom_id="quest_btn") menu_view = discord.ui.View() menu_view.add_item(stats_button) menu_view.add_item(quest_button) async def handle_click(interaction): if interaction.data["custom_id"] == "stats_btn": await interaction.response.send_message("Your stats: Level 10, HP 150, Gold 500", ephemeral=True) elif interaction.data["custom_id"] == "quest_btn": await interaction.response.send_message("Quest started! Defeat 5 goblins.", ephemeral=True) stats_button.callback = handle_click quest_button.callback = handle_click # Send via ctx instead of interaction await ctx.send(embed=embed, view=menu_view)
Just make sure your bot has the necessary intents enabled (Message Content Intent is required for prefix commands in newer versions).
内容的提问来源于stack exchange,提问作者Legion

