Skip to main content

Documentation Index

Fetch the complete documentation index at: https://mintlify.com/resynceddesign/giveawaybot/llms.txt

Use this file to discover all available pages before exploring further.

GiveawayBot uses a file-based event system that mirrors its command handler: drop a file into src/events/, build, and restart. Every Discord.js gateway event is available, and you can add as many handlers as you need without modifying any core files.

How the handler works

src/handlers/Event.ts runs at startup and uses readdirSync to scan the compiled build/events/ directory. For each .js file it finds, it imports the default export and registers it with the Discord.js client:
readdirSync(eventsDir).forEach((file) => {
    if (!file.endsWith(".js")) return;
    let event: BotEvent = require(`${eventsDir}/${file}`).default;
    event.once
        ? client.once(event.name, (...args) => event.execute(...args))
        : client.on(event.name, (...args) => event.execute(...args));
});
If once is true, the handler uses client.once so it fires only the first time the event occurs. Otherwise it uses client.on for every occurrence.

The BotEvent interface

Every event file must export a default object satisfying the BotEvent interface from src/types.d.ts:
export interface BotEvent {
    name: string;        // Discord.js event name
    once?: boolean;      // use client.once instead of client.on
    execute: (...args) => void;
}
  • name — any Discord.js Events enum value or its string equivalent (e.g. "ready", "messageCreate").
  • once — when true, the handler fires exactly once and is removed automatically. Defaults to false.
  • execute — the function that runs when the event fires. Argument types match the Discord.js event signature.

Built-in events

GiveawayBot ships with three event handlers in src/events/:
FileEventoncePurpose
ready.tsreadytrueSets the bot’s activity status and starts the 1-second giveaway check interval via setInterval(() => processGiveaways(client), 1000)
interactionCreate.tsinteractionCreateRoutes slash commands (with cooldown enforcement), autocomplete, modal submits, and button clicks (giveaway entry handling)
guildCreate.tsguildCreateCalls GuildManager.createGuild() to insert a new SQLite row with default settings whenever the bot joins a server

Adding a custom event

1

Create a new file in src/events/

Create src/events/myEvent.ts. The filename does not need to match the event name, but keeping them consistent makes the codebase easier to navigate.
2

Implement the BotEvent interface

Export a default object that satisfies BotEvent. Here is an example that logs a message to the console whenever the bot is removed from a server:
import { Guild } from "discord.js";
import { BotEvent } from "../types";

const event: BotEvent = {
    name: "guildDelete",
    execute: (guild: Guild) => {
        console.log(`Left guild: ${guild.name} (${guild.id})`);
    },
};

export default event;
For a messageCreate handler, the signature would be:
import { Message } from "discord.js";
import { BotEvent } from "../types";

const event: BotEvent = {
    name: "messageCreate",
    execute: (message: Message) => {
        if (message.author.bot) return;
        // handle message
    },
};

export default event;
3

Build and restart

Compile and restart the bot:
npm run build
On the next startup, Event.ts will find and register your new handler automatically.
Use once: true only for events that should fire a single time per process lifetime — typically ready. For recurring events like messageCreate or guildMemberAdd, omit once (or set it to false) so the handler stays registered and fires every time the event occurs.

Build docs developers (and LLMs) love