WebHooks sind einfache HTTP-Requests und ermöglichen eine Kommunikation zwischen zwei Anwendungen über das Internet. Mit einen WebHook können Daten an eine spezifische URL gesendet werden. Vereinfacht gesagt: Ein WebHook informiert Anwendung A automatisch über ein Ereignis in Anwendung B, indem sie Daten an eine vorher festgelegte Webhook-URL sendet. Als konkretes Beispiel kann makesmart bei einem neuen Blogbeitrag automatisch über einen Discord-Webhook eine Benachrichtigung in einem Kanal auslösen.
Durch die Einrichtung eines WebHooks kann sowohl der Serverbetreiber als auch jeder der im Besitz dieser URL ist automatisierte Nachrichten in einen spezifischen Kanal senden, ohne manuell eingreifen zu müssen. Webhooks sind ein beliebtes Werkzeug um Benachrichtigungen und Integrationsmeldungen von Drittanbieterdiensten innerhalb von Discord zu senden.
Zum Kapitel springen Webhooks in Discord
Ein Discord WebHook ist spezifisch für den Kanal in dem er eingerichtet wird. Eigentlich ist es im Prinzip nur eine URL, an die eine Anwendung oder ein Skript Daten im JSON-Format senden kann. Discord empfängt diese Daten, formt daraus eine Nachricht und zeigt diese im entsprechenden Kanal an. Der Schlüssel hierbei ist, dass der WebHook die Nachricht sendet, ohne dass ein realer Benutzer eingreifen muss. Dies bietet eine einfache Möglichkeit Benachrichtigungen oder Nachrichten zu automatisieren.
Ein Webhook unterstützt ein paar Standardisierte CRUD Operationen. CRUD steht für CREATE (Erstellen), READ (Lesen), UPDATE (Aktualisieren) und DELETE (Löschen). Diese Operationen sind in der Welt von HTTP Request besser bekannt als POST, GET, PATCH und DELETE. Mit einem Webhook können wir alle genannten Operationen bis auf GET verwenden. Das heißt wir können mit einem Webhook nicht nur Nachrichten senden sondern diese auch bearbeiten und wieder löschen.
Und darauf ist der Webhook auch beschränkt. Senden, bearbeiten, löschen. Für erweiterte Funktionen innerhalb von Discord muss auf einen eigenständigen Discord Bot zurückgegriffen werden.
Zum Kapitel springen Webhook erstellen
Webhooks in Discord werden immer für einen spezifischen Kanal erstellt. Mit dem Webhook können dann auch nur Nachrichten genau in diesen einen Kanal gesendet werden. Ein Webhook lässt sich ganz einfach über den Rechtsklickt auf einen Kanal erstellen. Klicke nach dem Rechtsklickt einfach auf das Feld Kanal bearbeiten
.
Anschließend kann über die Sidebar Integrationen
ein neuer Webhook erstellt werden.
Es wird ein neuer Webhook erstellt den wir dann auch direkt per Klick auswählen können. Im Menü des Webhooks können wir den Nutzernamen und den Avatar bearbeiten sowie die Webhook-URL kopieren.
Benutzername und der Avatar lassen sich mit jeder Nachricht definieren und überschreiben. Es bietet sich an in den Einstellungen einen eindeutigen Namen zu verwenden, damit man weiß in welchen Bereichen der Webhook zum Einsatz kommt.
Mit einem Klick auf den Button WebHook-URL kopieren
kann die URL des Webhooks kopiert werden.
https://discord.com/api/webhooks/1225881023472992367/4vBCEU2d2V2h9htgFfQIxCO8Bh2NP-_dgRne0NdPnc5BxstRcrSNUEfdNE9UQWcnJnA1
Achtung
Jeder mit diesem Link kann Nachrichten an den Discord Kanal senden. Es findet keine weitere Authentifizierung statt!
Zum Kapitel springen Einfaches Beispiel
Mit dem kopierten Link kann direkt eine HTTP Request ausgeführt werden. Ich habe hier mal eine kleine HTML-Datei vorbereitet. Diese könnt ihr euch herunterladen und in einem Editor eurer Wahl öffnen. Sucht die Webhook-URL und ersetzt diese mit der URL eures eigenen Webhooks.
const webhookURL = 'https://discord.com/api/webhooks/1225881023472992367/4vBCEU2d2V2h9htgFfQIxCO8Bh2NP-_dgRne0NdPnc5BxstRcrSNUEfdNE9UQWcnJnA1';
Öffnet die HTML Datei nach dem Speichern nun in dem Webbrowser eurer Wahl und sendet die erste externe Nachricht in euren Discord Kanal. Füllt das Textfeld dazu einfach mit dem gewünschten Inhalt der Nachricht und klickt auf den den Button Nachricht senden
.
Unmittelbar nach dem Klick wird die Nachricht in den Kanal des Webhooks gesendet.
Das war natürlich nur ein Beispiel und stimmt auch nicht ganz mit dem in der Einleitung erwähnten ohne dass ein realer Benutzer eingreifen muss überein. Es soll lediglich zeigen, wie einfach es ist, Webhooks in externe Dienste zu integrieren. Am Ende des Tages macht es Sinn, diesen Ablauf zu automatisieren und in die eigene Anwendung zu integrieren. Um eine Basis dafür werden wir uns jetzt kümmern.
Zum Kapitel springen Nachricht senden
In dem Beispiel wird bereits gezeigt, wie man einfache Textnachrichten versenden kann. Heruntergebrochen auf ein Javascript-Snippet unter Node.JS würde der Code für ein einfaches Senden einer Textnachricht wie folgt aussehen:
const webhookURL = 'https://discord.com/api/webhooks/1225881023472992367/4vBCEU2d2V2h9htgFfQIxCO8Bh2NP-_dgRne0NdPnc5BxstRcrSNUEfdNE9UQWcnJnA1';
async function sendMessage( ) {
const response = await fetch(`${webhookURL}`, {
method: "POST",
headers: {
"Content-Type": "application/json"
},
body: JSON.stringify({
content: "Das ist meine supertolle coole Benachrichtigung. Danke Ciao!"
})
});
return response;
}
async function main() {
const result = await sendMessage( );
// result.status enthält den HTTP-Statuscode der Antwort
// result.body enthält die Daten der Antwort
console.log( result.status, result.body );
}
main();
204 null
Es wurde der Status-Code 204
und null
Daten im Body zurückgegeben. Das ist passend, denn der Status 204 bedeutet so viel wie:
No Content; Die Anfrage wurde erfolgreich durchgeführt, die Antwort enthält jedoch bewusst keine Daten.
Mehr Informationen zu HTTP-Statuscodes auf Wikipedia.
Das mag in vielen Fällen durchaus in Ordnung sein, wenn man eine versendete Nachricht jedoch bearbeiten oder gar löschen möchte, sind diese Informationen nicht ausreichend. Wir brauchen einen Anhaltspunkt.
Welche Nachricht möchte ich bearbeiten? oder Welche Nachricht soll denn überhaupt gelöscht werden?
Zum Glück gibt es dafür einen weiteren Parameter für die Anfrage. Nämlich den GET-Parameter wait=true
.
Zum Kapitel springen Nachricht senden mit Webhook-Antwort
Mit dem übergeben des GET-Parameters wait=true
warten wir, bis die Nachricht versendet wurde und erhalten damit weitere Informationen zur Nachricht als Rückgabewert nach dem Senden der Nachricht in den Kanal.
{
id: '1225897357221298227',
type: 0,
content: 'Das ist meine supertolle coole Benachrichtigung. Danke Ciao!',
channel_id: '1217220452561453187',
author: {
id: '1225881023472992367',
username: 'makesmart Webhooks',
avatar: 'eebb4b21249c045baf5ac2b0611818bb',
discriminator: '0000',
public_flags: 0,
flags: 0,
bot: true,
global_name: null
},
attachments: [],
embeds: [],
mentions: [],
mention_roles: [],
pinned: false,
mention_everyone: false,
tts: false,
timestamp: '2024-04-05T19:50:29.686000+00:00',
edited_timestamp: null,
flags: 0,
components: [],
webhook_id: '1225881023472992367'
}
Was für das spätere Bearbeiten und Löschen relevant ist, ist die id: '1225897357221298227'
. Nicht nur jeder Nutzer, jeder Kanal oder jeder Discord-Server erhält eine eindeutige ID - nein - auch jede Nachricht kann durch eine eindeutige ID identifziert werden.
Mit dieser ID können betroffene Nachrichten bearbeitet oder gelöscht werden. Neben der ID der Nachricht können wir mit dem Parameter wait=true
noch einige andere wertvolle Daten auslesen. Um HTTP Requests mit diesem Parameter zu senden, reicht es den Parameter der Webhook-URL anzuhängen. Außerdem ist die Auswertung der Antwort ein bisschen anders.
Die Antwort mit den Daten zur Nachrichten wird nämlich nicht als ganzes am Stück geschickt geschickt sondern als incoming message
also als Stream. Dieser Stream muss erst "gesammelt" und kann dann als Paket zusammengeschnürt werden.
Dieser Parameter ändert nichts am Senden der Nachricht. Er ermöglicht es lediglich eine Antwort mit wertvollen Informationen zu erhalten.
Mit dem folgenden Code erhalten wir das oben aufgeführte Datenpaket der Antwort nach dem Senden über den Webhook:
const webhookURL = 'https://discord.com/api/webhooks/1225881023472992367/4vBCEU2d2V2h9htgFfQIxCO8Bh2NP-_dgRne0NdPnc5BxstRcrSNUEfdNE9UQWcnJnA1';
async function sendMessage( ) {
const response = await fetch(`${webhookURL}?wait=true`, {
method: "POST",
headers: {
"Content-Type": "application/json"
},
body: JSON.stringify({
content: "Das ist meine supertolle coole Benachrichtigung. Danke Ciao!"
})
});
const chunks = [];
for await ( const chunk of response.body ) { chunks.push( Buffer.from( chunk ) ); }
const data = JSON.parse( Buffer.concat(chunks).toString("utf-8") );
return data;
}
async function main() {
const result = await sendMessage( );
console.log( result );
}
main();
Zum Kapitel springen Nachricht bearbeiten
Mit den Daten der Antwort können wir nun die andereren CRUD-Operationen ausführen. Also PATCH
und DELETE
. In diesem Beispiel ist es PATCH
- das Bearbeiten einer vorhanden Nachricht.
Dazu ist es wichtig die ID der Nachricht gespeichert zu haben. In meinem Fall lautet die ID 1225897357221298227
. Mithilfe dieser ID kann die Nachricht nun bearbeitet werden.
Der Endpunkt des Webhooks ändert sich dabei. Anstatt direkt auf die vorhin kopierte URL zuzugreifen muss mit dem Bearbeiten auch die zu bearbeitende Nachricht übergeben werden. Dies passiert direkt in der URL:
${webhookURL}/messages/${messageID}
In einem Javascript Code-Snippet würde das so aussehen;
const webhookURL = 'https://discord.com/api/webhooks/1225881023472992367/4vBCEU2d2V2h9htgFfQIxCO8Bh2NP-_dgRne0NdPnc5BxstRcrSNUEfdNE9UQWcnJnA1';
async function editMessage( messageID ) {
const response = await fetch(`${webhookURL}/messages/${messageID}`, {
method: "PATCH",
headers: {
"Content-Type": "application/json"
},
body: JSON.stringify({
content: "Den Bodensack in kaltes Wasser hängen!"
})
});
const chunks = [];
for await ( const chunk of response.body ) { chunks.push( Buffer.from( chunk ) ); }
const data = JSON.parse( Buffer.concat(chunks).toString("utf-8") );
if( data.code ){
return false
}
return data;
}
async function main() {
const messageEdited = await editMessage('1225897357221298227');
if( !messageEdited ) {
console.log("Beim Bearbeiten der Nachricht ist ein Fehler aufgetreten!");
}
}
main();
Anhand dem Zusatz (Bearbeitet) neben der Nachricht und dem geänderten Inhalt kann man sehen, dass die Nachricht erfolgreich bearbeitet wurde. Auch in diesem Fall erhalten wir in der Antwort des Webhooks wieder Informationen zur Nachricht. Die ID bleibt dabei unverändert.
Es werden nur die Parameter überschrieben die auch gesendet werden. Vorhandene - nicht aktualisierte Parameter - werden nicht ersetzt. Erst wenn du diese mit dem HTTP-Request explizit überschreibst werden diese auch ersetzt.
Zum Kapitel springen Nachricht löschen
Ähnlich wie das Bearbeiten einer Nachricht kann auch das Löschen einer Nachricht implementiert werden. Statt PATCH
wird dabei DELETE
verwendet. Die einzigen beiden Unteschied zu PATCH
sind, dass 1. keine Daten gesendet werden und 2. DELETE
als Method verwendet wird.
const webhookURL = 'https://discord.com/api/webhooks/1225881023472992367/4vBCEU2d2V2h9htgFfQIxCO8Bh2NP-_dgRne0NdPnc5BxstRcrSNUEfdNE9UQWcnJnA1';
async function deleteMessage( messageID ) {
const response = await fetch(`${webhookURL}/messages/${messageID}`, {
method: "DELETE",
headers: { "Content-Type": "application/json" },
body: JSON.stringify({})
});
const status = response.status;
if( status === 204 || status === 404 ){
return true;
}
return false;
}
async function main() {
const messageDeleted = await deleteMessage('1225897357221298227');
if( !messageDeleted ) {
console.log("Es gab einen Fehler beim Löschen der Nachricht!");
}
console.log("Die Nachricht ist nicht mehr vorhanden oder wurde erfolgreich gelöscht!");
}
main();
Die Nachricht ist nicht mehr vorhanden oder wurde erfolgreich gelöscht!
Beim erneuten Ausführen des Codes mit den selben Parametern erscheint folgende Meldung in der Konsole:
Die Nachricht ist nicht mehr vorhanden oder wurde erfolgreich gelöscht!
Das liegt daran wie der Status ausgewertet wird. Jeder kennt den Statuscode 404 - Not found. So ist es auch bei den Discord Webhooks. Wenn eine angeforderte Nachricht nicht existiert, wird ein 404 Status zurückgegeben.
if( status === 204 || status === 404 ){
return true;
}
Zum Kapitel springen Nützliche Links
Weitere Informationen zum Thema Discord Webhooks findest du in einer Zusammenfassung von birdie0. Er hat eine sehr nützliche Dokumentation über Discord Webhooks verfasst. Dort findest du viele Informationen die dir helfen deinen Webhook so zu implementieren wie du es dir wünscht.
Desweiteren kann ich dir ein Tool von Merlin Fuchs ans Herz legen. Merlin ist seit Juli 2020 auf dem makesmart Discord Server und betreibt neben seinem Xenon Bot auch die Web-App message.style.
message.style ist ein Tool extra für Webhooks. Neben zahlreichen automatisierten Features die das Senden und Verwalten von Webhooks betreffen kannst du message.style auch für das Styling deiner Nachrichten verwenden. Neben einer eleganten und realen Vorschau der Nachricht hast du die Möglichkeit das JSON-Objekt der Nachricht zu kopieren. Dieses JSON kannst du für deine Anfrage verwenden um die Vorschau in eine echte Nachricht zu verwandeln.