11import colors from "colors" ;
2- import { Guild , REST , Routes } from "discord.js" ;
2+ import { ChatInputCommandInteraction , Guild , REST , Routes , SlashCommandBuilder } from "discord.js" ;
33import fs from "fs" ;
44import path from "path" ;
55import { pathToFileURL } from "url" ;
@@ -10,12 +10,16 @@ import {Logger} from "../main/logger.js";
1010import { Config } from "../main/config.js" ;
1111import { database } from "../main/database.js" ;
1212import { cli } from "winston/lib/winston/config/index.js" ;
13+ import { IDisBotCommand } from "../types/Interaction.js" ;
14+ import { DisBotInteractionType } from "../enums/disBotInteractionType.js" ;
1315
1416colors . enable ( ) ;
1517
1618export class CommandHelper {
1719
18- public static async loadCommandsForGuild ( client : ExtendedClient , guild : Guild ) {
20+ public static async loadCommandsForGuild ( client : ExtendedClient , guildId : string ) {
21+
22+ Logger . info ( `Starting Command loading for ${ guildId } ....` . gray . italic )
1923
2024 let cmdlist : any [ ] = [ ] ;
2125 const stats = {
@@ -105,103 +109,94 @@ export class CommandHelper {
105109 throw new Error ( "Missing Config variables: DiscordApplicationId or DiscordBotToken" ) ;
106110 }
107111
108- const restClient = new REST ( { version : "10" } ) . setToken ( Config . Bot . DiscordBotToken ) ;
109-
110- // Clear Guild Commands
111- await restClient . put ( Routes . applicationGuildCommands ( Config . Bot . DiscordApplicationId , guild . id ) , {
112- body : [ ] ,
113- } ) ;
114-
115112 const buildInCommandOverrides = await database . buildInCommands . findMany ( {
116113 where : {
117- GuildCommandMangerId : guild . id
114+ GuildCommandMangerId : guildId
118115 }
119116 } )
120- try {
121- cmdlist = cmdlist
122- . filter ( cmd => {
123- const override = buildInCommandOverrides . find ( o => o . CodeName === cmd . name ) ;
124- return ! ( override && override . IsEnabled === false ) ;
125- } )
126- . map ( cmd => {
127- const override = buildInCommandOverrides . find ( o => o . CodeName === cmd . name ) ;
128- if ( override ) {
129- return {
130- ...cmd ,
131- name : override . CustomName ,
132- description : override . Description ?? client . commands . get ( override . CodeName ) . command . description ,
133- default_member_permissions : override . Permissions ?? client . commands . get ( override . CodeName ) . command . default_member_permissions
134- } ;
135- }
136- return cmd ;
137- } )
138117
139- await restClient . put ( Routes . applicationGuildCommands ( Config . Bot . DiscordApplicationId , guild . id ) , {
140- body : cmdlist ,
141- } ) ;
118+ // TODO: ADD COMMAND_OVERWRITES
142119
143- const ticketCommands = await database . ticketSetups . findMany ( {
144- where : {
145- GuildId : guild . id
146- }
120+ Logger . info ( `Sending commands to guild ${ guildId } for client ${ client . user . username } ` ) ;
121+
122+ try {
123+ const commandReq = await fetch ( `https://discord.com/api/v10/applications/${ client . user . id } /guilds/${ guildId } /commands` , {
124+ method : "PUT" ,
125+ headers : {
126+ "Content-Type" : "application/json" ,
127+ Authorization : `Bot ${ Config . Bot . DiscordBotToken } `
128+ } ,
129+ body : JSON . stringify ( cmdlist )
147130 } )
131+ const data = await commandReq . json ( )
132+ console . log ( JSON . stringify ( data ) )
133+
134+ } catch ( e ) {
135+ Logger . error ( `Failed to load commands: ${ e } ` )
136+ }
137+
138+ const ticketCommands = await database . ticketSetups . findMany ( {
139+ where : {
140+ GuildId : guildId
141+ }
142+ } )
148143
144+ if ( ticketCommands . length > 0 ) {
149145 for ( const ticketCommand of ticketCommands ) {
150- const clientGuild = await client . guilds . fetch ( guild . id ) ;
146+ const clientGuild = await client . guilds . fetch ( guildId ) ;
151147
152148 let guildCommand = null ;
153149 try {
154150 guildCommand = await clientGuild . commands . fetch ( ticketCommand . SlashCommandId ) ;
155- } catch {
151+ } catch ( e ) {
152+ Logger . error ( `Failed to load commands: ${ e } ` )
156153 }
157154
158155 if ( ! guildCommand ) {
159- guildCommand = await clientGuild . commands . create ( {
160- name : ticketCommand . SlashCommandName ?? `open-${ ticketCommand . CustomId } -ticket` ,
161- description : ticketCommand . SlashCommandDescription ?? ticketCommand . CustomId ,
162- } ) ;
156+ try {
157+ guildCommand = await clientGuild . commands . create ( {
158+ name : ticketCommand . SlashCommandName ?? `open-${ ticketCommand . CustomId } -ticket` ,
159+ description : ticketCommand . SlashCommandDescription ?? ticketCommand . CustomId ,
160+ } ) ;
163161
164- await database . ticketSetups . update ( {
165- where : {
166- CustomId : ticketCommand . CustomId ,
167- } ,
168- data : {
169- SlashCommandId : guildCommand . id ,
170- } ,
171- } ) ;
162+ await database . ticketSetups . update ( {
163+ where : {
164+ CustomId : ticketCommand . CustomId ,
165+ } ,
166+ data : {
167+ SlashCommandId : guildCommand . id ,
168+ } ,
169+ } ) ;
170+ } catch ( e ) {
171+ Logger . error ( `Failed to load commands: ${ e } ` )
172+ }
172173 } else {
173174 if (
174175 guildCommand . name !== ticketCommand . SlashCommandName ||
175176 guildCommand . description !== ticketCommand . SlashCommandDescription
176177 ) {
177- const updated = await guildCommand . edit ( {
178- name : ticketCommand . SlashCommandName ?? guildCommand . name ,
179- description : ticketCommand . SlashCommandDescription ?? guildCommand . description ,
180- } ) ;
181-
182- await database . ticketSetups . update ( {
183- where : { CustomId : ticketCommand . CustomId } ,
184- data : { SlashCommandId : updated . id } ,
185- } ) ;
178+ try {
179+ const updated = await guildCommand . edit ( {
180+ name : ticketCommand . SlashCommandName ?? guildCommand . name ,
181+ description : ticketCommand . SlashCommandDescription ?? guildCommand . description ,
182+ } ) ;
183+
184+ await database . ticketSetups . update ( {
185+ where : { CustomId : ticketCommand . CustomId } ,
186+ data : { SlashCommandId : updated . id } ,
187+ } ) ;
188+ } catch ( e ) {
189+ Logger . error ( `Failed to load commands: ${ e } ` )
190+ }
186191 }
187192 }
188193 }
189- } catch ( e ) {
190- Logger . error ( {
191- timestamp : new Date ( ) . toISOString ( ) ,
192- level : "error" ,
193- label : "CommandHelper" ,
194- message : `Command loading failed with error: ${ e } - Commands failed at ${ cmdlist . map ( ( c ) => c . name ) } commands on Guild \"${ guild . name } \" (${ guild . id } )` ,
195- botType : Config . BotType . toString ( ) || "Unknown" ,
196- action : LoggingAction . Command ,
197- } ) ;
198194 }
199-
200195 Logger . info ( {
201196 timestamp : new Date ( ) . toISOString ( ) ,
202197 level : "info" ,
203198 label : "CommandHelper" ,
204- message : `Discord added ${ cmdlist . length } commands (${ stats . subCommands } subCommands, ${ stats . subCommandGroups } subCommandGroups), ${ stats . userInstall } userInstall commands, ${ stats . contextMenus } context menu commands from ${ moduleDirectories . length } module(s) for \" ${ guild . name } \" ( ${ guild . id } ) ` ,
199+ message : `Discord added ${ cmdlist . length } commands (${ stats . subCommands } subCommands, ${ stats . subCommandGroups } subCommandGroups), ${ stats . userInstall } userInstall commands, ${ stats . contextMenus } context menu commands from ${ moduleDirectories . length } module(s) for ${ guildId } ` ,
205200 botType : Config . BotType . toString ( ) || "Unknown" ,
206201 action : LoggingAction . Command ,
207202 } ) ;
@@ -329,11 +324,72 @@ export class CommandHelper {
329324
330325 const guilds = await client . guilds . fetch ( )
331326 guilds . map ( async ( guild ) => {
332- const clientGuild = await client . guilds . fetch ( guild . id )
333- await this . loadCommandsForGuild ( client , clientGuild )
334- setTimeout ( ( ) => {
335- } , 1500 )
336- console . log ( "NEXT GUILD" )
327+ await this . loadCommandsForGuild ( client , guild . id )
328+ } )
329+ }
330+
331+ public static async loadCustomAdminCommands ( client : ExtendedClient ) {
332+ const guild = await client . guilds . fetch ( Config . Bot . AdminGuildId )
333+
334+ const commands = [
335+ {
336+ interactionName : "Load Guild Commands" ,
337+ type : DisBotInteractionType . Command ,
338+ command : new SlashCommandBuilder ( )
339+ . setName ( "loadcommands" )
340+ . setDescription ( "Load Commands for all Guilds." ) ,
341+ execute : async ( interaction : ChatInputCommandInteraction , client : ExtendedClient ) => {
342+ await interaction . deferReply ( ) ;
343+
344+ const guilds = await client . guilds . fetch ( ) ;
345+ const guildArray = Array . from ( guilds . values ( ) ) ;
346+
347+ const delay = ( ms : number ) => new Promise ( resolve => setTimeout ( resolve , ms ) ) ;
348+
349+ let processedCount = 0 ;
350+ let successCount = 0 ;
351+ let errorCount = 0 ;
352+ const BATCH_SIZE = 5 ;
353+ const DELAY_MS = 3000 ;
354+
355+ for ( const guild of guildArray ) {
356+ try {
357+ if ( processedCount > 0 && processedCount % BATCH_SIZE === 0 ) {
358+ await interaction . editReply ( {
359+ content : `-# 📡 Loading commands... (${ processedCount } /${ guilds . size } ) - ⏸️ Waiting 3s...`
360+ } ) ;
361+ await delay ( DELAY_MS ) ;
362+ }
363+
364+ await CommandHelper . loadCommandsForGuild ( client , guild . id ) ;
365+ successCount ++ ;
366+
367+ if ( processedCount % 3 === 0 || processedCount === guildArray . length - 1 ) {
368+ await interaction . editReply ( {
369+ content : `-# 📡 Loading commands... (${ processedCount + 1 } /${ guilds . size } )`
370+ } ) ;
371+ }
372+ } catch ( error ) {
373+ errorCount ++ ;
374+ console . error ( `Failed to load commands for guild ${ guild . id } :` , error ) ;
375+ } finally {
376+ processedCount ++ ;
377+ }
378+ }
379+
380+ await interaction . editReply ( {
381+ content : `-# ✅ Commands loaded for ${ successCount } /${ guilds . size } guild(s)${ errorCount > 0 ? ` (${ errorCount } failed)` : '' } `
382+ } ) ;
383+ }
384+ } as IDisBotCommand
385+ ]
386+
387+
388+ commands . map ( ( commandData ) => {
389+ client . guildCommands . set ( commandData . command . name , commandData )
337390 } )
391+ await guild . commands . set (
392+ commands . map ( ( commandData ) => commandData . command )
393+ )
338394 }
339395}
0 commit comments