Menús de selección

Con la API de componentes, puedes crear componentes de mensajes interactivos. En esta página, veremos cómo enviar, recibir y responder a menús de selección con discord.js.

CONSEJO

Esta página es un seguimiento de la sección de interacciones (comandos de barra). Por favor, lee atentamente esa sección primero para que puedas comprender los métodos utilizados en esta sección.

Creación y envío de menús de selección

Los menús de selección son una de las clases MessageComponent, que pueden enviarse a través de mensajes o respuestas de interacción. Un menú de selección, como cualquier otro componente de mensaje, debe estar en una ActionRow.

ADVERTENCIA

Puede tener un máximo de cinco ActionRow por mensaje, y un menú de selección dentro de un ActionRow.

Para crear un menú de selección, utilice las clases ActionRowBuilderopen in new window y StringSelectMenuBuilderopen in new window. A continuación, pase el contenedor de componentes resultante a ChatInputCommandInteraction#replyopen in new window en el array components de InteractionReplyOptionsopen in new window:

const { ActionRowBuilder, Events, StringSelectMenuBuilder } = require('discord.js');

client.on(Events.InteractionCreate, async interaction => {
	if (!interaction.isChatInputCommand()) return;

	if (interaction.commandName === 'ping') {
		const row = new ActionRowBuilder()
			.addComponents(
				new StringSelectMenuBuilder()
					.setCustomId('selección')
					.setPlaceholder('Nada seleccionado')
					.addOptions(
						{
							label: 'Seleccioname',
							description: 'Esto es una descripción',
							value: 'primera_opción',
						},
						{
							label: 'También puedes seleccionarme',
							description: 'Esto también es otra descripción',
							value: 'segunda_opción',
						},
					),
			);

		await interaction.reply({ content: '¡Pong!', components: [row] });
	}
});
 





 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

 


1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28

CONSEJO

La id personalizada (custom_id) es una string definida por ti de hasta 100 caracteres. Utiliza este campo para asegurarte de que puedas definir de forma única todas las interacciones procedentes de tus menús de selección.

Reinicia tu bot y luego envía el comando a un canal al que tu bot tenga acceso. Si todo va bien, deberías ver algo como esto:

select

También puede enviar componentes de mensajes dentro de una respuesta efímera o junto a embeds.

const { ActionRowBuilder, EmbedBuilder, Events, StringSelectMenuBuilder } = require('discord.js');

client.on(Events.InteractionCreate, async interaction => {
	if (!interaction.isChatInputCommand()) return;

	if (interaction.commandName === 'ping') {
		const row = new ActionRowBuilder()
			.addComponents(
				// ...
			);

		const embed = new EmbedBuilder()
			.setColor(0x0099FF)
			.setTitle('Titulo ingenioso')
			.setURL('https://discord.js.org/')
			.setDescription('Alguna descripción');

		await interaction.reply({ content: '¡Pong!', ephemeral: true, embeds: [embed], components: [row] });
	}
});
 










 
 
 
 
 

 


1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20

Reinicia tu bot y luego envía el comando a un canal al que tu bot tenga acceso. Si todo va bien, deberías ver algo como esto:

selectephem

ADVERTENCIA

Si estás usando TypeScript necesitarás especificar el tipo de componentes que contiene tu contenedor de componentes. Esto se puede hacer especificando el constructor de componentes que le añadirás utilizando un parámetro genérico en ActionRowBuilderopen in new window.

- new ActionRowBuilder()
+ new ActionRowBuilder<StringSelectMenuBuilder>()
1
2

¡Ahora ya sabes todo lo que hay que saber para construir y enviar un SelectMenu! Pasemos ahora a cómo recibir menús.

Recibiendo interacciones de menús de selección

Colectores de componentes

Las interacciones de componentes de mensajes se pueden recopilar dentro del ámbito del comando de barra que las envió utilizando un InteractionCollectoropen in new window, o su variante awaitMessageComponent a base de promesa. Ambos proporcionan instancias de la clase MessageComponentInteractionopen in new window como elementos recogidos.

CONSEJO

Puede crear los colectores en un message o en un channel.

Para obtener una guía detallada sobre la recepción de componentes de mensajes a través de recopiladores, consulta la guía de recopiladores.

El evento interactionCreate

Para recibir un StringSelectMenuInteractionopen in new window, adjunta un oyente de evento Client#event:interactionCreateopen in new window a su cliente y utilice la protección de tipado BaseInteraction#isStringSelectMenuopen in new window para asegurarte de que sólo recibe menús de selección:

client.on(Events.InteractionCreate, interaction => {
	if (!interaction.isStringSelectMenu()) return;
	console.log(interaction);
});

 


1
2
3
4

Respondiendo a menús de selección

La clase MessageComponentInteractionopen in new window proporciona los mismos métodos que la clase ChatInputCommandInteractionopen in new window. Estos métodos se comportan igual:

  • reply()
  • editReply()
  • deferReply()
  • fetchReply()
  • deleteReply()
  • followUp()

Actualización del mensaje del menú de selección

La clase MessageComponentInteractionopen in new window proporciona un método MessageComponentInteraction#updateopen in new window para actualizar el mensaje al que se adjuntó el menú de selección. Si se pasa un array vacío a la opción components se eliminarán todos los menús una vez seleccionada una opción.

This method should be used in favour of editReply() on the original interaction, to ensure you respond to the select menu interaction.

client.on(Events.InteractionCreate, async interaction => {
	if (!interaction.isStringSelectMenu()) return;

	if (interaction.customId === 'select') {
		await interaction.update({ content: 'Something was selected!', components: [] });
	}
});
 


 
 
 

1
2
3
4
5
6
7

Deferring and updating the select menu's message

Este método debe usarse en lugar de editReply() en la interacción original, para asegurar que respondes a la interacción del menú de selección.

const wait = require('node:timers/promises').setTimeout;

client.on(Events.InteractionCreate, async interaction => {
	if (!interaction.isStringSelectMenu()) return;

	if (interaction.customId === 'select') {
		await interaction.deferUpdate();
		await wait(4000);
		await interaction.editReply({ content: '¡Se seleccionó algo!', components: [] });
	}
});
 




 
 
 
 
 

1
2
3
4
5
6
7
8
9
10
11

Un menú de selección no está vinculado a una única selección; puede especificar una cantidad mínima y máxima de opciones que deben seleccionarse. Puede utilizar los métodos SelectMenuBuilder#setMinValuesopen in new window y StringSelectMenuBuilder#setMaxValuesopen in new window para determinar estos valores.

const { ActionRowBuilder, Events, StringSelectMenuBuilder } = require('discord.js');

client.on(Events.InteractionCreate, async interaction => {
	if (!interaction.isChatInputCommand()) return;

	if (interaction.commandName === 'ping') {
		const row = new ActionRowBuilder()
			.addComponents(
				new StringSelectMenuBuilder()
					.setCustomId('selección')
					.setPlaceholder('Nada seleccionado')
					.setMinValues(2)
					.setMaxValues(3)
					.addOptions([
						{
							label: 'Seleccioname',
							description: 'Esto es una descripción',
							value: 'primera_opción',
						},
						{
							label: 'También puedes seleccionarme',
							description: 'Esto también es una descripción',
							value: 'segunda_opción',
						},
						{
							label: 'También soy una opción',
							description: 'Esta es una descripción también',
							value: 'tercera_opción',
						},
					]),
			);

		await interaction.reply({ content: '¡Pong!', components: [row] });
	}
});
 





 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

 


1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35

Accediendo a los valores de interacción del menú de selección

Después de recibir su StringSelectMenuInteractionopen in new window, podrás acceder a los valores seleccionados desde StringSelectMenuInteraction#valuesopen in new window. Esto devolverá un array de string asociados a las opciones seleccionadas en su menú de selección.

Por defecto, los menús de selección sólo aceptan una única selección. Puede recuperar el valor seleccionado accediendo al primer índice del array devuelta, como se muestra en el siguiente fragmento:

client.on(Events.InteractionCreate, async interaction => {
	if (!interaction.isStringSelectMenu()) return;

	const selected = interaction.values[0];

	if (selected === 'ping') {
		await interaction.update('¡Se ha seleccionado la opción ping!');
	} else if (selected === 'pong') {
		await interaction.update('¡Se ha seleccionado la opción Pong!');
	}
});



 

 
 
 
 
 

1
2
3
4
5
6
7
8
9
10
11

En el caso de un menú de selección múltiple, el StringSelectMenuInteraction#valuesopen in new window recibido puede contener más de un valor, y debe tratarse en consecuencia:

client.on(Events.InteractionCreate, async interaction => {
	if (!interaction.isStringSelectMenu()) return;

	const selected = interaction.values.join(', ');

	await interaction.update(`¡El usuario ha seleccionado ${selected}!`);
});



 

 

1
2
3
4
5
6
7