Zealy-Dokumentation

Automatische Übersetzung · Auf Englisch lesen

Webhooks

Erweitere die Möglichkeiten von Zealy mit Webhook-Verbindungen.

Von louis, Fredrika, benjamin

Webhooks
Auf dieser Seite

Ein Zealy-Webhook sendet ein HTTP POST an eine URL deiner Wahl, wenn eines von neun Community-Ereignissen eintritt, darunter der Beitritt eines Mitglieds, ein erfolgreicher oder fehlgeschlagener Quest-Claim, der Start eines Sprints und die Sperrung eines Nutzers. Jede Payload enthält eine Event-ID, einen Typ, Daten, einen Zeitstempel in Millisekunden und das Secret, das die Echtheit der Anfrage belegt.

Grundlagen

Zealy bietet Webhooks , mit denen du HTTP-Push-Benachrichtigungen erhalten kannst, wann immer Daten erstellt oder aktualisiert werden. So kannst du Integrationen auf Zealy aufbauen. Du könntest CI-Builds auslösen, Berechnungen mit Quest-Daten durchführen oder Nachrichten unter bestimmten Bedingungen senden – deiner Fantasie sind keine Grenzen gesetzt.

Bitte gehe zu Einstellungen > Integrationen > Zapier & Webhooks, um deine Webhooks einzurichten.

Wie funktioniert ein Webhook?

Ein Webhook-Push ist einfach eine HTTP POST -Anfrage, die an die URL deiner Wahl gesendet wird. Der Push wird automatisch von Linear ausgelöst, wenn Daten aktualisiert werden. Ein Beispiel dafür, welche Daten eine Payload enthält, findest du unter Die Webhook-Payload.

Dein Webhook-Consumer ist ein einfacher HTTP-Endpunkt. Er muss die folgenden Bedingungen erfüllen:

  • Er ist unter einer öffentlich zugänglichen HTTPS-URL verfügbar, die nicht localhost ist
  • Er antwortet auf den Zealy-Webhook-Push (HTTP POST-Anfrage) mit einer HTTP 200 -Antwort ("OK")

Wenn eine Zustellung fehlschlägt (z. B. Server nicht verfügbar, Antwort dauerte länger als 5 Sekunden, Antwort-Body war größer als 5000 Bytes oder es wurde mit einem anderen HTTP-Statuscode als 200 geantwortet), wird der Push 15 Mal wiederholt. Dabei wird eine exponentielle Backoff-Verzögerung verwendet: Der Versuch wird nach etwa 10 Minuten, dann nach 30 Minuten usw. wiederholt. Wenn die Webhook-URL weiterhin nicht reagiert, kann der Webhook von Zealy deaktiviert werden und muss manuell wieder aktiviert werden.

Um sicherzustellen, dass ein Webhook POST wirklich von Zealy erstellt wurde, generieren wir ein zufälliges Secret, das dem Body der Anfrage im Feld secret angehängt wird.

Für weitere Informationen zu Webhooks gibt es mehrere gute Ressourcen:

Wofür kann ich es verwenden?

  • Mit Zapier integrieren
  • Individuelle Belohnungen automatisieren
  • Über Quests benachrichtigen, die auf eine Überprüfung warten, auf Telegram

Und vieles, vieles mehr!

Erste Schritte mit Zealy Webhooks

  1. Bestimme, welche Ereignisse du überwachen möchtest.
  2. Entwickle eine Webhook-Endpunktfunktion, um POST-Anfragen mit Ereignisdaten zu empfangen.
  3. Registriere deinen Endpunkt in Zealy über das Webhooks-Dashboard unter Einstellungen > Integrationen > Zapier & Webhooks.
  4. Sichere deinen Webhook-Endpunkt ab.

Einen einfachen Webhook-Consumer erstellen

Du könntest etwas wie Netlify Functions in Betracht ziehen, das eine unkomplizierte Möglichkeit bietet, einfache HTTP(S)-Endpunkte bereitzustellen: https://www.netlify.com/blog/2018/09/13/how-to-run-express.js-apps-with-netlify-functions/.

// server.js
//
// Use this sample code to handle webhook events in your integration.
//
// 1) Paste this code into a new file (server.js)
//
// 2) Install dependencies
//   npm install express
//
// 3) Run the server on http://localhost:4242
//   node server.js
 
// The library needs to be configured with your account's secret key.
// Ensure the key is kept out of any version control system you might be using.
const express = require('express');
const app = express();
 
// This is your Zealy webhook secret for testing your endpoint locally.
const endpointSecret = '5888a6800dbac634e52d8504f097e064';
 
app.post('/webhook', express.raw({ type: 'application/json' }), (request, response) => {
  const payload = req.body;
  // Does createdAt make more sense than time?
  const { id, type, data, time, secret } = payload;
 
  if (secret === endpointSecret) {
    // Do something neat with the data received!
  }
 
  // Return a 200 response to acknowledge receipt of the event
  response.send();
});
 
app.listen(4242, () => console.log('Running on port 4242'));

In den Einstellungen konfigurieren

Richte den Webhook und die Ereignisse, die er überwachen soll, unter Einstellungen > Integrationen > Webhooks ein.

Die Webhook-Payload

Die HTTP-Payload des Webhooks enthält Informationen sowohl in den HTTP-Headern als auch im Request-Body.

Die Payload wird mit den folgenden HTTP-Headern gesendet:

User-Agent: Zealy-Webhook
Content-Type: application/json; charset=utf-8
{
  id: string // unique ID for this event (UUID v4)
  type: "JOINED_COMMUNITY" | "LEFT_COMMUNITY" | "QUEST_SUCCEEDED" | "QUEST_CLAIMED" | "QUEST_FAILED" | "QUEST_CLAIM_STATUS_UPDATED" | "SPRINT_STARTED" | "SPRINT_ENDED" | "USER_BANNED", // event type
  data: EventData, // event data, see below
  time: number, // timestamp, in milliseconds
  secret: string, // secret generated when you created your webhook, used for checking origin
}

EventData-Feld pro Ereignis:

// JOINED_COMMUNITY
type JoinedCommunityEventData = {
  community: WebhookCommunityPayload;
  user: WebhookUserPayload;
};
 
// LEFT_COMMUNITY
type LeftCommunityEventData = {
  community: WebhookCommunityPayload;
  user: WebhookUserPayload;
};
 
// QUEST_SUCCEEDED
type QuestSucceededEventData = {
  community: WebhookCommunityPayload;
  user: WebhookUserPayload;
  quest: WebhookQuestPayload;
  taskInputs?: Array<{
    taskId: string, // task ID (uuid v4)
    taskType: 'number' | 'date' | 'api' | 'text' | 'discord' | 'url' | 'telegram' | 'quiz' | 'invites' | 'visitLink' | 'file' | 'poll' | 'opinion' | 'twitterFollow' | 'twitterSpace' | 'tweetReact' | 'tweet',
    input: WebhookQuestTaskInputPayload,
  }>;
  status: 'success';
};
 
// QUEST_CLAIMED
type QuestClaimedEventData = {
  community: WebhookCommunityPayload;
  user: WebhookUserPayload;
  quest: WebhookQuestPayload;
  taskInputs?: Array<{
    taskId: string, // task ID (uuid v4)
    taskType: 'number' | 'date' | 'api' | 'text' | 'discord' | 'url' | 'telegram' | 'quiz' | 'invites' | 'visitLink' | 'file' | 'poll' | 'opinion' | 'twitterFollow' | 'twitterSpace' | 'tweetReact' | 'tweet',
    input: WebhookQuestTaskInputPayload,
  }>;
};
 
// QUEST_FAILED
type QuestFailedEventData = {
  community: WebhookCommunityPayload;
  user: WebhookUserPayload;
  quest: WebhookQuestPayload;
  taskInputs?: Array<{
    taskId: string, // task ID (uuid v4)
    taskType: 'number' | 'date' | 'api' | 'text' | 'discord' | 'url' | 'telegram' | 'quiz' | 'invites' | 'visitLink' | 'file' | 'poll' | 'opinion' | 'twitterFollow' | 'twitterSpace' | 'tweetReact' | 'tweet',
    input: WebhookQuestTaskInputPayload,
  }>;
};
 
// QUEST_CLAIM_STATUS_UPDATED
type QuestClaimStatusUpdatedEventData = {
  community: WebhookCommunityPayload;
  user: WebhookUserPayload;
  quest: WebhookQuestPayload;
  taskInputs?: Array<{
    taskId: string, // task ID (uuid v4)
    taskType: 'number' | 'date' | 'api' | 'text' | 'discord' | 'url' | 'telegram' | 'quiz' | 'invites' | 'visitLink' | 'file' | 'poll' | 'opinion' | 'twitterFollow' | 'twitterSpace' | 'tweetReact' | 'tweet',
    input: WebhookQuestTaskInputPayload,
  }>;
  status: 'success' | 'pending' | 'failed';
};
 
// SPRINT_STARTED
type SprintStartedEventData = {
  community: WebhookCommunityPayload;
  sprint: WebhookSprintPayload;
};
 
// SPRINT_ENDED
type SprintEndedEventData = {
  community: WebhookCommunityPayload;
  sprint: WebhookSprintPayload;
};
 
// USER_BANNED
type UserBannedEventData = {
  community: WebhookCommunityPayload;
  user: WebhookUserPayload;
};

Gemeinsame Entitäten:

type WebhookCommunityPayload = {
  id: string; // community ID (uuid V4)
  name: string; // community name
  subdomain: string; // community subdomain
  blockchain: string;
  discord: string | null; // discord URI of the community, e.g., https://discord.gg/zealy
  twitter: string | null; // twitter handle of the community, e.g., zealy_io
  website: string | null; // website URI of the community
};
type WebhookUserPayload = {
  id: string; // user ID (uuid V4)
  name: string | null; // user display name
  twitter: {
    id: string; // user twitter ID
    username: string | null; // user twitter handle
  } | null;
  discord: {
    id: string; // user discord ID
    handle: string | null; // user discord handle
  } | null;
  email: string | null; // user email
  addresses: Dict<string>; // key/value dictionary for wallets
  verifiedAddresses: Dict<string>; // key/value dictionary for all users verified wallets
};
type WebhookQuestPayload = {
  id: string; // quest ID (uuid V4)
  name: string; // quest display name
  categoryId: string; // category ID (uuid V4)
  categoryName: string | null; // category display name
  xp: number | null; // XP reward
  published: boolean | null; // true if quest is published, false otherwise
  autoValidate: boolean | null;
  tasks: TaskPayload[];
  lastReviewerId: string; // user ID (uuid V4)
};
type WebhookQuestTaskInputPayload =
 | { } // for task type 'visitLink', 'invites', 'discord', 'telegram', 'twitterFollow', 'twitterSpace'
 | { value: string } // for task type 'text', 'date', 'url', 'opinion'
 | { value: number } // for task type 'number'
 | { values: string[] } // for task type 'poll', 'quiz'
 | { fileUrls: string[] } // for task type 'fileUrls'
 | { tweetId?: string } // for task type 'tweetReact', 'tweet'
 | { requestId: string, statusCode: number } // for task type 'api'
type WebhookSprintPayload = {
  id: string; // sprint ID (uuid V4)
  startingAt: ISOString; // sprint starting date - https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Date/toISOString
  endingAt: ISOString; // sprint ending date
};

Webhooks absichern

Beim Erstellen eines Webhooks wird ein zufälliges Secret erzeugt, mit dem du überprüfen kannst, dass die Anfrage von Zealy-Webhooks stammt. Kopiere das Secret oben rechts im Webhook-Inspektionspanel und prüfe, ob das im Body der POST-Anfrage gesetzte Secret dasselbe ist.

Falls das Secret geleakt wird, kannst du es auf derselben Seite neu generieren.

Das Webhook-Inspektionspanel mit der Schaltfläche „Secret kopieren“ und einem geöffneten Menü mit den Einträgen Webhook bearbeiten, Deaktivieren, Testereignis auslösen, Secret neu generieren und Webhook löschen

Webhooks testen

Im Inspektionspanel des Webhooks kannst du manuell ein Testereignis auslösen. Klicke oben rechts auf die Schaltfläche und wähle „Testereignis senden“. Du kannst einen Ereignistyp aus den überwachten Ereignistypen auswählen. Ein Ereignis wird mit Mock-Daten ausgelöst und der Status wird angezeigt.

Debugging

Du kannst die Logs aller vergangenen Ereignisse sehen, die vom Webhook ausgelöst wurden, wenn du auf der Webhooks-Seite auf den Webhook klickst. Durch Filtern nach dem Status kannst du die Logs zum Debuggen nutzen, falls etwas schiefgelaufen ist. Für jedes Ereignis kannst du die empfangene Fehlermeldung und die gesendete Anfrage sehen.

Du kannst auch jedes Ereignis von dieser Seite aus erneut versuchen.

Die Ereignisliste des Webhooks mit Join-Community-Ereignissen, wobei für ein Ereignis die Zustellversuche, die Request-Payload und die Fehlerantwort angezeigt werden

FAQ