aslain.dev
0%
01 Hizmetler 02 Hakkımda 03 Projeler 04 Stack 05 Blog 06 İletişim
← Tüm makaleler Discord-Bots

Discord-Moderationsbot: Ban-, Kick- und Mute-Befehle

Ein Discord-Moderationsbot ist der praktischste Weg, einen wachsenden Server beherrschbar zu halten: Er reagiert in Sekunden auf Regelverstöße, protokolliert jede Aktion und übergibt Moderationsrechte nur den richtigen Personen. In dieser Anleitung bauen wir Ban-, Kick- und Mute- (Timeout-)Befehle von Grund auf mit discord.js v14. Es geht nicht nur darum, dass die Befehle funktionieren; entscheidend sind die Details, die auf echten Servern den Unterschied machen — Rechteprüfung, Rollenhierarchie und Audit-Log-Gründe.

Erforderliche Rechte und Intents

Moderationsbefehle erfordern, dass der Bot Mitglieder verwalten kann. Gib deinem Bot im Discord Developer Portal die Rechte Ban Members, Kick Members und Moderate Members. Moderate Members ist für Timeouts (Mutes) zwingend erforderlich. Außerdem musst du den GuildMembers-Intent im Code aktivieren und diesen Privileged Intent im Portal einschalten, um auf Mitgliederdaten zugreifen zu können.

const { Client, GatewayIntentBits } = require('discord.js');

const client = new Client({
  intents: [
    GatewayIntentBits.Guilds,
    GatewayIntentBits.GuildMembers,
  ],
});

In deinen Servereinstellungen muss die Rolle des Bots über den Rollen der Mitglieder stehen, die er moderieren soll. Discord lässt ihn niemanden bannen, der höher als er selbst eingestuft ist, und diese Regel erzwingen wir auch im Code.

Befehlsdefinition und Standardrecht

Beim Definieren von Slash Commands kannst du ihre Standardsichtbarkeit mit setDefaultMemberPermissions einschränken. Das verbirgt den Befehl vor Mitgliedern ohne das Recht, ist aber nur ein UI-Filter — die eigentliche Sicherheitsprüfung musst du trotzdem selbst zur Laufzeit durchführen.

const { SlashCommandBuilder, PermissionFlagsBits } = require('discord.js');

const banCommand = new SlashCommandBuilder()
  .setName('ban')
  .setDescription('Verbannt ein Mitglied vom Server')
  .addUserOption(o =>
    o.setName('mitglied').setDescription('Zu verbannendes Mitglied').setRequired(true))
  .addStringOption(o =>
    o.setName('grund').setDescription('Grund für den Bann'))
  .setDefaultMemberPermissions(PermissionFlagsBits.BanMembers);

Rechte- und Hierarchieprüfung

Bei jedem Moderationsbefehl musst du zwei Dinge prüfen: das Recht der ausführenden Person und die Rollenhierarchie. discord.js bietet fertige Getter, die das vereinfachen: member.bannable, member.kickable und member.moderatable. Diese berücksichtigen sowohl die Rechte des Bots als auch die Rollenreihenfolge. Dennoch ist es gute Praxis, zusätzlich zu prüfen, ob der ausführende Moderator über dem Zielmitglied steht.

function canModerate(interaction, target) {
  const actor = interaction.member;
  // Der Serverbesitzer darf alles
  if (actor.id === interaction.guild.ownerId) return true;
  // Steht der Moderator über dem Ziel?
  return actor.roles.highest.comparePositionTo(target.roles.highest) > 0;
}

Gibt comparePositionTo einen positiven Wert zurück, steht actor höher. Diese Prüfung zu überspringen könnte einem Moderator erlauben, jemanden mit mehr Befugnissen zu bannen.

Ban, Kick und Timeout umsetzen

Wir bündeln die Befehle in einem einzigen Handler. Wichtiger Punkt: Der Audit-Log-Grund erscheint in Discords Audit-Log, wenn du ihn der jeweiligen Methode über das Feld reason übergibst. So bleibt die Frage „wer hat was mit wem und warum getan" später nicht unbeantwortet.

client.on('interactionCreate', async (interaction) => {
  if (!interaction.isChatInputCommand()) return;

  const target = interaction.options.getMember('mitglied');
  const grund = interaction.options.getString('grund') ?? 'Nicht angegeben';

  if (!target) {
    return interaction.reply({ content: 'Mitglied nicht gefunden.', ephemeral: true });
  }
  if (!canModerate(interaction, target)) {
    return interaction.reply({ content: 'Du kannst dieses Mitglied nicht moderieren.', ephemeral: true });
  }

  if (interaction.commandName === 'ban') {
    if (!target.bannable) {
      return interaction.reply({ content: 'Ich kann dieses Mitglied nicht bannen.', ephemeral: true });
    }
    await target.ban({ reason: grund, deleteMessageSeconds: 60 * 60 * 24 });
    await interaction.reply(`🔨 ${target.user.tag} wurde gebannt. Grund: ${grund}`);
  }

  if (interaction.commandName === 'kick') {
    if (!target.kickable) {
      return interaction.reply({ content: 'Ich kann dieses Mitglied nicht kicken.', ephemeral: true });
    }
    await target.kick(grund);
    await interaction.reply(`👢 ${target.user.tag} wurde gekickt. Grund: ${grund}`);
  }

  if (interaction.commandName === 'mute') {
    if (!target.moderatable) {
      return interaction.reply({ content: 'Ich kann dieses Mitglied nicht stummschalten.', ephemeral: true });
    }
    const minuten = interaction.options.getInteger('minuten') ?? 10;
    await target.timeout(minuten * 60 * 1000, grund);
    await interaction.reply(`🔇 ${target.user.tag} wurde für ${minuten} Minuten stummgeschaltet.`);
  }
});

Für Mute erstellen wir keine separate Rolle; wir nutzen Discords integrierte Timeout-Funktion. member.timeout() nimmt eine Dauer in Millisekunden entgegen und ist auf 28 Tage begrenzt. Übergib null als Dauer, um den Timeout aufzuheben. Der integrierte Timeout ist zuverlässiger als eine separate „muted"-Rolle, weil die Stummschaltung auch dann gilt, wenn der Nutzer neue Kanäle betritt.

Fehler nicht verschlucken

Netzwerkfehler, fehlende Rechte oder ein bereits ausgetretenes Mitglied kommen in der Praxis häufig vor. Umschließe die Befehle mit einem try/catch und gib dem Nutzer eine aussagekräftige Meldung zurück; ein Fehler, der still in der Konsole landet, ist die häufigste Ursache für „der Bot funktioniert nicht"-Beschwerden.

try {
  await target.ban({ reason: grund });
  await interaction.reply(`🔨 ${target.user.tag} wurde gebannt.`);
} catch (err) {
  console.error(err);
  await interaction.reply({ content: 'Die Aktion ist fehlgeschlagen.', ephemeral: true });
}

Hinweise zu Best Practices

  • Ephemere Antworten: Zeige Fehler- und Rechtemeldungen mit ephemeral: true, damit nur die ausführende Person sie sieht; das hält den Kanal sauber.
  • Grund verpflichtend: Setze bei schwerwiegenden Aktionen setRequired(true), um den Moderator zu einer Erklärung zu zwingen.
  • Eigener Log-Kanal: Sende jede Moderationsaktion zusätzlich als Embed in einen privaten Log-Kanal; das ist ein dauerhafter Eintrag zusätzlich zum Audit-Log.
  • Dich und den Bot schützen: Lehne die Aktion ab, wenn das Ziel die ausführende Person oder der Bot selbst ist.

Häufige Fragen

Sollte ich eine separate Rolle für Mute einrichten?

Nein. Mit discord.js v14 ist die Nutzung von Discords integrierter Timeout-Funktion (member.timeout()) deutlich robuster. Eine separate „muted"-Rolle erfordert Rechte-Overrides in jedem Kanal und kann Lücken hinterlassen, wenn ein Nutzer neue Kanäle betritt; ein Timeout gilt automatisch serverweit.

Warum kann mein Bot höher eingestufte Mitglieder nicht bannen?

Discord lässt einen Bot oder ein Mitglied nur Mitglieder verwalten, die unter seiner eigenen höchsten Rolle stehen. Verschiebe die Rolle des Bots in den Servereinstellungen → Rollen über diese Mitglieder. Gibt der Getter member.bannable false zurück, ist die Ursache fast immer die Hierarchie.

Wie schreibe ich einen Grund in das Audit-Log?

Übergib einfach das Feld reason an die jeweilige Methode: target.ban({ reason: 'Spam' }) oder target.timeout(ms, 'Werbung'). Discord fügt diesen Text neben der Aktion im Audit-Log des Servers ein.

Möchtest du einen sicheren, rechtebewussten Moderationsbot für deinen Server? Lass uns gemeinsam ein Setup mit Ban/Kick/Timeout, einem automatischen Log-Kanal und Anti-Raid-Maßnahmen planen — nimm Kontakt mit mir auf.

Devamı için