Discord Bot con Claude Code
Aprende sobre Discord Bot usando Claude Code. Incluye consejos practicos y ejemplos de codigo.
Optimizando el desarrollo de Discord Bot con Claude Code
Los Discord Bots se utilizan ampliamente para la gestion de comunidades, administracion de servidores de juegos, distribucion de notificaciones y mas. Con la biblioteca discord.js puedes desarrollar comodamente en TypeScript, pero el procesamiento de interacciones y la gestion de permisos requieren mucha implementacion. Aprovecha Claude Code para construir eficientemente un Discord Bot con funcionalidades avanzadas.
Configuracion del proyecto
> Crea un proyecto de Discord Bot.
> Con discord.js v14, TypeScript y estructura de manejador de comandos.
npm init -y
npm install discord.js
npm install -D typescript @types/node tsx
// src/index.ts
import { Client, GatewayIntentBits, Collection, Events } from 'discord.js';
import { registerCommands } from './commands';
const client = new Client({
intents: [
GatewayIntentBits.Guilds,
GatewayIntentBits.GuildMessages,
GatewayIntentBits.MessageContent,
GatewayIntentBits.GuildMembers,
],
});
client.commands = new Collection();
client.once(Events.ClientReady, (c) => {
console.log(`Conectado como ${c.user.tag}`);
});
// Manejador de comandos
client.on(Events.InteractionCreate, async (interaction) => {
if (!interaction.isChatInputCommand()) return;
const command = client.commands.get(interaction.commandName);
if (!command) return;
try {
await command.execute(interaction);
} catch (error) {
console.error(error);
const reply = {
content: 'Ocurrio un error al ejecutar el comando.',
ephemeral: true,
};
if (interaction.replied || interaction.deferred) {
await interaction.followUp(reply);
} else {
await interaction.reply(reply);
}
}
});
registerCommands(client);
client.login(process.env.DISCORD_TOKEN);
Implementacion de comandos slash
> Implementa una funcion de votacion con el comando /poll.
> Que se pueda votar con botones.
// src/commands/poll.ts
import {
SlashCommandBuilder,
ActionRowBuilder,
ButtonBuilder,
ButtonStyle,
EmbedBuilder,
ChatInputCommandInteraction,
ButtonInteraction,
} from 'discord.js';
const polls = new Map<string, { question: string; votes: Map<string, Set<string>> }>();
export const data = new SlashCommandBuilder()
.setName('poll')
.setDescription('Crear una votacion')
.addStringOption((opt) =>
opt.setName('question').setDescription('Pregunta').setRequired(true)
)
.addStringOption((opt) =>
opt.setName('option1').setDescription('Opcion 1').setRequired(true)
)
.addStringOption((opt) =>
opt.setName('option2').setDescription('Opcion 2').setRequired(true)
)
.addStringOption((opt) =>
opt.setName('option3').setDescription('Opcion 3').setRequired(false)
);
export async function execute(interaction: ChatInputCommandInteraction) {
const question = interaction.options.getString('question', true);
const options = [
interaction.options.getString('option1', true),
interaction.options.getString('option2', true),
interaction.options.getString('option3'),
].filter(Boolean) as string[];
const pollId = `poll-${Date.now()}`;
const votes = new Map<string, Set<string>>();
options.forEach((opt) => votes.set(opt, new Set()));
polls.set(pollId, { question, votes });
const embed = new EmbedBuilder()
.setTitle('📊 ' + question)
.setColor(0x6366f1)
.setDescription(
options.map((opt) => `**${opt}**: 0 votos`).join('\n')
)
.setFooter({ text: `Poll ID: ${pollId}` });
const row = new ActionRowBuilder<ButtonBuilder>().addComponents(
...options.map((opt, i) =>
new ButtonBuilder()
.setCustomId(`${pollId}:${opt}`)
.setLabel(opt)
.setStyle(ButtonStyle.Primary)
)
);
await interaction.reply({ embeds: [embed], components: [row] });
}
// Manejador de botones
export async function handlePollButton(interaction: ButtonInteraction) {
const [pollId, option] = interaction.customId.split(':');
const poll = polls.get(pollId);
if (!poll) return;
const userId = interaction.user.id;
// Eliminar voto existente
for (const voters of poll.votes.values()) {
voters.delete(userId);
}
// Agregar nuevo voto
poll.votes.get(option)?.add(userId);
const description = Array.from(poll.votes.entries())
.map(([opt, voters]) => {
const count = voters.size;
const bar = '█'.repeat(count) || '░';
return `**${opt}**: ${count} votos ${bar}`;
})
.join('\n');
const embed = new EmbedBuilder()
.setTitle('📊 ' + poll.question)
.setColor(0x6366f1)
.setDescription(description)
.setFooter({ text: `Poll ID: ${pollId}` });
await interaction.update({ embeds: [embed] });
}
Mensajes Embed
> Crea un comando que muestre la informacion del servidor.
> Mostrar en formato Embed enriquecido.
// src/commands/serverinfo.ts
import {
SlashCommandBuilder,
EmbedBuilder,
ChatInputCommandInteraction,
} from 'discord.js';
export const data = new SlashCommandBuilder()
.setName('serverinfo')
.setDescription('Muestra la informacion del servidor');
export async function execute(interaction: ChatInputCommandInteraction) {
const guild = interaction.guild;
if (!guild) return;
const embed = new EmbedBuilder()
.setTitle(guild.name)
.setThumbnail(guild.iconURL() || '')
.setColor(0x6366f1)
.addFields(
{ name: 'Miembros', value: `${guild.memberCount}`, inline: true },
{ name: 'Canales', value: `${guild.channels.cache.size}`, inline: true },
{ name: 'Roles', value: `${guild.roles.cache.size}`, inline: true },
{ name: 'Fecha de creacion', value: guild.createdAt.toLocaleDateString('es-ES'), inline: true },
{ name: 'Boost', value: `Nv.${guild.premiumTier} (${guild.premiumSubscriptionCount} veces)`, inline: true },
)
.setTimestamp();
await interaction.reply({ embeds: [embed] });
}
Registro de comandos
// src/commands/index.ts
import { REST, Routes, Client } from 'discord.js';
import * as poll from './poll';
import * as serverinfo from './serverinfo';
const commands = [poll, serverinfo];
export function registerCommands(client: Client) {
for (const command of commands) {
client.commands.set(command.data.name, command);
}
}
// Registrar comandos slash en Discord
export async function deployCommands() {
const rest = new REST().setToken(process.env.DISCORD_TOKEN!);
const body = commands.map((c) => c.data.toJSON());
await rest.put(
Routes.applicationCommands(process.env.DISCORD_CLIENT_ID!),
{ body }
);
console.log('Comandos desplegados');
}
Resumen
Combinando discord.js con Claude Code, puedes construir eficientemente Discord Bots interactivos. Consulta tambien la guia de desarrollo de chatbot y los fundamentos de desarrollo de API.
Para mas detalles sobre discord.js, consulta la guia oficial de discord.js.
Related Posts
Cómo potenciar tus proyectos personales con Claude Code [Con ejemplos]
Aprende a acelerar drásticamente tus proyectos personales de desarrollo usando Claude Code. Incluye ejemplos reales y un flujo de trabajo práctico desde la idea hasta el despliegue.
Cómo automatizar la refactorización con Claude Code
Aprende a automatizar eficientemente la refactorización de código usando Claude Code. Incluye prompts prácticos y patrones concretos de refactorización para proyectos reales.
Guia completa de configuracion CORS con Claude Code
Aprende sobre la configuracion completa de CORS usando Claude Code. Incluye consejos practicos y ejemplos de codigo.