1- const fs = require ( 'node:fs' ) ;
2- const path = require ( 'node:path' ) ;
3- const { Client, GatewayIntentBits, REST , Collection, Routes, ActivityType } = require ( "discord.js" ) ;
4- const { getEnvironment } = require ( "./src/Configs/EnvironmentSelector" ) ;
5- const { DatabaseConnection } = require ( "./src/Database/DbConnection" ) ;
6- const { WebServer } = require ( './src/WebServer' ) ;
7- const { default : AutoPoster } = require ( 'topgg-autoposter' ) ;
8- const config = require ( './config.json' ) ;
1+ import fs from 'node:fs' ;
2+ import path from 'node:path' ;
3+ import { Client , GatewayIntentBits , REST , Collection , Routes , ActivityType } from "discord.js" ;
4+ import { fileURLToPath , pathToFileURL } from 'node:url' ;
5+ import getEnvironment from "./src/Configs/EnvironmentSelector.js" ;
6+ // import { DatabaseConnection } from "./src/Database/DbConnection";
7+ import WebServerModule from './src/WebServer.js' ;
8+ // import { default as AutoPoster } from 'topgg-autoposter';
9+ // import raw from './config.json' assert { type: 'json' };
10+ // const config = raw;
11+
12+ // Resuelve __dirname en ESM
13+ const __filename = fileURLToPath ( import . meta. url ) ;
14+ const __dirname = path . dirname ( __filename ) ;
915
1016getEnvironment ( ) ;
11- if ( config . database . active === true ) {
12- DatabaseConnection . getInstance ( ) ;
13- }
14- if ( config . api . active === true ) {
15- new WebServer ( ) . listen ( ) ;
17+ // if (config.database.active === true) {
18+ // DatabaseConnection.getInstance();
19+ // }
20+ // Arranque opcional del servidor HTTP según variable de entorno.
21+ if ( process . env . API_ACTIVE === 'true' ) {
22+ new WebServerModule . WebServer ( ) . listen ( ) ;
1623}
1724
1825const client = new Client ( { intents : [ GatewayIntentBits . Guilds , GatewayIntentBits . GuildMessages ] } ) ;
@@ -21,26 +28,34 @@ const commandsPath = path.join(__dirname, './src/Commands');
2128const commandFiles = fs . readdirSync ( commandsPath ) . filter ( file => file . endsWith ( '.js' ) ) ;
2229const commands = [ ] ;
2330
24- for ( const file of commandFiles ) {
25- const filePath = path . join ( commandsPath , file ) ;
26- const command = require ( filePath ) ;
27- client . commands . set ( command . data . name , command ) ;
28- commands . push ( command . data . toJSON ( ) ) ;
31+ /**
32+ * Carga dinámicamente los comandos desde la carpeta ./src/Commands en ESM.
33+ */
34+ async function loadCommands ( ) {
35+ for ( const file of commandFiles ) {
36+ const filePath = path . join ( commandsPath , file ) ;
37+ const module = await import ( pathToFileURL ( filePath ) . href ) ;
38+ const command = module . default ;
39+ client . commands . set ( command . data . name , command ) ;
40+ commands . push ( command . data . toJSON ( ) ) ;
41+ }
2942}
3043
31- const rest = new REST ( { version : '10' } ) . setToken ( process . env . TOKEN ) ;
44+ // Registro de comandos vía REST (ejecuta tras cargar comandos)
3245
33- setInterval ( async ( ) => {
34- if ( process . env . STEAMID_ENV === 'production' ) {
35- const ap = AutoPoster ( process . env . DBL_TOKEN , client ) ;
36- ap . on ( 'posted' , ( ) => {
37- console . log ( 'Server count posted!' ) ;
38- } )
39- }
40- } , 3600000 ) ;
46+ // setInterval(async () => {
47+ // if (process.env.STEAMID_ENV === 'production') {
48+ // const ap = AutoPoster(process.env.DBL_TOKEN, client);
49+ // ap.on('posted', () => {
50+ // console.log('Server count posted!');
51+ // })
52+ // }
53+ // }, 3600000);
4154
4255( async ( ) => {
4356 try {
57+ await loadCommands ( ) ;
58+ const rest = new REST ( { version : '10' } ) . setToken ( process . env . TOKEN ) ;
4459 console . log ( 'Started refreshing application (/) commands.' ) ;
4560 await rest . put (
4661 Routes . applicationCommands ( process . env . CLIENT_ID ) ,
@@ -59,6 +74,14 @@ client.on('ready', () => {
5974} ) ;
6075
6176client . on ( 'interactionCreate' , async interaction => {
77+ /**
78+ * Maneja interacciones de comandos (slash) de Discord.
79+ * Si ocurre un error, responde de forma segura usando `reply` o `followUp`
80+ * según si la interacción ya fue reconocida (deferred/replied) para evitar
81+ * el error "Interaction has already been acknowledged".
82+ * Usa `flags: 64` para respuestas efímeras (deprecado `ephemeral`).
83+ * @param {import('discord.js').Interaction } interaction - Interacción entrante.
84+ */
6285 if ( ! interaction . isChatInputCommand ( ) ) return ;
6386 const command = client . commands . get ( interaction . commandName ) ;
6487 if ( ! command ) return ;
@@ -67,7 +90,17 @@ client.on('interactionCreate', async interaction => {
6790 await command . execute ( interaction ) ;
6891 } catch ( error ) {
6992 console . error ( error ) ;
70- await interaction . reply ( { content : 'There was an error while executing this command!' , ephemeral : true } ) ;
93+ const errorPayload = { content : 'There was an error while executing this command!' , flags : 64 } ;
94+ try {
95+ if ( interaction . deferred || interaction . replied ) {
96+ await interaction . followUp ( errorPayload ) ;
97+ } else {
98+ await interaction . reply ( errorPayload ) ;
99+ }
100+ } catch ( e ) {
101+ // Evita que el proceso se caiga si no puede responder
102+ console . error ( 'Failed to send error response for interaction:' , e ) ;
103+ }
71104 }
72105} ) ;
73106
0 commit comments