Compare commits
2 Commits
362437bcd5
...
3da019b8c7
| Author | SHA1 | Date | |
|---|---|---|---|
| 3da019b8c7 | |||
| b0f153f135 |
@@ -351,6 +351,29 @@ if (unit === 'perm') {
|
|||||||
}
|
}
|
||||||
```
|
```
|
||||||
|
|
||||||
|
### 11. Purge Command (Message Deletion)
|
||||||
|
|
||||||
|
**Subcommands:**
|
||||||
|
- `purge amount <1-100>` - Delete X messages
|
||||||
|
- `purge time <duration> <min|hour>` - Delete messages from last X time
|
||||||
|
- `purge user <user> <1-100>` - Delete X messages from specific user
|
||||||
|
- `purge all` - Delete all possible messages (max 100)
|
||||||
|
|
||||||
|
**Discord API Constraints:**
|
||||||
|
- Max 100 messages per bulk delete
|
||||||
|
- Messages older than 14 days cannot be bulk deleted
|
||||||
|
- Requires `ModerateMembers` permission
|
||||||
|
|
||||||
|
```typescript
|
||||||
|
// Filter messages older than 14 days (Discord API limit)
|
||||||
|
const twoWeeksAgo = Date.now() - 14 * 24 * 60 * 60 * 1000;
|
||||||
|
const filtered = messages.filter((m: any) => m.createdTimestamp > twoWeeksAgo);
|
||||||
|
|
||||||
|
await channel.bulkDelete(filtered, true);
|
||||||
|
```
|
||||||
|
|
||||||
|
**Logging:** Purge actions are logged to the moderation log channel with event type `messages`.
|
||||||
|
|
||||||
## 🚀 Build & Deploy
|
## 🚀 Build & Deploy
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
@@ -388,5 +411,5 @@ docker-compose up -d --build
|
|||||||
| `/timer` | add, remove, list, listall, help | Public/Admin |
|
| `/timer` | add, remove, list, listall, help | Public/Admin |
|
||||||
| `/welcome` | setchannel, add, remove, list, help | Admin |
|
| `/welcome` | setchannel, add, remove, list, help | Admin |
|
||||||
| `/log` | setchannel, enable, disable, list, help | Admin |
|
| `/log` | setchannel, enable, disable, list, help | Admin |
|
||||||
| `/admin` | kick, warn, unwarn, mute, unmute, ban, unban, config, help | Admin |
|
| `/admin` | kick, warn, unwarn, mute, unmute, ban, unban, purge, config, help | Admin |
|
||||||
| `/owner` | deploy, stats, servers, help | Owner |
|
| `/owner` | deploy, stats, servers, help | Owner |
|
||||||
@@ -93,6 +93,10 @@ npm run deploy
|
|||||||
- `/admin unmute <user>` – Nutzer entmuten
|
- `/admin unmute <user>` – Nutzer entmuten
|
||||||
- `/admin ban <user>` – Nutzer bannen
|
- `/admin ban <user>` – Nutzer bannen
|
||||||
- `/admin unban <id>` – Nutzer entbannen
|
- `/admin unban <id>` – Nutzer entbannen
|
||||||
|
- `/admin purge amount <1-100>` – X Nachrichten löschen
|
||||||
|
- `/admin purge time <dauer> <min|hour>` – Nachrichten der letzten X Zeit löschen
|
||||||
|
- `/admin purge user <user> <1-100>` – X Nachrichten eines Nutzers löschen
|
||||||
|
- `/admin purge all` – Alle Nachrichten löschen (max 100)
|
||||||
- `/admin config` – Warn-System konfigurieren
|
- `/admin config` – Warn-System konfigurieren
|
||||||
- `/admin help` – Admin-Hilfe
|
- `/admin help` – Admin-Hilfe
|
||||||
|
|
||||||
|
|||||||
@@ -137,6 +137,55 @@ const command: Command = {
|
|||||||
option.setName('duration_value')
|
option.setName('duration_value')
|
||||||
.setDescription('Dauer in Sekunden')
|
.setDescription('Dauer in Sekunden')
|
||||||
.setMinValue(0)))
|
.setMinValue(0)))
|
||||||
|
.addSubcommandGroup(group =>
|
||||||
|
group
|
||||||
|
.setName('purge')
|
||||||
|
.setDescription('Löscht Nachrichten im Channel')
|
||||||
|
.addSubcommand(subcommand =>
|
||||||
|
subcommand
|
||||||
|
.setName('amount')
|
||||||
|
.setDescription('Löscht X Nachrichten')
|
||||||
|
.addIntegerOption(option =>
|
||||||
|
option.setName('count')
|
||||||
|
.setDescription('Anzahl der Nachrichten (1-100)')
|
||||||
|
.setRequired(true)
|
||||||
|
.setMinValue(1)
|
||||||
|
.setMaxValue(100)))
|
||||||
|
.addSubcommand(subcommand =>
|
||||||
|
subcommand
|
||||||
|
.setName('time')
|
||||||
|
.setDescription('Löscht Nachrichten der letzten X Minuten/Stunden')
|
||||||
|
.addIntegerOption(option =>
|
||||||
|
option.setName('duration')
|
||||||
|
.setDescription('Dauer')
|
||||||
|
.setRequired(true)
|
||||||
|
.setMinValue(1))
|
||||||
|
.addStringOption(option =>
|
||||||
|
option.setName('unit')
|
||||||
|
.setDescription('Zeiteinheit')
|
||||||
|
.setRequired(true)
|
||||||
|
.addChoices(
|
||||||
|
{ name: 'Minuten', value: 'min' },
|
||||||
|
{ name: 'Stunden', value: 'hour' }
|
||||||
|
)))
|
||||||
|
.addSubcommand(subcommand =>
|
||||||
|
subcommand
|
||||||
|
.setName('user')
|
||||||
|
.setDescription('Löscht Nachrichten eines bestimmten Nutzers')
|
||||||
|
.addUserOption(option =>
|
||||||
|
option.setName('target')
|
||||||
|
.setDescription('Der Nutzer')
|
||||||
|
.setRequired(true))
|
||||||
|
.addIntegerOption(option =>
|
||||||
|
option.setName('count')
|
||||||
|
.setDescription('Anzahl der Nachrichten (1-100)')
|
||||||
|
.setRequired(true)
|
||||||
|
.setMinValue(1)
|
||||||
|
.setMaxValue(100)))
|
||||||
|
.addSubcommand(subcommand =>
|
||||||
|
subcommand
|
||||||
|
.setName('all')
|
||||||
|
.setDescription('Löscht alle möglichen Nachrichten (max 100)')))
|
||||||
.addSubcommand(subcommand =>
|
.addSubcommand(subcommand =>
|
||||||
subcommand
|
subcommand
|
||||||
.setName('help')
|
.setName('help')
|
||||||
@@ -162,6 +211,10 @@ const command: Command = {
|
|||||||
{ name: '`/admin unmute <nutzer>`', value: 'Entmutet einen Nutzer.', inline: false },
|
{ name: '`/admin unmute <nutzer>`', value: 'Entmutet einen Nutzer.', inline: false },
|
||||||
{ name: '`/admin ban <nutzer> [grund] [delete_days]`', value: 'Bannt einen Nutzer vom Server.\ndelete_days: Nachrichten der letzten X Tage löschen (0-7).', inline: false },
|
{ name: '`/admin ban <nutzer> [grund] [delete_days]`', value: 'Bannt einen Nutzer vom Server.\ndelete_days: Nachrichten der letzten X Tage löschen (0-7).', inline: false },
|
||||||
{ name: '`/admin unban <id>`', value: 'Entbannt einen Nutzer (via ID oder @username).', inline: false },
|
{ name: '`/admin unban <id>`', value: 'Entbannt einen Nutzer (via ID oder @username).', inline: false },
|
||||||
|
{ name: '`/admin purge amount <1-100>`', value: 'Löscht X Nachrichten im Channel.', inline: false },
|
||||||
|
{ name: '`/admin purge time <dauer> <min|hour>`', value: 'Löscht Nachrichten der letzten X Minuten/Stunden.', inline: false },
|
||||||
|
{ name: '`/admin purge user <nutzer> <1-100>`', value: 'Löscht X Nachrichten eines bestimmten Nutzers.', inline: false },
|
||||||
|
{ name: '`/admin purge all`', value: 'Löscht alle möglichen Nachrichten (max 100).', inline: false },
|
||||||
{ name: '`/admin config <setting> [wert]`', value: 'Konfiguriert das Warn-System.\nSettings: warn_threshold, warn_action, warn_mute_duration, show', inline: false },
|
{ name: '`/admin config <setting> [wert]`', value: 'Konfiguriert das Warn-System.\nSettings: warn_threshold, warn_action, warn_mute_duration, show', inline: false },
|
||||||
{ name: 'Warn-System', value: 'Automatische Aktionen bei X Warnungen:\n`/admin config warn_action kick|mute|ban`', inline: false }
|
{ name: 'Warn-System', value: 'Automatische Aktionen bei X Warnungen:\n`/admin config warn_action kick|mute|ban`', inline: false }
|
||||||
)
|
)
|
||||||
@@ -507,6 +560,115 @@ const command: Command = {
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Handle purge subcommands
|
||||||
|
const subcommandGroup = interaction.options.getSubcommandGroup();
|
||||||
|
if (subcommandGroup === 'purge') {
|
||||||
|
const purgeSubcommand = interaction.options.getSubcommand();
|
||||||
|
const channel = interaction.channel;
|
||||||
|
|
||||||
|
if (!channel || !channel.isTextBased()) {
|
||||||
|
await interaction.reply({ content: '❌ Dieser Befehl kann nur in Text-Channels verwendet werden.', flags: [MessageFlags.Ephemeral] });
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Defer reply since bulk delete can take time
|
||||||
|
await interaction.deferReply({ flags: [MessageFlags.Ephemeral] });
|
||||||
|
|
||||||
|
let deletedCount = 0;
|
||||||
|
|
||||||
|
try {
|
||||||
|
if (purgeSubcommand === 'amount') {
|
||||||
|
const count = interaction.options.getInteger('count')!;
|
||||||
|
const messages = await channel.messages.fetch({ limit: count + 1 }); // +1 for the command message
|
||||||
|
const twoWeeksAgo = Date.now() - 14 * 24 * 60 * 60 * 1000;
|
||||||
|
const filtered = messages.filter((m: any) => m.createdTimestamp > twoWeeksAgo);
|
||||||
|
|
||||||
|
await (channel as any).bulkDelete(filtered, true);
|
||||||
|
deletedCount = filtered.size - 1; // -1 for command message
|
||||||
|
|
||||||
|
await interaction.editReply(`✅ ${deletedCount} Nachrichten gelöscht.`);
|
||||||
|
}
|
||||||
|
|
||||||
|
else if (purgeSubcommand === 'time') {
|
||||||
|
const duration = interaction.options.getInteger('duration')!;
|
||||||
|
const unit = interaction.options.getString('unit')!;
|
||||||
|
|
||||||
|
const unitMs: Record<string, number> = {
|
||||||
|
min: 60 * 1000,
|
||||||
|
hour: 60 * 60 * 1000
|
||||||
|
};
|
||||||
|
|
||||||
|
const cutoff = Date.now() - (duration * unitMs[unit]);
|
||||||
|
const messages = await channel.messages.fetch({ limit: 100 });
|
||||||
|
const twoWeeksAgo = Date.now() - 14 * 24 * 60 * 60 * 1000;
|
||||||
|
const filtered = messages.filter((m: any) =>
|
||||||
|
m.createdTimestamp > cutoff &&
|
||||||
|
m.createdTimestamp > twoWeeksAgo
|
||||||
|
);
|
||||||
|
|
||||||
|
await (channel as any).bulkDelete(filtered, true);
|
||||||
|
deletedCount = filtered.size;
|
||||||
|
|
||||||
|
const unitName = unit === 'min' ? 'Minute(n)' : 'Stunde(n)';
|
||||||
|
await interaction.editReply(`✅ ${deletedCount} Nachrichten der letzten ${duration} ${unitName} gelöscht.`);
|
||||||
|
}
|
||||||
|
|
||||||
|
else if (purgeSubcommand === 'user') {
|
||||||
|
const target = interaction.options.getUser('target')!;
|
||||||
|
const count = interaction.options.getInteger('count')!;
|
||||||
|
|
||||||
|
const messages = await channel.messages.fetch({ limit: 100 });
|
||||||
|
const twoWeeksAgo = Date.now() - 14 * 24 * 60 * 60 * 1000;
|
||||||
|
const userMessages = messages.filter((m: any) =>
|
||||||
|
m.author.id === target.id &&
|
||||||
|
m.createdTimestamp > twoWeeksAgo
|
||||||
|
).first(count);
|
||||||
|
|
||||||
|
if (userMessages.length === 0) {
|
||||||
|
await interaction.editReply(`Keine Nachrichten von ${target.tag} gefunden.`);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
await (channel as any).bulkDelete(userMessages, true);
|
||||||
|
deletedCount = userMessages.length;
|
||||||
|
|
||||||
|
await interaction.editReply(`✅ ${deletedCount} Nachrichten von ${target.tag} gelöscht.`);
|
||||||
|
}
|
||||||
|
|
||||||
|
else if (purgeSubcommand === 'all') {
|
||||||
|
const messages = await channel.messages.fetch({ limit: 100 });
|
||||||
|
const twoWeeksAgo = Date.now() - 14 * 24 * 60 * 60 * 1000;
|
||||||
|
const filtered = messages.filter((m: any) => m.createdTimestamp > twoWeeksAgo);
|
||||||
|
|
||||||
|
await (channel as any).bulkDelete(filtered, true);
|
||||||
|
deletedCount = filtered.size;
|
||||||
|
|
||||||
|
await interaction.editReply(`✅ ${deletedCount} Nachrichten gelöscht.`);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Log the purge action
|
||||||
|
if (deletedCount > 0) {
|
||||||
|
const embed = new EmbedBuilder()
|
||||||
|
.setTitle('🗑️ Nachrichten gelöscht (Purge)')
|
||||||
|
.setColor(0x9b59b6)
|
||||||
|
.addFields(
|
||||||
|
{ name: 'Channel', value: `<#${channel.id}>`, inline: true },
|
||||||
|
{ name: 'Moderator', value: `${interaction.user.tag} (<@${interaction.user.id}>)`, inline: true },
|
||||||
|
{ name: 'Anzahl', value: `${deletedCount} Nachrichten`, inline: true },
|
||||||
|
{ name: 'Typ', value: purgeSubcommand === 'amount' ? 'Nach Anzahl' :
|
||||||
|
purgeSubcommand === 'time' ? 'Nach Zeit' :
|
||||||
|
purgeSubcommand === 'user' ? 'Nach Nutzer' : 'Alle', inline: true }
|
||||||
|
)
|
||||||
|
.setTimestamp();
|
||||||
|
await sendModerationLog(interaction.client, guildId, 'messages', embed);
|
||||||
|
}
|
||||||
|
} catch (error) {
|
||||||
|
console.error('[ADMIN] Purge error:', error);
|
||||||
|
await interaction.editReply('❌ Fehler beim Löschen der Nachrichten.');
|
||||||
|
}
|
||||||
|
return;
|
||||||
|
}
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user