Skip to content

Creating a simple handler

Creating a command handler might look daunting at first because of lilybird’s interface, but, i can assure you its simple.

For our examples we will be using Bun.FileSystemRouter because well its bun, but, you can use other options like fs.readdir.

Creating an event handler

Handling events its trivial, all we need to do is read a file and pass the function as a listener.

We will be using the following event structure for this example:

import type { ClientEventListeners } from "lilybird";
export interface Event<
E extends keyof ClientEventListeners = keyof ClientEventListeners,
T extends Required<ClientEventListeners> = Required<ClientEventListeners>
> {
name?: string;
event: E;
run: (...args: Parameters<T[E]>) => Awaitable<any>;
}

Lets start by creating our main function and read all the files in a directory.

event-handler.ts
import type { ClientEventListeners } from "lilybird";
function createEventListeners(directory: string): ClientEventListeners {
const router = new Bun.FileSystemRouter({
fileExtensions: [".ts", ".tsx", ".js", ".jsx"],
style: "nextjs",
dir: directory
});
}

After getting all the files in the directory we can start iterating over them and importing the files.

event-handler.ts
import type { ClientEventListeners } from "lilybird";
function createEventListeners(directory: string): ClientEventListeners {
const router = new Bun.FileSystemRouter({
fileExtensions: [".ts", ".tsx", ".js", ".jsx"],
style: "nextjs",
dir: directory
});
for (let i = 0, values = Object.values(router.routes), { length } = values; i < length; i++) {
const route = values[i];
const file: Event = (await import(val)).default;
if (typeof file === "undefined") continue;
}
}

Now that we have the file we can start building an object with all the listeners.

event-handler.ts
import type { ClientEventListeners } from "lilybird";
function createEventListeners(directory: string): ClientEventListeners {
const router = new Bun.FileSystemRouter({
fileExtensions: [".ts", ".tsx", ".js", ".jsx"],
style: "nextjs",
dir: directory
});
const listeners: ClientEventListeners = {};
for (let i = 0, values = Object.values(router.routes), { length } = values; i < length; i++) {
const route = values[i];
const file: Event = (await import(val)).default;
if (typeof file === "undefined") continue;
listeners[file.event] = file.run;
}
return listeners;
}

Now you can simply pass the return type into the client listeners property and it will just work.

Creating a slash command handler

A slash command handler its fairly similar to an event handler the only difference is that you need to push the data to discord using the rest api.

We will be using the following structure for our slash commands:

import type {
POSTApplicationCommandStructure,
ApplicationCommandData,
AutocompleteData,
Interaction,
Awaitable
} from "lilybird";
export interface SlashCommand {
data: POSTApplicationCommandStructure;
autocomplete?: (interaction: Interaction<AutocompleteData>) => Awaitable<any>;
run: (interaction: Interaction<ApplicationCommandData>) => Awaitable<any>;
}

Before creating the handler lets take a look at building the onInteraction helper.

command-handler.ts
const slashCommands = new Map<string, SlashCommand>();
async function onInteraction(interaction: Interaction): Promise<void> {
if (interaction.isApplicationCommandInteraction()) {
await slashCommands.get(interaction.data.name)?.run(interaction);
} else if (interaction.isAutocompleteInteraction()) {
await slashCommands.get(interaction.data.name)?.autocomplete?.(interaction);
}
}

Now that we have the helper lets use our event handler as a base and modify it.

command-handler.ts
import type { ClientEventListeners, REST } from "lilybird";
const rest = new REST(YOUR_TOKEN);
function createEventListeners(directory: string): ClientEventListeners {
const router = new Bun.FileSystemRouter({
fileExtensions: [".ts", ".tsx", ".js", ".jsx"],
style: "nextjs",
dir: directory
});
const listeners: ClientEventListeners = {};
for (let i = 0, values = Object.values(router.routes), { length } = values; i < length; i++) {
const route = values[i];
const file: Event = (await import(val)).default;
const file: SlashCommand = (await import(val)).default;
if (typeof file === "undefined") continue;
listeners[file.event] = file.run;
slashCommands.set(file.data.name, file)
await rest.createGlobalApplicationCommand(YOUR_CLIENT_ID, command.data)
}
return listeners;
return { interactionCreate: onInteraction }
}