Saltearse al contenido

Eventos del Bot

🎯 Eventos del Bot

Documentación completa de todos los eventos de Discord que el bot maneja y procesa.

📋 Lista de Eventos

🚀 Eventos de Ciclo de Vida

ready

src/events/ready.js
module.exports = {
name: 'ready',
once: true,
async execute(client) {
console.log(`✅ Bot conectado como ${client.user.tag}`);
// Registrar comandos slash
await registerCommands(client);
// Inicializar sistemas
await initializeSystems(client);
// Logs de inicio
Logger.info('Bot iniciado correctamente', {
guilds: client.guilds.cache.size,
users: client.users.cache.size,
commands: client.commands.size
});
}
};

Funcionalidades:

  • Registro de comandos slash globales
  • Inicialización de base de datos
  • Configuración de sistemas por defecto
  • Logs de inicio y estadísticas

disconnect

src/events/disconnect.js
module.exports = {
name: 'disconnect',
async execute(client) {
Logger.warn('Bot desconectado de Discord');
// Backup de emergencia
await BackupManager.createBackup();
// Limpiar recursos
await cleanup(client);
}
};

👥 Eventos de Servidor

guildCreate

src/events/guild/guildCreate.js
module.exports = {
name: 'guildCreate',
async execute(guild) {
Logger.info(`Agregado a nuevo servidor: ${guild.name} (${guild.id})`);
// Crear configuración por defecto
await ConfigManager.getGuildConfig(guild.id);
// Mensaje de bienvenida al servidor
const owner = await guild.fetchOwner();
const welcomeEmbed = createWelcomeEmbed(guild);
try {
await owner.send({ embeds: [welcomeEmbed] });
} catch (error) {
Logger.warn('No se pudo enviar mensaje de bienvenida al propietario');
}
// Estadísticas
MetricsCollector.recordGuildJoin(guild);
}
};

Funcionalidades:

  • Configuración automática del servidor
  • Mensaje de bienvenida al propietario
  • Creación de base de datos para el servidor
  • Registro de métricas

guildDelete

src/events/guild/guildDelete.js
module.exports = {
name: 'guildDelete',
async execute(guild) {
Logger.info(`Eliminado del servidor: ${guild.name} (${guild.id})`);
// Opcional: Limpiar datos del servidor
// await ConfigManager.deleteGuildConfig(guild.id);
MetricsCollector.recordGuildLeave(guild);
}
};

👤 Eventos de Miembros

guildMemberAdd

src/events/guild/guildMemberAdd.js
module.exports = {
name: 'guildMemberAdd',
async execute(member) {
const guildId = member.guild.id;
const config = await ConfigManager.getGuildConfig(guildId);
Logger.info(`Nuevo miembro: ${member.user.tag} en ${member.guild.name}`);
// Sistema de bienvenida
if (config.welcome.enabled) {
await WelcomeHandler.handleNewMember(member);
}
// Roles automáticos
if (config.autoRoles && config.autoRoles.length > 0) {
await RoleManager.assignAutoRoles(member);
}
// Logs de auditoría
await AuditLogger.logMemberJoin(member);
MetricsCollector.recordMemberJoin(member.guild);
}
};

Funcionalidades:

  • Mensajes de bienvenida personalizados
  • Asignación de roles automáticos
  • Logs de auditoría
  • Estadísticas de crecimiento

guildMemberRemove

src/events/guild/guildMemberRemove.js
module.exports = {
name: 'guildMemberRemove',
async execute(member) {
Logger.info(`Miembro salió: ${member.user.tag} de ${member.guild.name}`);
// Mensajes de despedida (si están configurados)
const config = await ConfigManager.getGuildConfig(member.guild.id);
if (config.farewell && config.farewell.enabled) {
await FarewellHandler.handleMemberLeave(member);
}
// Limpiar tickets abiertos del usuario
await TicketManager.closeUserTickets(member.user.id, member.guild.id);
// Logs de auditoría
await AuditLogger.logMemberLeave(member);
MetricsCollector.recordMemberLeave(member.guild);
}
};

💬 Eventos de Mensajes

messageCreate

src/events/message/messageCreate.js
module.exports = {
name: 'messageCreate',
async execute(message) {
// Ignorar bots
if (message.author.bot) return;
// Ignorar DMs
if (!message.guild) return;
const guildId = message.guild.id;
const userId = message.author.id;
// Sistema de niveles
await LevelManager.addXP(userId, guildId, message);
// Auto-moderación
const config = await ConfigManager.getGuildConfig(guildId);
if (config.moderation.autoMod) {
await AutoMod.checkMessage(message);
}
// Comandos de texto (legacy - si están habilitados)
if (config.textCommands) {
await TextCommandHandler.handle(message);
}
MetricsCollector.recordMessage(message.guild);
}
};

Funcionalidades:

  • Sistema de XP y niveles
  • Auto-moderación de contenido
  • Procesamiento de comandos de texto
  • Métricas de actividad

messageDelete

src/events/message/messageDelete.js
module.exports = {
name: 'messageDelete',
async execute(message) {
// Ignorar mensajes parciales o de bots
if (message.partial || message.author?.bot) return;
// Log de mensaje eliminado
await AuditLogger.logMessageDelete(message);
// Verificar si era un panel de roles
await RoleManager.checkDeletedPanel(message);
}
};

🎛️ Eventos de Interacciones

interactionCreate

src/events/interaction/interactionCreate.js
module.exports = {
name: 'interactionCreate',
async execute(interaction) {
const guildId = interaction.guild?.id;
// Rate limiting
if (RateLimiter.isLimited(`${interaction.user.id}:${interaction.commandName}`)) {
return await interaction.reply({
content: 'Estás usando comandos muy rápido. Espera un momento.',
ephemeral: true
});
}
try {
if (interaction.isChatInputCommand()) {
await handleSlashCommand(interaction);
} else if (interaction.isButton()) {
await handleButtonInteraction(interaction);
} else if (interaction.isStringSelectMenu()) {
await handleSelectMenuInteraction(interaction);
} else if (interaction.isModalSubmit()) {
await handleModalSubmit(interaction);
}
} catch (error) {
Logger.error('Error en interacción', {
error: error.message,
user: interaction.user.tag,
command: interaction.commandName || 'unknown'
});
await handleInteractionError(interaction, error);
}
}
};

🔘 Eventos de Reacciones

messageReactionAdd

src/events/reaction/messageReactionAdd.js
module.exports = {
name: 'messageReactionAdd',
async execute(reaction, user) {
// Ignorar reacciones de bots
if (user.bot) return;
// Manejar reacciones parciales
if (reaction.partial) {
try {
await reaction.fetch();
} catch (error) {
Logger.error('Error al obtener reacción', error);
return;
}
}
const message = reaction.message;
if (!message.guild) return;
// Sistema de roles por reacción
await RoleManager.handleReactionRoleAdd(reaction, user);
// Otros sistemas que usen reacciones
await ReactionHandler.processReaction(reaction, user, 'add');
}
};

messageReactionRemove

src/events/reaction/messageReactionRemove.js
module.exports = {
name: 'messageReactionRemove',
async execute(reaction, user) {
if (user.bot) return;
if (reaction.partial) {
try {
await reaction.fetch();
} catch (error) {
return;
}
}
// Quitar roles por reacción
await RoleManager.handleReactionRoleRemove(reaction, user);
await ReactionHandler.processReaction(reaction, user, 'remove');
}
};

🎭 Eventos de Roles

guildMemberUpdate

src/events/guild/guildMemberUpdate.js
module.exports = {
name: 'guildMemberUpdate',
async execute(oldMember, newMember) {
// Detectar cambios de roles
const addedRoles = newMember.roles.cache.filter(role =>
!oldMember.roles.cache.has(role.id)
);
const removedRoles = oldMember.roles.cache.filter(role =>
!newMember.roles.cache.has(role.id)
);
// Log cambios de roles
if (addedRoles.size > 0 || removedRoles.size > 0) {
await AuditLogger.logRoleChanges(oldMember, newMember, addedRoles, removedRoles);
}
// Detectar cambios de nickname
if (oldMember.nickname !== newMember.nickname) {
await AuditLogger.logNicknameChange(oldMember, newMember);
}
// Verificar actualizaciones de permisos
await PermissionManager.checkMemberPermissions(newMember);
}
};

🔄 Manejo de Errores

Error Handler Global

src/events/error/error.js
module.exports = {
name: 'error',
async execute(error) {
Logger.error('Error del cliente Discord', {
message: error.message,
stack: error.stack,
timestamp: new Date().toISOString()
});
// Notificar al owner en errores críticos
if (error.code === 'CRITICAL') {
await notifyOwner(error);
}
MetricsCollector.recordError(error);
}
};

Warning Handler

src/events/error/warn.js
module.exports = {
name: 'warn',
async execute(warning) {
Logger.warn('Advertencia del cliente Discord', {
message: warning,
timestamp: new Date().toISOString()
});
}
};

📊 Eventos de Monitoreo

Rate Limit Handler

src/events/rateLimit.js
module.exports = {
name: 'rateLimit',
async execute(rateLimitData) {
Logger.warn('Rate limit alcanzado', {
timeout: rateLimitData.timeout,
limit: rateLimitData.limit,
method: rateLimitData.method,
path: rateLimitData.path
});
MetricsCollector.recordRateLimit(rateLimitData);
}
};

Debug Events

src/events/debug.js
module.exports = {
name: 'debug',
async execute(info) {
if (process.env.NODE_ENV === 'development') {
Logger.debug('Discord.js debug', { info });
}
}
};

🎯 Eventos Personalizados

Custom Event Emitter

src/utils/eventEmitter.js
const EventEmitter = require('events');
class BotEventEmitter extends EventEmitter {
// Eventos personalizados del bot
emitLevelUp(userId, guildId, level) {
this.emit('levelUp', { userId, guildId, level });
}
emitTicketCreated(ticketData) {
this.emit('ticketCreated', ticketData);
}
emitConfigChanged(guildId, changes) {
this.emit('configChanged', { guildId, changes });
}
}
module.exports = new BotEventEmitter();

Event Listeners

src/events/custom/levelUp.js
const botEvents = require('../../utils/eventEmitter');
botEvents.on('levelUp', async ({ userId, guildId, level }) => {
Logger.info(`Level up: User ${userId} reached level ${level} in guild ${guildId}`);
// Verificar roles automáticos por nivel
await RoleManager.checkLevelRoles(userId, guildId, level);
// Estadísticas
MetricsCollector.recordLevelUp(guildId, level);
});

🔧 Configuración de Eventos

Event Handler

src/handlers/events.js
const fs = require('fs');
const path = require('path');
function loadEvents(client) {
const eventsPath = path.join(__dirname, '..', 'events');
function loadEventFiles(dir) {
const files = fs.readdirSync(dir);
for (const file of files) {
const filePath = path.join(dir, file);
const stat = fs.statSync(filePath);
if (stat.isDirectory()) {
loadEventFiles(filePath);
} else if (file.endsWith('.js')) {
const event = require(filePath);
if (event.once) {
client.once(event.name, (...args) => event.execute(...args));
} else {
client.on(event.name, (...args) => event.execute(...args));
}
Logger.debug(`Evento cargado: ${event.name}`);
}
}
}
loadEventFiles(eventsPath);
}
module.exports = { loadEvents };

📈 Métricas de Eventos

Event Statistics

class EventMetrics {
static stats = {
messageCreate: 0,
interactionCreate: 0,
guildMemberAdd: 0,
guildMemberRemove: 0,
ready: 0,
errors: 0
};
static record(eventName) {
if (this.stats.hasOwnProperty(eventName)) {
this.stats[eventName]++;
}
}
static getStats() {
return { ...this.stats };
}
static reset() {
Object.keys(this.stats).forEach(key => {
this.stats[key] = 0;
});
}
}

Todos los eventos están optimizados para máximo rendimiento y incluyen manejo de errores robusto. Los logs detallados permiten debugging efectivo y monitoreo del comportamiento del bot.