Autocompletar

Autocomplete le permite proporcionar dinámicamente una selección de valores al usuario, basándose en su entrada, en lugar de depender de opciones estáticas. En esta sección veremos cómo añadir la función de autocompletar a tus comandos.

CONSEJO

Esta página es una continuación de la sección creación de comandos avanzados que trata de las opciones y de la elección de opciones. Por favor, lea atentamente esas páginas primero para que pueda entender los métodos utilizados en esta sección.

Activar autocompletar

Para utilizar el autocompletado con sus comandos, en lugar de listar las opciones estáticas, la opción debe configurarse para utilizar el autocompletado utilizando SlashCommandStringOption#setAutocomplete()open in new window:

const { SlashCommandBuilder } = require('discord.js');

const data = new SlashCommandBuilder()
	.setName('guide')
	.setDescription('Busca en discordjs-guide-es.netlify.app!')
	.addStringOption(option =>
		option.setName('query')
			.setDescription('Frase a buscar')
			.setAutocomplete(true));








 
1
2
3
4
5
6
7
8
9

Respuesta a las interacciones de autocompletar

Para manejar un AutocompleteInteractionopen in new window, utilice la protección de tipo (type guard) BaseInteraction#isAutocompleteopen in new window para asegurarse de que la instancia de interacción es una interacción de autocompletar. Puedes hacer esto en un listener interactionCreate separado:

client.on(Events.InteractionCreate, interaction => {
	if (!interaction.isAutocomplete()) return;
	// gestión de autocompletar
});
1
2
3
4

O alternativamente, haciendo un pequeño cambio en tu manejador de comandos y añadiendo un método adicional a tus archivos de comandos individuales.

El siguiente ejemplo muestra cómo podría aplicarse esto a una versión conceptual del comando guide para determinar el tema más cercano a la entrada de búsqueda:

client.on(Events.InteractionCreate, async interaction => {
	if (interaction.isChatInputCommand()) {
		// manejo de comandos
	} else if (interaction.isAutocomplete()) {
		const command = interaction.client.commands.get(interaction.commandName);

		if (!command) {
			console.error(`No se ha encontrado ningún comando que coincida con ${interaction.commandName}.`);
			return;
		}

		try {
			await command.autocomplete(interaction);
		} catch (error) {
			console.error(error);
		}
	}
});



 








 





1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
module.exports = {
	data: new SlashCommandBuilder()
		.setName('guide')
		.setDescription('Busca en discordjs-guide-es.netlify.app!')
		.addStringOption(option =>
			option.setName('query')
				.setDescription('Frase a buscar')
				.setAutocomplete(true)),
	async autocomplete(interaction) {
		// gestiona la respuesta de autocompletado (más adelante se explica cómo hacerlo)
	},
	async execute(interaction) {
		// responder al comando de barra completo
	},
};
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15

El manejo de los comandos es casi idéntico, pero fíjate en el cambio de execute a autocomplete en la nueva rama else-if. Añadiendo una función autocomplete separada al module.exports de los comandos que requieren autocompletado, puedes separar de forma segura la lógica de proporcionar opciones dinámicas del código que necesita responder al comando slash una vez que se ha completado.

TIP

Puede que ya hayas movido este código a events/interactionCreate.js si también has seguido nuestra guía Manejo de eventos.

Envío de resultados

La clase AutocompleteInteractionopen in new window proporciona el método AutocompleteInteraction#respondopen in new window para enviar una respuesta. Usando esto, puede enviar un array de objetos ApplicationCommandOptionChoiceDataopen in new window para que el usuario elija. Si se pasa un array vacío, se mostrará al usuario el mensaje "No hay opciones que coincidan con su búsqueda".

ADVERTENCIA

A diferencia de las opciones estáticas, las sugerencias de autocompletado no son obligatorias, y los usuarios pueden introducir texto libre.

El método CommandInteractionOptionResolver#getFocusedopen in new window devuelve el valor de la opción actualmente enfocada, que puede utilizarse para aplicar filtros a las opciones presentadas. Por ejemplo, para mostrar sólo las opciones que comienzan con el valor enfocado se puede utilizar el método Array#filter(), luego utilizando Array#map(), se puede transformar el array en un array de objetos ApplicationCommandOptionChoiceDataopen in new window.

module.exports = {
	data: new SlashCommandBuilder()
		.setName('guide')
		.setDescription('Buscar en discordjs-guide-es.netlify.app!')
		.addStringOption(option =>
			option.setName('query')
				.setDescription('Frase a buscar')
				.setAutocomplete(true)),
	async autocomplete(interaction) {
		const focusedValue = interaction.options.getFocused();
		const choices = ['Temas populares: Threads', 'Sharding: Primeros pasos', 'Biblioteca: Conexiones de voz', 'Interacciones: Responder a comandos de barra", "Temas populares: Incrustar vista previa'];
		const filtered = choices.filter(choice => choice.startsWith(focusedValue));
		await interaction.respond(
			filtered.map(choice => ({ name: choice, value: choice })),
		);
	},
};









 
 
 
 
 
 


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

Manejo de múltiples opciones de autocompletar

To distinguish between multiple options, you can pass true into CommandInteractionOptionResolver#getFocusedopen in new window, which will now return the full focused object instead of just the value. This is used to get the name of the focused option below, allowing for multiple options to each have their own set of suggestions:

module.exports = {
	data: new SlashCommandBuilder()
		.setName('guide')
		.setDescription('Busca en discordjs-guide-es.netlify.app!')
		.addStringOption(option =>
			option.setName('query')
				.setDescription('Frase a buscar')
				.setAutocomplete(true))
		.addStringOption(option =>
			option.setName('version')
				.setDescription('Version en la que buscar')
				.setAutocomplete(true)),
	async autocomplete(interaction) {
		const focusedOption = interaction.options.getFocused(true);
		let choices;

		if (focusedOption.name === 'query') {
			choices = ['Temas populares: Threads', 'Sharding: Primeros pasos', 'Biblioteca: Conexiones de voz', 'Interacciones: Responder a comandos de barra", "Temas populares: Incrustar vista previa'];
		}

		if (focusedOption.name === 'version') {
			choices = ['v9', 'v11', 'v12', 'v13', 'v14'];
		}

		const filtered = choices.filter(choice => choice.startsWith(focusedOption.value));
		await interaction.respond(
			filtered.map(choice => ({ name: choice, value: choice })),
		);
	},
};









 
 
 
 
 
 
 
 
 
 











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

Acceso a otros valores

Además de filtrar basándose en el valor enfocado, puede que también desee cambiar las opciones mostradas basándose en el valor de otros argumentos del comando. Los siguientes métodos funcionan igual en AutocompleteInteractionopen in new window:

const string = interaction.options.getString('input');
const integer = interaction.options.getInteger('int');
const boolean = interaction.options.getBoolean('choice');
const number = interaction.options.getNumber('num');
1
2
3
4

Sin embargo, los métodos .getUser(), .getMember(), .getRole(), .getChannel(), .getMentionable() y .getAttachment() no están disponibles para autocompletar interacciones. Discord no envía los respectivos objetos completos para estos métodos hasta que se completa el comando de barra. Para estos, puedes obtener el valor Snowflake usando interaction.options.get('option').value:

Notas

  • Al igual que con otras interacciones de comandos de aplicación, las interacciones de autocompletar deben recibir una respuesta antes de 3 segundos.
  • No se puede aplazar la respuesta a una interacción de autocompletar. Si se trata de sugerencias asíncronas, como las procedentes de una API, considere la posibilidad de mantener una caché local.
  • Después de que el usuario seleccione un valor y envíe el comando, se recibirá como un ChatInputCommandInteractionopen in new window normal con el valor elegido.
  • Sólo se puede responder con un máximo de 25 opciones a la vez, aunque más que esto probablemente significa que usted debe revisar su filtro para reducir aún más las selecciones.