diff --git a/src/commands/messages/net/commandsAdmin.ts b/src/commands/messages/net/commandsAdmin.ts new file mode 100644 index 0000000..0558509 --- /dev/null +++ b/src/commands/messages/net/commandsAdmin.ts @@ -0,0 +1,56 @@ +// Comando de administración para sincronizar / limpiar comandos (solo dueño) +// @ts-ignore +import { CommandMessage } from "../../../core/types/commands"; + +const OWNER_ID = '327207082203938818'; + +export const command: CommandMessage = { + name: 'admin-comandos', + type: 'message', + aliases: ['cmdadmin', 'synccommands', 'comandos-admin'], + cooldown: 5, + run: async (message, _args, _client) => { + if (message.author.id !== OWNER_ID) { + await message.reply({ content: '❌ No tienes permisos para usar este panel.' }); + return; + } + + const panel = { + type: 17, + accent_color: 0x2b2d31, + components: [ + { + type: 10, + content: '### 🛠️ Panel de Administración de Comandos\nGestiona el registro y limpieza de comandos **Slash**.' + }, + { type: 14, divider: true, spacing: 1 }, + { + type: 10, + content: 'Acciones disponibles:\n• Registrar comandos de GUILD (testing)\n• Registrar comandos GLOBAL (propagación lenta)\n• Limpiar comandos de GUILD\n• Limpiar comandos GLOBAL\n\nUsa los botones de abajo. Se evita ejecución simultánea.' + } + ] + }; + + const rows = [ + { + type: 1, + components: [ + { type: 2, style: 1, label: 'Registrar GUILD', custom_id: 'cmd_reg_guild' }, + { type: 2, style: 1, label: 'Registrar GLOBAL', custom_id: 'cmd_reg_global' } + ] + }, + { + type: 1, + components: [ + { type: 2, style: 4, label: 'Limpiar GUILD', custom_id: 'cmd_clear_guild' }, + { type: 2, style: 4, label: 'Limpiar GLOBAL', custom_id: 'cmd_clear_global' } + ] + } + ]; + + await message.reply({ + flags: 32768, + components: [panel, ...rows] + }); + } +}; diff --git a/src/components/buttons/cmdClearGlobal.ts b/src/components/buttons/cmdClearGlobal.ts new file mode 100644 index 0000000..da9bfb8 --- /dev/null +++ b/src/components/buttons/cmdClearGlobal.ts @@ -0,0 +1,33 @@ +import type { ButtonInteraction } from 'discord.js'; +import { clearGlobalCommands } from '../../core/api/discordAPI'; + +const OWNER_ID = '327207082203938818'; +let running = false; + +export default { + customId: 'cmd_clear_global', + run: async (interaction: ButtonInteraction) => { + if (interaction.user.id !== OWNER_ID) { + return interaction.reply({ content: '❌ No autorizado.', ephemeral: true }); + } + if (running) { + return interaction.reply({ content: '⏳ Limpieza GLOBAL en progreso, espera.', ephemeral: true }); + } + running = true; + try { + await interaction.deferReply({ ephemeral: true }); + await clearGlobalCommands(); + await interaction.editReply('🧹 Comandos GLOBAL eliminados.'); + } catch (e: any) { + console.error('Error limpiando comandos globales:', e); + if (interaction.deferred || interaction.replied) { + await interaction.editReply('❌ Error limpiando comandos globales.'); + } else { + await interaction.reply({ content: '❌ Error limpiando comandos globales.', ephemeral: true }); + } + } finally { + running = false; + } + } +}; + diff --git a/src/components/buttons/cmdClearGuild.ts b/src/components/buttons/cmdClearGuild.ts new file mode 100644 index 0000000..fdcb309 --- /dev/null +++ b/src/components/buttons/cmdClearGuild.ts @@ -0,0 +1,33 @@ +import type { ButtonInteraction } from 'discord.js'; +import { clearAllCommands } from '../../core/api/discordAPI'; + +const OWNER_ID = '327207082203938818'; +let running = false; + +export default { + customId: 'cmd_clear_guild', + run: async (interaction: ButtonInteraction) => { + if (interaction.user.id !== OWNER_ID) { + return interaction.reply({ content: '❌ No autorizado.', ephemeral: true }); + } + if (running) { + return interaction.reply({ content: '⏳ Limpieza GUILD en progreso, espera.', ephemeral: true }); + } + running = true; + try { + await interaction.deferReply({ ephemeral: true }); + await clearAllCommands(); + await interaction.editReply('🧹 Comandos de GUILD eliminados.'); + } catch (e: any) { + console.error('Error limpiando comandos guild:', e); + if (interaction.deferred || interaction.replied) { + await interaction.editReply('❌ Error limpiando comandos de guild.'); + } else { + await interaction.reply({ content: '❌ Error limpiando comandos de guild.', ephemeral: true }); + } + } finally { + running = false; + } + } +}; + diff --git a/src/components/buttons/cmdRegisterGlobal.ts b/src/components/buttons/cmdRegisterGlobal.ts new file mode 100644 index 0000000..3117c44 --- /dev/null +++ b/src/components/buttons/cmdRegisterGlobal.ts @@ -0,0 +1,33 @@ +import type { ButtonInteraction } from 'discord.js'; +import { registeringGlobalCommands } from '../../core/api/discordAPI'; + +const OWNER_ID = '327207082203938818'; +let running = false; + +export default { + customId: 'cmd_reg_global', + run: async (interaction: ButtonInteraction) => { + if (interaction.user.id !== OWNER_ID) { + return interaction.reply({ content: '❌ No autorizado.', ephemeral: true }); + } + if (running) { + return interaction.reply({ content: '⏳ Ya hay un registro GLOBAL en curso, espera.', ephemeral: true }); + } + running = true; + try { + await interaction.deferReply({ ephemeral: true }); + await registeringGlobalCommands(); + await interaction.editReply('✅ Comandos GLOBAL registrados (propagación puede tardar).'); + } catch (e: any) { + console.error('Error registrando comandos globales:', e); + if (interaction.deferred || interaction.replied) { + await interaction.editReply('❌ Error registrando comandos globales.'); + } else { + await interaction.reply({ content: '❌ Error registrando comandos globales.', ephemeral: true }); + } + } finally { + running = false; + } + } +}; + diff --git a/src/components/buttons/cmdRegisterGuild.ts b/src/components/buttons/cmdRegisterGuild.ts new file mode 100644 index 0000000..ca27562 --- /dev/null +++ b/src/components/buttons/cmdRegisterGuild.ts @@ -0,0 +1,33 @@ +import type { ButtonInteraction } from 'discord.js'; +import { registeringCommands } from '../../core/api/discordAPI'; + +const OWNER_ID = '327207082203938818'; +let running = false; + +export default { + customId: 'cmd_reg_guild', + run: async (interaction: ButtonInteraction) => { + if (interaction.user.id !== OWNER_ID) { + return interaction.reply({ content: '❌ No autorizado.', ephemeral: true }); + } + if (running) { + return interaction.reply({ content: '⏳ Ya hay un registro de comandos guild en curso, espera.', ephemeral: true }); + } + running = true; + try { + await interaction.deferReply({ ephemeral: true }); + await registeringCommands(); + await interaction.editReply('✅ Comandos de GUILD registrados correctamente.'); + } catch (e: any) { + console.error('Error registrando comandos guild:', e); + if (interaction.deferred || interaction.replied) { + await interaction.editReply('❌ Error registrando comandos de guild. Revisa logs.'); + } else { + await interaction.reply({ content: '❌ Error registrando comandos de guild.', ephemeral: true }); + } + } finally { + running = false; + } + } +}; + diff --git a/src/core/api/discordAPI.ts b/src/core/api/discordAPI.ts index ad17492..bf2561a 100644 --- a/src/core/api/discordAPI.ts +++ b/src/core/api/discordAPI.ts @@ -10,7 +10,7 @@ export async function registeringCommands(): Promise { const commandsToRegister: any[] = []; // Recorremos la Collection que ya cargó loadCommands() - for (const [name, cmd] of commands) { + for (const [_name, cmd] of commands) { if (cmd.type === "slash") { commandsToRegister.push({ name: cmd.name, @@ -19,12 +19,12 @@ export async function registeringCommands(): Promise { options: cmd.options ?? [] }); - console.log(`✅ Preparado para registrar: ${cmd.name}`); + console.log(`✅ Preparado para registrar (guild): ${cmd.name}`); } } try { - console.log(`🧹 Limpiando comandos antiguos/residuales...`); + console.log(`🧹 Limpiando comandos antiguos/residuales (guild)...`); // Primero eliminamos TODOS los comandos existentes await rest.put( @@ -35,12 +35,11 @@ export async function registeringCommands(): Promise { { body: [] } // Array vacío elimina todos los comandos ); - console.log(`✅ Comandos antiguos eliminados correctamente.`); - + console.log(`✅ Comandos antiguos de guild eliminados.`); // Pequeña pausa para asegurar que Discord procese la eliminación - await new Promise(resolve => setTimeout(resolve, 1000)); + await new Promise(r => setTimeout(r, 1000)); - console.log(`🚀 Registrando ${commandsToRegister.length} comandos slash nuevos...`); + console.log(`🚀 Registrando ${commandsToRegister.length} comandos slash nuevos (guild)...`); // Ahora registramos los comandos actuales const data: any = await rest.put( @@ -51,20 +50,47 @@ export async function registeringCommands(): Promise { { body: commandsToRegister } ); - console.log(`✅ ${data.length} comandos registrados correctamente.`); - console.log(`🎉 Proceso completado: comandos antiguos limpiados y nuevos registrados.`); + console.log(`✅ ${data.length} comandos de guild registrados.`); } catch (error) { - console.error("❌ Error en el proceso de comandos:", error); + console.error("❌ Error en el proceso de comandos de guild:", error); + } +} + +export async function registeringGlobalCommands(): Promise { + const commandsToRegister: any[] = []; + for (const [_name, cmd] of commands) { + if (cmd.type === "slash") { + commandsToRegister.push({ + name: cmd.name, + description: cmd.description ?? "Sin descripción", + type: 1, + options: cmd.options ?? [] + }); + console.log(`🌍 Preparado para registrar global: ${cmd.name}`); + } + } + try { + console.log(`🧹 Limpiando comandos globales existentes...`); + await rest.put( + Routes.applicationCommands(process.env.CLIENT!), + { body: [] } + ); + console.log(`✅ Comandos globales previos eliminados.`); + await new Promise(r => setTimeout(r, 1500)); + console.log(`🚀 Registrando ${commandsToRegister.length} comandos globales... (propagación puede tardar hasta 1h)`); + const data: any = await rest.put( + Routes.applicationCommands(process.env.CLIENT!), + { body: commandsToRegister } + ); + console.log(`✅ ${data.length} comandos globales enviados a la API.`); + } catch (error) { + console.error("❌ Error registrando comandos globales:", error); } } -/** - * Función específica para eliminar TODOS los comandos slash (útil para limpieza) - */ export async function clearAllCommands(): Promise { try { - console.log(`🧹 Eliminando TODOS los comandos slash...`); - + console.log(`🧹 Eliminando TODOS los comandos slash (guild)...`); await rest.put( Routes.applicationGuildCommands( process.env.CLIENT!, @@ -72,28 +98,21 @@ export async function clearAllCommands(): Promise { ), { body: [] } ); - - console.log(`✅ Todos los comandos han sido eliminados correctamente.`); + console.log(`✅ Todos los comandos de guild eliminados.`); } catch (error) { - console.error("❌ Error eliminando comandos:", error); + console.error("❌ Error eliminando comandos de guild:", error); } } -/** - * Función para limpiar comandos globales (si los hay) - */ export async function clearGlobalCommands(): Promise { try { console.log(`🌍 Eliminando comandos globales...`); - await rest.put( Routes.applicationCommands(process.env.CLIENT!), { body: [] } ); - - console.log(`✅ Comandos globales eliminados correctamente.`); + console.log(`✅ Comandos globales eliminados.`); } catch (error) { console.error("❌ Error eliminando comandos globales:", error); } } -