Tarjeta de perfil
Una tarjeta de perfil para un comando /perfil. Usa Container, Section con Thumbnail, Separator, Text Display y Action Row.
{ "flags": 32768, "components": [ { "type": 17, "accent_color": 5793266, "components": [ { "type": 9, "components": [ { "type": 10, "content": "# Ana García" }, { "type": 10, "content": "-# @ana · Miembro desde <t:1609459200:D>" }, { "type": 10, "content": "🏆 **Nivel 42** · 12 350 XP" } ], "accessory": { "type": 11, "media": { "url": "attachment://avatar.png" }, "description": "Avatar de Ana" } }, { "type": 14, "divider": true, "spacing": 2 }, { "type": 10, "content": "### 📊 Estadísticas\n- **Mensajes:** 8 214\n- **Tiempo en voz:** 120 h\n- **Insignias:** 🥇 🎨 🎮" }, { "type": 14, "divider": false, "spacing": 1 }, { "type": 10, "content": "### 🖼️ Últimas capturas" }, { "type": 12, "items": [ { "media": { "url": "attachment://mountains.png" } }, { "media": { "url": "attachment://sunset.png" } }, { "media": { "url": "attachment://forest.png" } } ] }, { "type": 1, "components": [ { "type": 2, "style": 1, "label": "Dar reputación", "custom_id": "rep:123456789012345678", "emoji": { "name": "⭐" } }, { "type": 2, "style": 2, "label": "Ver insignias", "custom_id": "insignias:123456789012345678" } ] } ] } ]}Cómo está construida
Sección titulada «Cómo está construida»- Container con el color de la marca (
accent_color). - Section: el nombre y los datos a la izquierda, el avatar a la derecha.
- Separator grande con línea para separar la cabecera.
- Text Display con una lista markdown para las estadísticas.
- Media Gallery con 3 imágenes.
- Action Row con botones que llevan el ID del usuario en el
custom_id.
Envía el JSON de arriba en payload_json junto con las imágenes como multipart/form-data.
import { ContainerBuilder, ButtonBuilder, ButtonStyle, SeparatorSpacingSize, MessageFlags } from 'discord.js';
function profileCard(user, stats) { return new ContainerBuilder() .setAccentColor(0x5865f2) .addSectionComponents((section) => section .addTextDisplayComponents( (text) => text.setContent(`# ${user.displayName}`), (text) => text.setContent(`-# @${user.username}`), (text) => text.setContent(`🏆 **Nivel ${stats.level}** · ${stats.xp} XP`), ) .setThumbnailAccessory((thumbnail) => thumbnail.setURL(user.displayAvatarURL()).setDescription(`Avatar de ${user.displayName}`), ), ) .addSeparatorComponents((separator) => separator.setSpacing(SeparatorSpacingSize.Large)) .addTextDisplayComponents((text) => text.setContent(`### 📊 Estadísticas\n- **Mensajes:** ${stats.messages}`), ) .addActionRowComponents((row) => row.setComponents( new ButtonBuilder().setCustomId(`rep:${user.id}`).setLabel('Dar reputación').setEmoji('⭐').setStyle(ButtonStyle.Primary), new ButtonBuilder().setCustomId(`insignias:${user.id}`).setLabel('Ver insignias').setStyle(ButtonStyle.Secondary), ), );}
await interaction.reply({ flags: MessageFlags.IsComponentsV2, components: [profileCard(interaction.user, { level: 42, xp: 12350, messages: 8214 })],});def profile_card(user: discord.User, level: int, xp: int, messages: int) -> discord.ui.LayoutView: view = discord.ui.LayoutView() view.add_item( discord.ui.Container( discord.ui.Section( f"# {user.display_name}", f"-# @{user.name}", f"🏆 **Nivel {level}** · {xp} XP", accessory=discord.ui.Thumbnail(user.display_avatar.url, description=f"Avatar de {user.display_name}"), ), discord.ui.Separator(spacing=discord.SeparatorSpacing.large), discord.ui.TextDisplay(f"### 📊 Estadísticas\n- **Mensajes:** {messages}"), discord.ui.ActionRow( discord.ui.Button(label="Dar reputación", emoji="⭐", style=discord.ButtonStyle.primary, custom_id=f"rep:{user.id}"), discord.ui.Button(label="Ver insignias", style=discord.ButtonStyle.secondary, custom_id=f"insignias:{user.id}"), ), accent_colour=0x5865F2, ) ) return view
await interaction.response.send_message(view=profile_card(interaction.user, 42, 12350, 8214))func profileCard(u *discordgo.User, level, xp, messages int) discordgo.Container { color := 0x5865F2 large := discordgo.SeparatorSpacingSizeLarge alt := "Avatar de " + u.Username
return discordgo.Container{ AccentColor: &color, Components: []discordgo.MessageComponent{ discordgo.Section{ Components: []discordgo.MessageComponent{ discordgo.TextDisplay{Content: "# " + u.Username}, discordgo.TextDisplay{Content: fmt.Sprintf("🏆 **Nivel %d** · %d XP", level, xp)}, }, Accessory: discordgo.Thumbnail{ Media: discordgo.UnfurledMediaItem{URL: u.AvatarURL("256")}, Description: &alt, }, }, discordgo.Separator{Spacing: &large}, discordgo.TextDisplay{Content: fmt.Sprintf("### 📊 Estadísticas\n- **Mensajes:** %d", messages)}, discordgo.ActionsRow{Components: []discordgo.MessageComponent{ discordgo.Button{Label: "Dar reputación", Style: discordgo.PrimaryButton, CustomID: "rep:" + u.ID, Emoji: &discordgo.ComponentEmoji{Name: "⭐"}}, discordgo.Button{Label: "Ver insignias", Style: discordgo.SecondaryButton, CustomID: "insignias:" + u.ID}, }}, }, }}

