5.9 KiB
5.9 KiB
AI Agent Guide: Pixelpöbel Discord Bot
This document is intended for AI agents to understand and recreate the pixelpöbel Discord bot.
🏗 Architecture Overview
The bot uses a Modular Command & Event Loading pattern with ESM (ECMAScript Modules) and TypeScript.
Key Design Patterns:
- Extended Client Pattern: Extend
discord.jsClientclass to hold global state. - Dynamic Discovery:
index.tsusesreaddirSyncand dynamicimport()to register commands/events. - Interface-Driven Commands: All commands implement
Commandinterface. - Optimized SQLite Database: Persistent storage with
better-sqlite3, utilizing WAL (Write-Ahead Logging) and In-Memory Caching for frequently accessed data. - Twitch Monitoring: Periodic API polling using Batch-Requests (100 channels per request) with Stream ID tracking.
- TwitchMonitor IRC: TMI.js-based IRC chat monitoring for mod events.
- Reminder System: Periodic reminder checking with target_time tracking.
- Auto-Response System: Trigger word detection for automatic replies (cached).
- Welcome/Goodbye System: Guild member add/remove events with customizable messages.
- Logging System: Configurable event logging (messages, roles, moderation, etc.).
- Role Selection System: Self-service role assignment via select menus.
- Grouped Commands: Admin/Owner/Trigger/Timer commands grouped under subcommands.
📁 Project Structure
pixelpoebel/
├── src/
│ ├── index.ts # Entry point, loads commands/events
│ ├── deploy-commands.ts # Deploy script for Discord
│ ├── commands/
│ │ └── utility/ # All commands grouped here
│ ├── events/
│ │ ├── ... # All Discord event handlers
│ └── structures/
│ ├── ExtendedClient.ts
│ ├── Command.ts
│ ├── Database.ts # Database with Caching logic
│ ├── TwitchManager.ts # Batch Polling logic
│ ├── TwitchMonitor.ts # IRC Monitoring logic
│ ├── TwitchCache.ts # IRC Message FIFO Cache
│ ├── ReminderManager.ts
│ └── Deployer.ts
├── data/ # SQLite database (volume mounted)
├── package.json
├── tsconfig.json
├── Dockerfile
├── docker-compose.yml
├── .env.example
└── .gitattributes
📝 Implementation Steps
1. Database with Caching
The database uses WAL mode for performance and an in-memory Map for caching settings and triggers.
// src/structures/Database.ts
export class DB {
private static settingsCache = new Map<string, any>();
private static triggersCache = new Map<string, any[]>();
static init() {
db.pragma('journal_mode = WAL');
// ... Table creation ...
}
static getSettings(guildId: string) {
if (this.settingsCache.has(guildId)) return this.settingsCache.get(guildId);
const settings = db.prepare('SELECT * FROM guild_settings WHERE guild_id = ?').get(guildId);
if (settings) this.settingsCache.set(guildId, settings);
return settings;
}
static run(query: string, ...params: any[]) {
const result = db.prepare(query).run(...params);
if (query.toLowerCase().includes('guild_settings') || query.toLowerCase().includes('auto_responses')) {
this.settingsCache.clear();
this.triggersCache.clear();
}
return result;
}
}
2. Twitch Batch Polling
To stay within API limits and provide faster updates, the bot polls Twitch in batches of 100.
// src/structures/TwitchManager.ts
static async checkStreams(client: any) {
const monitors = client.DB.all('SELECT * FROM twitch_monitors');
const uniqueChannels = [...new Set(monitors.map(m => m.channel_name.toLowerCase()))];
for (let i = 0; i < uniqueChannels.length; i += 100) {
const chunk = uniqueChannels.slice(i, i + 100);
const query = chunk.map(name => `user_login=${encodeURIComponent(name)}`).join('&');
// fetch https://api.twitch.tv/helix/streams?${query}
// ... process results ...
}
}
static startPolling(client: any) {
setInterval(() => this.checkStreams(client), 2 * 60 * 1000); // 2 minute interval
}
3. Event Logging Optimization
All logging events use a centralized sendLog pattern that utilizes the DB.getSettings() cache.
async function sendLog(client: any, guildId: string, event: string, embed: EmbedBuilder) {
const settings = client.DB.getSettings(guildId);
if (!settings?.log_events || !settings?.log_channel) return;
const activeEvents = settings.log_events.split(',').filter(Boolean);
if (!activeEvents.includes(event)) return;
const channel = client.guilds.cache.get(guildId)?.channels.cache.get(settings.log_channel);
if (channel?.isTextBased()) await channel.send({ embeds: [embed] });
}
4. TwitchMonitor IRC Chat Logging
Overview: Uses TMI.js to connect to Twitch IRC and logs moderation events (bans, timeouts, deletes) via webhooks.
Key Feature: FIFO Message Cache (TwitchCache.ts) allows restoring the text of deleted messages in the logs.
🚀 Performance Benchmarks (approx.)
| Metric | Old (Individual) | New (Batch/Cached) |
|---|---|---|
| API Calls (500 channels) | 500 | 5 |
| DB Access (Triggers) | Disk I/O per msg | RAM access |
| Notification Delay | ~5-7 min | ~2 min |
⚠️ Critical Constraints
- Batching: Never exceed 100 channels per Twitch API request.
- Caching: Always invalidate cache (
clearCache) when updating settings. - WAL Mode: Ensure the
data/directory has proper permissions for.shmand.walfiles. - Webhook Safety: Use
WebhookClientfor Twitch IRC logging to avoid Discord bot rate limits.