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

Discord Global-Command vs. Guild-Command: Vergleich

Eine der ersten verwirrenden Entscheidungen beim Bau eines Discord-Bots ist diese: Soll man einen Slash-Command als Discord Global-Command oder als an einen bestimmten Server (Guild) gebundenen Command registrieren? Beide stammen aus demselben Code und werden gleich ausgelöst, aber ihre Registrierungsmethoden, Aktualisierungszeiten und Einsatzszenarien unterscheiden sich deutlich. In diesem Artikel zeige ich beide Ansätze mit echtem discord.js-Code und mache klar, welchen du wann wählst.

Was ist ein Global-Command und was ein Guild-Command?

Ein Global-Command ist auf jedem Server sichtbar, auf den dein Bot eingeladen wurde, und sogar in DMs (wenn du es erlaubst). Du registrierst ihn einmal, und der Bot bietet überall denselben Command an. Ein Guild-Command ist nur auf dem Server sichtbar, auf dem du ihn registriert hast; außerhalb verhält er sich, als gäbe es den Command nicht.

Auf der Seite der Discord-API ergibt sich der Unterschied aus zwei getrennten Endpunkten:

  • Global: PUT /applications/{application.id}/commands
  • Guild: PUT /applications/{application.id}/guilds/{guild.id}/commands

discord.js kapselt diese Endpunkte mit den Helfern Routes.applicationCommands() und Routes.applicationGuildCommands().

Der wichtigste Unterschied: die Aktualisierungszeit

In der Praxis ist das Wichtigste, was die beiden Methoden trennt, wann der Command nach der Registrierung im Discord-Client erscheint:

  • Guild-Commands werden nahezu sofort aktualisiert. Sie tauchen Sekunden nach der Registrierung im Slash-Menü auf. Das macht sie ideal für Entwicklung und Tests.
  • Global-Commands propagieren. Discord cacht sie; eine Änderung erreicht meist schnell alle Clients, aber im schlimmsten Fall kann es bis zu einer Stunde dauern. Einen neuen Command hinzuzufügen oder seine Beschreibung zu ändern erscheint möglicherweise nicht sofort.

Dieser eine Unterschied bestimmt die meisten Architekturentscheidungen: Während du aktiv entwickelst, willst du dich nicht auf Global verlassen und dann stundenlang warten mit der Frage „Warum erscheint es nicht?".

Commands mit discord.js registrieren (REST)

Commands werden in der Regel mit einem separaten deploy-commands.js-Skript registriert, das du nur ausführst, wenn sich Commands ändern, nicht bei jedem Start des Bots. Hier ist ein Beispiel, das auf eine Guild registriert (discord.js v14):

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

const commands = [
  new SlashCommandBuilder()
    .setName('ping')
    .setDescription('Zeigt die Latenz des Bots'),
].map(c => c.toJSON());

const rest = new REST({ version: '10' }).setToken(process.env.TOKEN);

(async () => {
  await rest.put(
    Routes.applicationGuildCommands(process.env.CLIENT_ID, process.env.GUILD_ID),
    { body: commands },
  );
  console.log('Guild-Commands registriert.');
})();

Um dasselbe Skript global zu machen, besteht die einzige Änderung darin, die Route zu tauschen und die GUILD_ID wegzulassen:

await rest.put(
  Routes.applicationCommands(process.env.CLIENT_ID),
  { body: commands },
);

Achtung: Die Methode put überschreibt. Das Array, das du sendest, wird zum vollständigen neuen Satz von Commands für diesen Geltungsbereich (global oder diese Guild). Wenn du einen Command aus dem Array weglässt, löscht der nächste put ihn. Dieses Verhalten ist beabsichtigt und liefert dir eine idempotente Registrierung.

Welchen verwendest du, und wann?

Als allgemeine Regel empfehle ich diesen Ansatz:

  • Nutze Guild-Commands während der Entwicklung. Registriere sie auf deinem eigenen Testserver; jede Änderung erscheint sofort und du wartest nie stundenlang auf die Propagierung.
  • Nutze Global-Commands für die Produktion. Wenn der Bot auf vielen Servern läuft, ergibt es keinen Sinn, Commands einzeln pro Guild zu registrieren; Global erreicht mit einem einzigen Aufruf alle.
  • Behalte Guild-Commands für serverspezifische Funktionen. Admin-Commands einer einzelnen Community, Commands für spezielle Events und Ähnliches sollten nicht global sein.

Viele ernsthafte Projekte nutzen beides: nutzerseitige Commands als Global und Commands, die nur auf dem Support-/Admin-Server laufen, im Guild-Geltungsbereich.

Häufige Fehler

  • Doppelte Commands. Wenn du denselben Command sowohl global als auch als Guild-Command auf deinem Testserver registrierst, siehst du dort zwei Kopien. Räume die Guild-Registrierung auf, sobald die Tests abgeschlossen sind (ein put mit einem leeren Array).
  • Die „Command erscheint nicht"-Panik. Eine globale Änderung wird nicht sofort widergespiegelt; erkläre sie nicht für „kaputt", ohne wirklich bis zu einer Stunde gewartet zu haben. Registriere zum schnellen Testen vorübergehend auf eine Guild.
  • Registrierung mit Listening verwechseln. Einen Command zu registrieren (REST put) und die eingehende Interaktion zu behandeln (das interactionCreate-Event) sind zwei getrennte Aufgaben. Lauschst du ohne zu registrieren, erscheint der Command nie; registrierst du ohne zu lauschen, bekommst du beim Klick „Diese Interaktion ist fehlgeschlagen".
  • Falsche CLIENT_ID. Das ist die Application-ID, nicht die des Bots (bei den meisten Bots stimmen sie überein, aber die Application-ID ist konzeptionell die richtige).

Häufige Fragen

Dauert ein Global-Command wirklich eine Stunde?

Meist geht es viel schneller und die Änderung erscheint innerhalb von Minuten. Discord garantiert jedoch eine Obergrenze von einer Stunde; besonders bei neu hinzugefügten Commands kann Caching eine Verzögerung verursachen. Deshalb ist es gesünder, für Tests Guild-Commands zu verwenden, statt sich auf Global zu verlassen.

Kann ich einen Command zuerst auf einer Guild testen und ihn dann global machen?

Ja, das ist der häufigste Workflow. Du registrierst während der Entwicklung auf eine Guild und führst das Global-Skript aus, wenn es fertig ist. Denke nur daran, die Test-Guild-Registrierung zu leeren, damit du keine Duplikate siehst.

Wie lösche ich einen Command?

Ein put mit einem leeren Array auf die betreffende Route löscht alle Commands in diesem Geltungsbereich. Um einen einzelnen Command zu löschen, kannst du rest.delete() mit seiner ID verwenden oder ihn aus dem Array entfernen und erneut put ausführen.

Willst du die Command-Architektur für deinen Discord-Bot richtig aufsetzen? Ich plane und baue den Global-/Guild-Geltungsbereich, die Berechtigungen und die Propagierungsstrategie passend zu deinem Projekt. Wenn du ein Bot-Projekt hast, nimm Kontakt mit mir auf.

Bu kategorideki tüm yazılar →

Devamı için