Add: Timer and Trigger modules with help subcommands
All checks were successful
Auto Build and Push Docker Image / build (push) Successful in 6s
All checks were successful
Auto Build and Push Docker Image / build (push) Successful in 6s
- Add /timer command: add, remove, list, listall, help - Add /trigger command: add, remove, list, help - Add /admin help and /owner help subcommands - Add /twitch help subcommand - Add ReminderManager for timer notifications - Add reminders table to database - Update README.md and AGENTS-BOT.md documentation Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
104
AGENTS-BOT.md
104
AGENTS-BOT.md
@@ -12,7 +12,9 @@ The bot uses a **Modular Command & Event Loading** pattern with **ESM (ECMAScrip
|
||||
3. **Interface-Driven Commands:** All commands implement `Command` interface.
|
||||
4. **SQLite Database:** Persistent data storage with `better-sqlite3`.
|
||||
5. **Twitch Monitoring:** Periodic API polling with Stream ID tracking.
|
||||
6. **Grouped Commands:** Admin/Owner commands grouped under subcommands.
|
||||
6. **Reminder System:** Periodic reminder checking with target_time tracking.
|
||||
7. **Auto-Response System:** Trigger word detection for automatic replies.
|
||||
8. **Grouped Commands:** Admin/Owner/Trigger/Timer commands grouped under subcommands.
|
||||
|
||||
## 📁 Project Structure
|
||||
|
||||
@@ -26,6 +28,8 @@ pixelpoebel/
|
||||
│ │ ├── ping.ts
|
||||
│ │ ├── help.ts
|
||||
│ │ ├── twitch.ts
|
||||
│ │ ├── trigger.ts # Auto-responses
|
||||
│ │ ├── timer.ts # Reminders
|
||||
│ │ ├── admin.ts # All admin subcommands
|
||||
│ │ └── owner.ts # All owner subcommands
|
||||
│ ├── events/
|
||||
@@ -36,6 +40,7 @@ pixelpoebel/
|
||||
│ ├── Command.ts
|
||||
│ ├── Database.ts
|
||||
│ ├── TwitchManager.ts
|
||||
│ ├── ReminderManager.ts
|
||||
│ └── Deployer.ts
|
||||
├── data/ # SQLite database (volume mounted)
|
||||
├── package.json
|
||||
@@ -132,6 +137,17 @@ CREATE TABLE auto_responses (
|
||||
response_text TEXT,
|
||||
UNIQUE(guild_id, trigger_word)
|
||||
);
|
||||
|
||||
-- reminders
|
||||
CREATE TABLE reminders (
|
||||
id INTEGER PRIMARY KEY AUTOINCREMENT,
|
||||
guild_id TEXT,
|
||||
channel_id TEXT,
|
||||
user_id TEXT,
|
||||
reminder_text TEXT,
|
||||
target_time DATETIME,
|
||||
created_at DATETIME DEFAULT CURRENT_TIMESTAMP
|
||||
);
|
||||
```
|
||||
|
||||
### 3. Key Components
|
||||
@@ -167,44 +183,65 @@ export interface Command {
|
||||
}
|
||||
```
|
||||
|
||||
**Deployer - Auto-Deploy (Option 3):**
|
||||
### 4. Timer System
|
||||
|
||||
**Time Parsing:**
|
||||
```typescript
|
||||
export class Deployer {
|
||||
static async deployIfMissing(clientId: string, token: string) {
|
||||
const rest = new REST().setToken(token);
|
||||
// Duration parsing: "30s", "2h", "1d30m", "3wochen"
|
||||
function parseDuration(input: string): number | null {
|
||||
const unitMs: Record<string, number> = {
|
||||
's': 1000, 'sec': 1000, 'sek': 1000, 'sekunden': 1000,
|
||||
'm': 60000, 'min': 60000, 'minuten': 60000,
|
||||
'h': 3600000, 'hour': 3600000, 'std': 3600000, 'stunden': 3600000,
|
||||
'd': 86400000, 'day': 86400000, 't': 86400000, 'tage': 86400000,
|
||||
'w': 604800000, 'week': 604800000, 'wochen': 604800000,
|
||||
'mo': 2592000000, 'month': 2592000000, 'monat': 2592000000, 'monate': 2592000000,
|
||||
'y': 31536000000, 'year': 31536000000, 'j': 31536000000, 'jahr': 31536000000, 'jahre': 31536000000
|
||||
};
|
||||
// Parse and calculate total milliseconds
|
||||
}
|
||||
|
||||
try {
|
||||
const data = await rest.get(Routes.applicationCommands(clientId));
|
||||
if (data.length > 0) {
|
||||
console.log('[DEPLOYER] Commands already registered. Skipping deployment.');
|
||||
return data.length;
|
||||
}
|
||||
} catch (error) {
|
||||
// Commands don't exist yet
|
||||
// Date parsing: "25.12.2024 14:30", "morgen 15:00"
|
||||
function parseDateTime(input: string): Date | null {
|
||||
// German date format, ISO format, or relative "tomorrow"
|
||||
}
|
||||
```
|
||||
|
||||
**Reminder Polling:**
|
||||
```typescript
|
||||
export class ReminderManager {
|
||||
static async checkReminders(client: any) {
|
||||
const now = new Date().toISOString();
|
||||
const dueReminders = DB.all('SELECT * FROM reminders WHERE target_time <= ?', now);
|
||||
|
||||
for (const reminder of dueReminders) {
|
||||
const guild = client.guilds.cache.get(reminder.guild_id);
|
||||
const channel = guild.channels.cache.get(reminder.channel_id);
|
||||
// Send notification and delete reminder
|
||||
}
|
||||
}
|
||||
|
||||
return this.deploy(clientId, token);
|
||||
static startPolling(client: any) {
|
||||
setInterval(() => this.checkReminders(client), 30 * 1000);
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
### 4. Command Examples
|
||||
### 5. Auto-Response (Trigger) System
|
||||
|
||||
**Grouped Command (admin):**
|
||||
```typescript
|
||||
data: new SlashCommandBuilder()
|
||||
.setName('admin')
|
||||
.setDescription('Admin-Commands')
|
||||
.addSubcommand(sub => sub.setName('kick').setDescription('Kickt einen Nutzer')
|
||||
.addUserOption(opt => opt.setName('target').setDescription('Nutzer').setRequired(true))
|
||||
.addStringOption(opt => opt.setName('reason').setDescription('Grund')))
|
||||
.addSubcommand(sub => sub.setName('warn').setDescription('Verwarnt einen Nutzer')
|
||||
.addUserOption(opt => opt.setName('target').setDescription('Nutzer').setRequired(true))
|
||||
.addStringOption(opt => opt.setName('reason').setDescription('Grund').setRequired(true)))
|
||||
// ... more subcommands
|
||||
// Add trigger (admin only)
|
||||
DB.run('INSERT INTO auto_responses (guild_id, trigger_word, response_text) VALUES (?, ?, ?)',
|
||||
guildId, triggerWord.toLowerCase(), responseText);
|
||||
|
||||
// List triggers (public)
|
||||
DB.all('SELECT * FROM auto_responses WHERE guild_id = ? ORDER BY trigger_word ASC', guildId);
|
||||
|
||||
// Remove trigger (admin only)
|
||||
DB.run('DELETE FROM auto_responses WHERE guild_id = ? AND trigger_word = ?', guildId, triggerWord);
|
||||
```
|
||||
|
||||
### 5. Twitch Monitoring with Stream ID
|
||||
### 6. Twitch Monitoring with Stream ID
|
||||
|
||||
```typescript
|
||||
// Stream ID tracking prevents duplicate notifications
|
||||
@@ -218,7 +255,7 @@ if (wasOffline || (monitor.last_status === 'online' && isNewStream)) {
|
||||
}
|
||||
```
|
||||
|
||||
### 6. Configurable Warn System
|
||||
### 7. Configurable Warn System
|
||||
|
||||
**Database Schema:**
|
||||
- `warn_threshold`: Number of warns before action
|
||||
@@ -238,7 +275,7 @@ if (warnCount >= warnThreshold) {
|
||||
}
|
||||
```
|
||||
|
||||
### 7. Mute with Multiple Time Units
|
||||
### 8. Mute with Multiple Time Units
|
||||
|
||||
```typescript
|
||||
const unitSeconds: Record<string, number> = {
|
||||
@@ -281,6 +318,7 @@ docker-compose up -d --build
|
||||
3. **Interaction States:** Check `interaction.replied` before replying.
|
||||
4. **Twitch API:** Max 100 channels per request, batch properly.
|
||||
5. **Deploy:** Commands NOT auto-registered on start – use `/owner deploy`.
|
||||
6. **Ephemeral Replies:** Use `flags: [MessageFlags.Ephemeral]` instead of deprecated `ephemeral: true`.
|
||||
|
||||
## 📋 Command Summary
|
||||
|
||||
@@ -288,6 +326,8 @@ docker-compose up -d --build
|
||||
|---------|-------------|------------|
|
||||
| `/ping` | – | Public |
|
||||
| `/help` | – | Public |
|
||||
| `/twitch` | online, add, remove, list | Public/Admin |
|
||||
| `/admin` | kick, warn, unwarn, mute, unmute, ban, unban, config | Admin |
|
||||
| `/owner` | deploy, stats, servers | Owner |
|
||||
| `/twitch` | online, add, remove, list, help | Public/Admin |
|
||||
| `/trigger` | add, remove, list, help | Public/Admin |
|
||||
| `/timer` | add, remove, list, listall, help | Public/Admin |
|
||||
| `/admin` | kick, warn, unwarn, mute, unmute, ban, unban, config, help | Admin |
|
||||
| `/owner` | deploy, stats, servers, help | Owner |
|
||||
Reference in New Issue
Block a user