3.0 KiB
title, weight
| title | weight |
|---|---|
| Module Development Workflow | 1 |
Goal: Create a new feature for the Quetza bot by implementing a self-contained module.
1. Conceptualization Phase
Before writing code, determine the module's architecture:
- Simple Command: Needs only a
commands/folder (e.g., utility commands). - Reactive Logic: Needs
events/to listen to Discord lifecycles (e.g., welcome messages). - Stateful Feature: Needs a Controller to manage state across guilds (e.g., music player).
2. Structure Establishment
Create the module directory structure. The presence of these files triggers automatic discovery.
{{< filetree/container >}} {{< filetree/folder name="src" state="open" >}} {{< filetree/folder name="modules" state="open" >}} {{< filetree/folder name="my-feature" state="open" >}} {{< filetree/file name="module.ts" >}} {{< filetree/folder name="commands" >}} {{< /filetree/folder >}} {{< filetree/folder name="events" >}} {{< /filetree/folder >}} {{< filetree/folder name="lib" >}} {{< /filetree/folder >}} {{< /filetree/folder >}} {{< /filetree/folder >}} {{< /filetree/folder >}} {{< /filetree/container >}}
3. Implementation Steps
{{% steps %}}
Step 1: Create the Manifest
Create module.ts to declare the module.
// src/modules/my-feature/module.ts
export const name = 'my-feature';
export const description = 'Adds cool feature capabilities';
// Optional: export const controller = new MyFeatureController();
Step 2: Implement Commands
Create command files in commands/. Each file exports data and an executor.
// src/modules/my-feature/commands/ping.ts
import { SlashCommandBuilder } from 'discord.js';
export const data = new SlashCommandBuilder()
.setName('ping')
.setDescription('Replies with Pong!');
export async function execute(interaction) {
await interaction.reply('Pong!');
}
Step 3: Implement Events (Optional)
Create event handlers in events/ to observe Discord state.
// src/modules/my-feature/events/ready.ts
import { Events } from 'discord.js';
export const name = Events.ClientReady;
export const once = true;
export function execute(client) {
console.log(`Ready! Logged in as ${client.user.tag}`);
}
Step 4: Define Controller (Optional)
For stateful logic, implement a controller in lib/ and export it in module.ts.
Step 5: Validate
Restart the bot.
- Check logs for "Loaded module: my-feature".
- Verify the command
/pingappears in Discord.
{{% /steps %}}
Integration Patterns
| Pattern | Use Case | Components |
|---|---|---|
| Simple Command | Stateless utilities (Ping, Dice Roll) | commands/ only |
| Stateful Service | Music, RPGs, Economy | commands/ + lib/Controller |
| Event-Driven | Auto-moderation, Logging | events/ only |
| Hybrid | Complex features (AI Chat) | All components |
See also: