Panel de roles
Un panel donde cada miembro elige sus roles. Cada rol es una Section con un botón al lado, y al final hay un menú para los colores.
{ "flags": 32768, "components": [ { "type": 17, "accent_color": 15418782, "components": [ { "type": 10, "content": "## 🎭 Elige tus roles\nPulsa un botón para añadir o quitar el rol." }, { "type": 14 }, { "type": 9, "components": [ { "type": 10, "content": "🎮 **Gamer**\n-# Acceso a los canales de juegos" } ], "accessory": { "type": 2, "style": 2, "label": "Gamer", "custom_id": "rol:111111111111111111" } }, { "type": 9, "components": [ { "type": 10, "content": "🎨 **Artista**\n-# Comparte tus dibujos" } ], "accessory": { "type": 2, "style": 2, "label": "Artista", "custom_id": "rol:222222222222222222" } }, { "type": 9, "components": [ { "type": 10, "content": "📢 **Anuncios**\n-# Recibe una mención en cada anuncio" } ], "accessory": { "type": 2, "style": 2, "label": "Anuncios", "custom_id": "rol:333333333333333333" } }, { "type": 14, "spacing": 2 }, { "type": 10, "content": "**Color del nombre**" }, { "type": 1, "components": [ { "type": 3, "custom_id": "color", "placeholder": "Elige un color", "min_values": 0, "options": [ { "label": "Rojo", "value": "444444444444444444", "emoji": { "name": "🔴" } }, { "label": "Verde", "value": "555555555555555555", "emoji": { "name": "🟢" } }, { "label": "Azul", "value": "666666666666666666", "emoji": { "name": "🔵" } } ] } ] } ] } ]}La lógica
Sección titulada «La lógica»- El
custom_idde cada botón esrol:+ ID del rol. Así un solo manejador sirve para todos. - Al pulsar: si el miembro tiene el rol, se le quita; si no, se le añade.
- Responde con un mensaje efímero para confirmar (solo lo ve quien pulsó).
- El panel no cambia, así que no hace falta editarlo.
Código del manejador
Sección titulada «Código del manejador»- Lee
data.custom_idy extrae el ID del rol. - Añade el rol con
PUT /guilds/{guild.id}/members/{user.id}/roles/{role.id}o quítalo conDELETEen la misma ruta. - Responde a la interacción con
type: 4yflags: 32832(V2 + efímero).
client.on(Events.InteractionCreate, async (interaction) => { if (!interaction.isButton() || !interaction.customId.startsWith('rol:')) return;
const roleId = interaction.customId.split(':')[1]; const member = interaction.member; let text;
if (member.roles.cache.has(roleId)) { await member.roles.remove(roleId); text = `➖ Rol <@&${roleId}> quitado.`; } else { await member.roles.add(roleId); text = `➕ Rol <@&${roleId}> añadido.`; }
await interaction.reply({ flags: MessageFlags.IsComponentsV2 | MessageFlags.Ephemeral, components: [new TextDisplayBuilder().setContent(text)], allowedMentions: { parse: [] }, });});@client.eventasync def on_interaction(interaction: discord.Interaction): if interaction.type != discord.InteractionType.component: return custom_id = interaction.data.get("custom_id", "") if not custom_id.startswith("rol:"): return
role = interaction.guild.get_role(int(custom_id.split(":")[1])) member = interaction.user
if role in member.roles: await member.remove_roles(role) text = f"➖ Rol {role.mention} quitado." else: await member.add_roles(role) text = f"➕ Rol {role.mention} añadido."
view = discord.ui.LayoutView() view.add_item(discord.ui.TextDisplay(text)) await interaction.response.send_message(view=view, ephemeral=True)s.AddHandler(func(s *discordgo.Session, i *discordgo.InteractionCreate) { if i.Type != discordgo.InteractionMessageComponent { return } customID := i.MessageComponentData().CustomID if !strings.HasPrefix(customID, "rol:") { return }
roleID := strings.TrimPrefix(customID, "rol:") text := "➕ Rol <@&" + roleID + "> añadido."
if slices.Contains(i.Member.Roles, roleID) { s.GuildMemberRoleRemove(i.GuildID, i.Member.User.ID, roleID) text = "➖ Rol <@&" + roleID + "> quitado." } else { s.GuildMemberRoleAdd(i.GuildID, i.Member.User.ID, roleID) }
s.InteractionRespond(i.Interaction, &discordgo.InteractionResponse{ Type: discordgo.InteractionResponseChannelMessageWithSource, Data: &discordgo.InteractionResponseData{ Flags: discordgo.MessageFlagsIsComponentsV2 | discordgo.MessageFlagsEphemeral, Components: []discordgo.MessageComponent{discordgo.TextDisplay{Content: text}}, }, })})