import { ApplicationCommandDataResolvable, Client, ClientOptions, Collection, GatewayIntentBits, Guild, IntentsBitField, Snowflake } from "discord.js"; import { CommandType } from "../types/commandTypes"; import fs from 'fs' import { config } from "../configuration"; export class ExtendedClient extends Client { private eventFilePath = `${__dirname}/../events` private commandFilePath = `${__dirname}/../commands` public commands: Collection = new Collection() public constructor() { const intents: IntentsBitField = new IntentsBitField() intents.add(IntentsBitField.Flags.GuildMembers, IntentsBitField.Flags.MessageContent, IntentsBitField.Flags.Guilds, IntentsBitField.Flags.DirectMessages) const options: ClientOptions = { intents } super(options) } public start() { if (process.env.NODE_ENV === 'test') return const promises: Promise[] = Array() promises.push(this.registerSlashCommands()) promises.push(this.registerEventCallback()) Promise.all(promises).then(() => { this.login(config.token) }) } private async importFile(filepath: string): Promise { console.debug(`Importing ${filepath}`) const imported = await import(filepath) console.debug(`Imported ${JSON.stringify(imported)}`) return imported.default ?? imported } public async registerCommands(cmds: ApplicationCommandDataResolvable[], guildIds: Collection) { if (guildIds) { guildIds.forEach(guild => { this.guilds.cache.get(guild.id)?.commands.set(cmds) console.log(`Registering commands to ${guild.name}|${guild.id}`) }) } else { this.application?.commands.set(cmds) console.log(`Registering global commands`) } return } public async registerSlashCommands(): Promise { try { const slashCommands: ApplicationCommandDataResolvable[] = [] const commandFiles = fs.readdirSync(this.commandFilePath).filter(file => file.endsWith('.ts') || file.endsWith('.js')) for (const commandFile of commandFiles) { const filePath = `${this.commandFilePath}/${commandFile}` const command = await this.importFile(filePath) console.debug(JSON.stringify(command)) if (!command.name) return console.debug(command) this.commands.set(command.name, command) slashCommands.push(command) } this.on("ready", (client: Client) => { //console.log(`Ready processing ${JSON.stringify(client)}`) console.log(`SlashCommands: ${JSON.stringify(slashCommands)}`) const guilds = client.guilds.cache this.registerCommands(slashCommands, guilds) this.cacheUsers(guilds) }) } catch (error) { console.log(`Error refreshing slash commands: ${error}`) } } public async cacheUsers(guilds: Collection) { guilds.forEach((guild:Guild, id:Snowflake) => { console.log(`Fetching members for ${guild.name}|${id}`) guild.members.fetch() console.log(`Fetched: ${guild.memberCount} members`) }) } public async registerEventCallback() { try { const eventFiles = fs.readdirSync(this.eventFilePath).filter(file => file.endsWith('.ts') || file.endsWith('.js')); for (const file of eventFiles) { const filePath = `${this.eventFilePath}/${file}` const event = await this.importFile(filePath) if (event.once) { console.log(`Registering once ${file}`) this.once(event.name, (...args: any[]) => event.execute(...args)) } else { console.log(`Registering on ${file}`) this.on(event.name, (...args: any[]) => event.execute(...args)) } } console.log(this.eventNames()) } catch (error) { console.error(error) } } }