# AI Agent Guide: Modular Discord Bot Architecture This document is intended for AI agents to understand, recreate, or extend the `pixelpoebel` Discord bot. It describes the design patterns, conventions, and key considerations for this specific modular architecture. ## 🏗 Architecture Overview The bot uses a **Modular Command & Event Loading** pattern with **ESM (ECMAScript Modules)** and **TypeScript**. ### Key Design Patterns: 1. **Extended Client Pattern:** We extend the `discord.js` `Client` class to hold global state like the `commands` Collection. This avoids global variables and improves type safety. 2. **Dynamic Discovery:** The `src/index.ts` entry point uses `readdirSync` and dynamic `import()` to automatically register any command or event found in the `src/commands` or `src/events` directories. 3. **Interface-Driven Commands:** All commands must implement the `Command` interface defined in `src/structures/Command.ts`. 4. **Persistent SQLite Database:** The bot uses `better-sqlite3` for data persistence. It's initialized in `src/structures/Database.ts` and stores data in the `data/` directory. 5. **Twitch Monitoring Service:** The `TwitchManager` in `src/structures/` handles periodic API polling and notification logic. 6. **Granular Permission Handling:** Commands like `twitch.ts` use manual permission checks (`interaction.memberPermissions.has(PermissionFlagsBits.Administrator)`) to allow a mix of public and restricted subcommands within a single command. ## 💾 Database Interaction To use the database in any command or event: ```typescript import { DB } from '../../structures/Database.js'; // Example: Get one row const user = DB.get('SELECT * FROM mod_logs WHERE user_id = ?', userId); // Example: Insert data DB.run('INSERT INTO mod_logs (guild_id, user_id, action) VALUES (?, ?, ?)', guildId, userId, 'WARN'); ``` **Persistence:** In Docker, the `data/` folder is mapped to a volume to ensure data survives container restarts. ## 📡 Twitch API Implementation The bot uses the **Twitch Helix API** with a client credentials flow. It requires: - `TWITCH_CLIENT_ID` - `TWITCH_CLIENT_SECRET` **Workflow:** - `TwitchManager.getAccessToken()`: Handles token acquisition and automatic renewal. - `TwitchManager.fetchStreamData(channelName)`: Helper for real-time status checks. - `TwitchManager.checkStreams()`: Periodically checks the status of monitored streamers from the database. - `TwitchManager.sendNotification()`: Constructs and sends an embed with live stream details to the designated Discord channel. ## 🚀 How to Extend ### Adding a Command: 1. Navigate to `src/commands/`. 2. Create a subfolder for the category (e.g., `utility`, `owner`, `moderation`). 3. Create a file (e.g., `ping.ts`). 4. Implement the `Command` interface and `export default`. 5. Run `npm run deploy` (or use `/deploy` in Discord) to register it with Discord. ### Adding an Event: 1. Navigate to `src/events/`. 2. Create a file (e.g., `messageCreate.ts`). 3. `export default` an object with `name`, `once` (optional), and `execute`. ## ⚠️ Critical AI Agent Constraints 1. **Environment Variables:** Always use `process.env.DISCORD_TOKEN`, `CLIENT_ID`, `TWITCH_CLIENT_ID`, and `TWITCH_CLIENT_SECRET`. **Never hardcode credentials.** 2. **Type-Safe Casting:** When using `interaction.options.getMember('target')`, always cast to `GuildMember` if you need guild-specific methods like `.kick()`. 3. **Interaction States:** Remember to check `interaction.replied` or `interaction.deferred` before replying in error handlers to avoid "Interaction already replied" errors. 4. **Deployment:** Slash commands are NOT automatically registered on bot start. You MUST run the `deploy-commands.ts` script whenever the command data changes. 5. **Owner-Checks:** Use `client.application.owner` to verify permissions for owner-only commands. ## 📦 Replication Checklist for Agents - [ ] Initialize NPM project with ESM. - [ ] Set up `tsconfig.json` for NodeNext. - [ ] Create `ExtendedClient.ts` to store commands. - [ ] Create `index.ts` with dynamic folder loading logic. - [ ] Create `deploy-commands.ts` for REST registration. - [ ] Implement global error handling in `interactionCreate.ts`. - [ ] Initialize SQLite database in `index.ts` via `DB.init()`. - [ ] Set up `TwitchManager` for stream monitoring. - [ ] Enable `Message Content Intent` in Discord Developer Portal if message tracking is needed.