Encontranos en redes
Slash CommandsInteraccionesdiscord.js6 min de lectura
Configurar Slash Commands
Registrar slash commands globales y por servidor, manejar interacciones, opciones y autocompletado.
¿Qué son los Slash Commands?
Los slash commands son la forma moderna de interactuar con bots en Discord. Aparecen cuando el usuario escribe / y ofrecen autocompletado, validación de tipos y mejor UX.
Paso 1: Registrar comandos
Creá un archivo deploy-commands.js:
javascript
const { REST, Routes, SlashCommandBuilder } = require('discord.js');
require('dotenv').config();
const commands = [
new SlashCommandBuilder()
.setName('ping')
.setDescription('Responde con pong y la latencia'),
new SlashCommandBuilder()
.setName('info')
.setDescription('Muestra info de un usuario')
.addUserOption(option =>
option.setName('usuario')
.setDescription('El usuario a consultar')
.setRequired(true)
),
new SlashCommandBuilder()
.setName('config')
.setDescription('Configuración del servidor')
.addSubcommand(sub =>
sub.setName('prefix')
.setDescription('Cambiar el prefijo')
.addStringOption(opt =>
opt.setName('nuevo').setDescription('Nuevo prefijo').setRequired(true)
)
)
];
const rest = new REST().setToken(process.env.DISCORD_TOKEN);
(async () => {
// Registro global (tarda ~1 hora en propagarse)
await rest.put(
Routes.applicationCommands(process.env.CLIENT_ID),
{ body: commands.map(c => c.toJSON()) }
);
console.log('Comandos registrados globalmente');
// Registro por guild (instantáneo, ideal para desarrollo)
await rest.put(
Routes.applicationGuildCommands(process.env.CLIENT_ID, process.env.GUILD_ID),
{ body: commands.map(c => c.toJSON()) }
);
console.log('Comandos registrados en guild de desarrollo');
})();Paso 2: Manejar interacciones
javascript
client.on('interactionCreate', async interaction => {
if (!interaction.isChatInputCommand()) return;
const { commandName } = interaction;
if (commandName === 'ping') {
const latency = Date.now() - interaction.createdTimestamp;
await interaction.reply(`Pong! Latencia: ${latency}ms`);
}
if (commandName === 'info') {
const user = interaction.options.getUser('usuario');
await interaction.reply(`Usuario: ${user.tag}\nID: ${user.id}`);
}
});Paso 3: Opciones avanzadas
Tipos de opciones disponibles:
javascript
// String con choices predefinidos
.addStringOption(opt =>
opt.setName('color')
.setDescription('Elegí un color')
.addChoices(
{ name: 'Rojo', value: 'red' },
{ name: 'Azul', value: 'blue' }
)
)
// Integer con rango
.addIntegerOption(opt =>
opt.setName('cantidad')
.setDescription('Cantidad')
.setMinValue(1)
.setMaxValue(100)
)Paso 4: Autocompletado
javascript
// En el builder
.addStringOption(opt =>
opt.setName('juego')
.setDescription('Nombre del juego')
.setAutocomplete(true)
)
// En el handler
client.on('interactionCreate', async interaction => {
if (interaction.isAutocomplete()) {
const focused = interaction.options.getFocused();
const choices = ['Minecraft', 'FiveM', 'CS2', 'Valorant'];
const filtered = choices.filter(c =>
c.toLowerCase().startsWith(focused.toLowerCase())
);
await interaction.respond(
filtered.map(c => ({ name: c, value: c }))
);
}
});Recomendaciones
- Usá registro por guild durante desarrollo (es instantáneo)
- Registrá globalmente solo cuando el comando esté listo para producción
- Implementá manejo de errores en cada comando
- Usá
interaction.deferReply()si el comando tarda más de 3 segundos
¿Te resultó útil esta guía?