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
|
||||
|
||||
```bash
|
||||
@@ -388,5 +411,5 @@ docker-compose up -d --build
|
||||
| `/timer` | add, remove, list, listall, help | Public/Admin |
|
||||
| `/welcome` | setchannel, add, remove, 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 |
|
||||
@@ -93,6 +93,10 @@ npm run deploy
|
||||
- `/admin unmute <user>` – Nutzer entmuten
|
||||
- `/admin ban <user>` – Nutzer bannen
|
||||
- `/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 help` – Admin-Hilfe
|
||||
|
||||
|
||||
@@ -137,6 +137,55 @@ const command: Command = {
|
||||
option.setName('duration_value')
|
||||
.setDescription('Dauer in Sekunden')
|
||||
.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 =>
|
||||
subcommand
|
||||
.setName('help')
|
||||
@@ -162,6 +211,10 @@ const command: Command = {
|
||||
{ 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 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: '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;
|
||||
}
|
||||
}
|
||||
|
||||
// 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