From dcd747e9b3390cf39d3a1f8f1a0c02d5c8916e9d Mon Sep 17 00:00:00 2001 From: neru Date: Sat, 10 Jan 2026 09:17:39 -0300 Subject: [PATCH] feat: create basic bot module --- src/bot.ts | 105 +++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 105 insertions(+) create mode 100644 src/bot.ts diff --git a/src/bot.ts b/src/bot.ts new file mode 100644 index 0000000..8f6d9d6 --- /dev/null +++ b/src/bot.ts @@ -0,0 +1,105 @@ +import { + Client, + GatewayIntentBits, + OAuth2Scopes, + PermissionFlagsBits +} from 'discord.js'; +import { Logger } from './utils/log'; +import { config } from './utils/config'; + +export class Bot { + private client: Client | undefined; + + private readonly token: string; + private readonly clientId: string; + + private readonly log: Logger; + + /* + class methods + */ + private constructor() { + this.log = new Logger('Bot'); + + this.token = config.token; + this.clientId = config.client_id; + } + + public async init(): Promise { + this.log.info('Bot init'); + + if (this.client) + throw new Error('Client already exists, was init called twice?'); + + this.log.info('Instantiating client'); + this.client = new Client({ + intents: [ + GatewayIntentBits.Guilds, + GatewayIntentBits.GuildMessages, + GatewayIntentBits.GuildVoiceStates, + GatewayIntentBits.MessageContent + ] + }); + + this.log.info('Registering callbacks'); + this.client.on('clientReady', () => this.onReady()); + this.client.on('error', (err) => this.onError(err, false)); + this.client.on('shardError', (err) => this.onError(err, true)); + + this.log.info('Logging in...'); + await this.client.login(this.token); + } + + /* + event listeners + */ + private onReady(): void { + this.log.info('Logged in'); + + const inviteLink = this.client?.generateInvite({ + scopes: [OAuth2Scopes.ApplicationsCommands, OAuth2Scopes.Bot], + permissions: [ + PermissionFlagsBits.AddReactions, + PermissionFlagsBits.AttachFiles, + PermissionFlagsBits.ChangeNickname, + PermissionFlagsBits.Connect, + PermissionFlagsBits.Speak, + PermissionFlagsBits.ViewChannel, + PermissionFlagsBits.ReadMessageHistory, + PermissionFlagsBits.SendMessages, + PermissionFlagsBits.SendMessagesInThreads, + PermissionFlagsBits.SendVoiceMessages, + PermissionFlagsBits.EmbedLinks + ] + }); + + this.log.info('Invite link: %s', inviteLink); + } + + private onError(error: Error, isShardError: boolean): void { + if (isShardError) + this.log.error( + 'A shard error ocurred: %s - %s - %s', + error.name, + error.message, + error.stack + ); + else + this.log.error( + 'An error ocurred: %s - %s - %s', + error.name, + error.message, + error.stack + ); + } + + /* + singleton logic + */ + static #instance: Bot | null = null; + + public static get get(): Bot { + if (!Bot.#instance) Bot.#instance = new Bot(); + return Bot.#instance; + } +}