joel bot
This commit is contained in:
40
src/events/handlers/guild.ts
Normal file
40
src/events/handlers/guild.ts
Normal file
@@ -0,0 +1,40 @@
|
||||
/**
|
||||
* Guild events handlers
|
||||
*/
|
||||
|
||||
import { Events } from "discord.js";
|
||||
import type { EventHandler } from "../types";
|
||||
import { guildRepository, userRepository } from "../../database";
|
||||
import { createLogger } from "../../core/logger";
|
||||
|
||||
const logger = createLogger("Events:Guild");
|
||||
|
||||
export const guildCreateHandler: EventHandler<"guildCreate"> = {
|
||||
name: Events.GuildCreate as "guildCreate",
|
||||
once: false,
|
||||
execute: async (_client, guild) => {
|
||||
logger.info(`Joined guild: ${guild.name}`);
|
||||
await guildRepository.create({
|
||||
id: guild.id,
|
||||
name: guild.name,
|
||||
});
|
||||
},
|
||||
};
|
||||
|
||||
export const guildMemberAddHandler: EventHandler<"guildMemberAdd"> = {
|
||||
name: Events.GuildMemberAdd as "guildMemberAdd",
|
||||
once: false,
|
||||
execute: async (_client, member) => {
|
||||
await userRepository.addMembership(member.id, member.guild.id);
|
||||
logger.debug(`Member joined: ${member.displayName} in ${member.guild.name}`);
|
||||
},
|
||||
};
|
||||
|
||||
export const guildMemberRemoveHandler: EventHandler<"guildMemberRemove"> = {
|
||||
name: Events.GuildMemberRemove as "guildMemberRemove",
|
||||
once: false,
|
||||
execute: async (_client, member) => {
|
||||
await userRepository.removeMembership(member.id);
|
||||
logger.debug(`Member left: ${member.displayName} in ${member.guild.name}`);
|
||||
},
|
||||
};
|
||||
8
src/events/handlers/index.ts
Normal file
8
src/events/handlers/index.ts
Normal file
@@ -0,0 +1,8 @@
|
||||
/**
|
||||
* Event handler exports
|
||||
*/
|
||||
|
||||
export { readyHandler } from "./ready";
|
||||
export { messageCreateHandler } from "./message-create";
|
||||
export { interactionCreateHandler } from "./interaction-create";
|
||||
export { guildCreateHandler, guildMemberAddHandler, guildMemberRemoveHandler } from "./guild";
|
||||
16
src/events/handlers/interaction-create.ts
Normal file
16
src/events/handlers/interaction-create.ts
Normal file
@@ -0,0 +1,16 @@
|
||||
/**
|
||||
* Interaction Create event handler
|
||||
*/
|
||||
|
||||
import { Events } from "discord.js";
|
||||
import type { EventHandler } from "../types";
|
||||
import { handleCommand } from "../../commands";
|
||||
|
||||
export const interactionCreateHandler: EventHandler<"interactionCreate"> = {
|
||||
name: Events.InteractionCreate as "interactionCreate",
|
||||
once: false,
|
||||
execute: async (_client, interaction) => {
|
||||
if (!interaction.isChatInputCommand()) return;
|
||||
await handleCommand(interaction);
|
||||
},
|
||||
};
|
||||
29
src/events/handlers/message-create.ts
Normal file
29
src/events/handlers/message-create.ts
Normal file
@@ -0,0 +1,29 @@
|
||||
/**
|
||||
* Message Create event handler
|
||||
*/
|
||||
|
||||
import { Events } from "discord.js";
|
||||
import type { EventHandler } from "../types";
|
||||
import { createLogger } from "../../core/logger";
|
||||
import { messageLogger } from "../../features/message-logger";
|
||||
import { joelResponder } from "../../features/joel";
|
||||
|
||||
const logger = createLogger("Events:MessageCreate");
|
||||
|
||||
export const messageCreateHandler: EventHandler<"messageCreate"> = {
|
||||
name: Events.MessageCreate as "messageCreate",
|
||||
once: false,
|
||||
execute: async (client, message) => {
|
||||
// Ignore bot messages
|
||||
if (message.author.bot) return;
|
||||
|
||||
// Only process guild messages
|
||||
if (!message.inGuild()) return;
|
||||
|
||||
// Log message to database
|
||||
await messageLogger.logMessage(message);
|
||||
|
||||
// Handle Joel responses
|
||||
await joelResponder.handleMessage(client, message);
|
||||
},
|
||||
};
|
||||
58
src/events/handlers/ready.ts
Normal file
58
src/events/handlers/ready.ts
Normal file
@@ -0,0 +1,58 @@
|
||||
/**
|
||||
* Client Ready event handler
|
||||
*/
|
||||
|
||||
import { ActivityType, Events } from "discord.js";
|
||||
import type { EventHandler } from "../types";
|
||||
import { loadCommands, registerCommands } from "../../commands";
|
||||
import { guildRepository } from "../../database";
|
||||
import { createLogger } from "../../core/logger";
|
||||
|
||||
const logger = createLogger("Events:Ready");
|
||||
|
||||
export const readyHandler: EventHandler<"ready"> = {
|
||||
name: Events.ClientReady as "ready",
|
||||
once: true,
|
||||
execute: async (client) => {
|
||||
logger.info(`Logged in as ${client.user?.tag}`);
|
||||
|
||||
// Set initial activity
|
||||
client.user?.setActivity({
|
||||
name: "Joel blir väckt...",
|
||||
type: ActivityType.Custom,
|
||||
});
|
||||
|
||||
// Load and register commands
|
||||
const commands = await loadCommands();
|
||||
for (const command of commands) {
|
||||
client.commands.set(command.data.name, command);
|
||||
}
|
||||
await registerCommands(commands, client.user!.id);
|
||||
|
||||
// Sync guilds with database
|
||||
await syncGuilds(client);
|
||||
|
||||
// Update activity to show ready
|
||||
client.user?.setActivity({
|
||||
name: "Joel är VAKEN",
|
||||
type: ActivityType.Custom,
|
||||
});
|
||||
|
||||
logger.info("Bot is ready!");
|
||||
},
|
||||
};
|
||||
|
||||
async function syncGuilds(client: import("../../core/client").BotClient): Promise<void> {
|
||||
const discordGuilds = await client.guilds.fetch();
|
||||
const dbGuilds = await guildRepository.findAll();
|
||||
|
||||
const existingIds = new Set(dbGuilds.map((g) => g.id));
|
||||
const toAdd = discordGuilds
|
||||
.filter((g) => !existingIds.has(g.id))
|
||||
.map((g) => ({ id: g.id, name: g.name }));
|
||||
|
||||
if (toAdd.length > 0) {
|
||||
await guildRepository.createMany(toAdd);
|
||||
logger.info(`Added ${toAdd.length} guilds to database`);
|
||||
}
|
||||
}
|
||||
6
src/events/index.ts
Normal file
6
src/events/index.ts
Normal file
@@ -0,0 +1,6 @@
|
||||
/**
|
||||
* Events module exports
|
||||
*/
|
||||
|
||||
export type { EventHandler } from "./types";
|
||||
export { registerEvents } from "./register";
|
||||
43
src/events/register.ts
Normal file
43
src/events/register.ts
Normal file
@@ -0,0 +1,43 @@
|
||||
/**
|
||||
* Event registration
|
||||
*/
|
||||
|
||||
import type { BotClient } from "../core/client";
|
||||
import { createLogger } from "../core/logger";
|
||||
import type { AnyEventHandler } from "./types";
|
||||
import {
|
||||
readyHandler,
|
||||
messageCreateHandler,
|
||||
interactionCreateHandler,
|
||||
guildCreateHandler,
|
||||
guildMemberAddHandler,
|
||||
guildMemberRemoveHandler,
|
||||
} from "./handlers";
|
||||
|
||||
const logger = createLogger("Events:Register");
|
||||
|
||||
// All event handlers
|
||||
const handlers: AnyEventHandler[] = [
|
||||
readyHandler,
|
||||
messageCreateHandler,
|
||||
interactionCreateHandler,
|
||||
guildCreateHandler,
|
||||
guildMemberAddHandler,
|
||||
guildMemberRemoveHandler,
|
||||
];
|
||||
|
||||
/**
|
||||
* Register all event handlers on the client
|
||||
*/
|
||||
export function registerEvents(client: BotClient): void {
|
||||
for (const handler of handlers) {
|
||||
if (handler.once) {
|
||||
client.once(handler.name, (...args) => handler.execute(client, ...args));
|
||||
} else {
|
||||
client.on(handler.name, (...args) => handler.execute(client, ...args));
|
||||
}
|
||||
logger.debug(`Registered event: ${handler.name}`);
|
||||
}
|
||||
|
||||
logger.info(`Registered ${handlers.length} event handlers`);
|
||||
}
|
||||
24
src/events/types.ts
Normal file
24
src/events/types.ts
Normal file
@@ -0,0 +1,24 @@
|
||||
/**
|
||||
* Event types and interfaces
|
||||
*/
|
||||
|
||||
import type { ClientEvents } from "discord.js";
|
||||
import type { BotClient } from "../core/client";
|
||||
|
||||
export interface EventHandler<K extends keyof ClientEvents = keyof ClientEvents> {
|
||||
/** Event name to listen for */
|
||||
name: K;
|
||||
|
||||
/** Whether to only run once */
|
||||
once?: boolean;
|
||||
|
||||
/** Execute the event handler */
|
||||
execute: (client: BotClient, ...args: ClientEvents[K]) => Promise<void> | void;
|
||||
}
|
||||
|
||||
// Type-safe event handler that can be stored in an array
|
||||
export type AnyEventHandler = {
|
||||
name: keyof ClientEvents;
|
||||
once?: boolean;
|
||||
execute: (client: BotClient, ...args: any[]) => Promise<void> | void;
|
||||
};
|
||||
Reference in New Issue
Block a user