Compare commits

..

2 Commits

Author SHA1 Message Date
neru 710de16af1 feat: add registerable events 2026-01-10 09:26:40 -03:00
neru 88305e5c8b feat: add extra event listeners 2026-01-10 09:19:27 -03:00
+90 -1
View File
@@ -1,12 +1,23 @@
import {
CacheType,
Client,
GatewayIntentBits,
Interaction,
Message,
OAuth2Scopes,
PermissionFlagsBits
PermissionFlagsBits,
VoiceState
} from 'discord.js';
import { Logger } from './utils/log';
import { config } from './utils/config';
type BotEventListeners = {
'messageCreate': (message: Message) => void;
'interactionCreate': (interaction: Interaction) => void;
'voiceStateUpdate': (oldState: VoiceState, newState: VoiceState) => void;
};
type BotEventListener<K extends keyof BotEventListeners> = BotEventListeners[K];
export class Bot {
private client: Client | undefined;
@@ -15,6 +26,66 @@ export class Bot {
private readonly log: Logger;
private eventListeners: {
[K in keyof BotEventListeners]?: BotEventListener<K>[];
} = {};
/*
event methods
*/
public on<K extends keyof BotEventListeners>(
event: K,
listener: BotEventListener<K>
): void {
if (!this.eventListeners[event]) {
this.eventListeners[event] = [];
}
(this.eventListeners[event] as BotEventListener<K>[]).push(listener);
}
public off<K extends keyof BotEventListeners>(
event: K,
listener: BotEventListener<K>
): boolean {
const listeners = this.eventListeners[event];
if (!listeners) return false;
const index = (listeners as BotEventListener<K>[]).indexOf(listener);
if (index > -1) {
(listeners as BotEventListener<K>[]).splice(index, 1);
return true;
}
return false;
}
public once<K extends keyof BotEventListeners>(
event: K,
listener: BotEventListener<K>
): void {
const onceWrapper = ((...args: Parameters<BotEventListener<K>>) => {
this.off(event, onceWrapper as BotEventListener<K>);
(listener as (...args: unknown[]) => void)(...args);
}) as BotEventListener<K>;
this.on(event, onceWrapper);
}
private emit<K extends keyof BotEventListeners>(
event: K,
...args: Parameters<BotEventListener<K>>
): void {
const listeners = this.eventListeners[event];
if (listeners) {
for (const listener of listeners as BotEventListener<K>[]) {
try {
(listener as (...args: unknown[]) => void)(...args);
} catch (error) {
this.log.error(`Error in event listener for ${String(event)}:`, error);
}
}
}
}
/*
class methods
*/
@@ -45,6 +116,9 @@ export class Bot {
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.client.on('messageCreate', (message: Message<boolean>) => this.onMessage(message));
this.client.on('interactionCreate', (interaction: Interaction<CacheType>) => this.onInteraction(interaction));
this.client.on('voiceStateUpdate', (oldState: VoiceState, newState: VoiceState) => this.onVoiceStateUpdate(oldState, newState));
this.log.info('Logging in...');
await this.client.login(this.token);
@@ -93,6 +167,21 @@ export class Bot {
);
}
/*
public event listeners
*/
private async onInteraction(interaction: Interaction): Promise<void> {
this.emit('interactionCreate', interaction);
}
private async onMessage(message: Message): Promise<void> {
this.emit('messageCreate', message);
}
private async onVoiceStateUpdate(oldState: VoiceState, newState: VoiceState): Promise<void> {
this.emit('voiceStateUpdate', oldState, newState);
}
/*
singleton logic
*/