Documentation Zealy

Traduction automatique · Lire en anglais

Webhooks

Améliorez les capacités de Zealy avec les connexions Webhook.

Par louis, Fredrika, benjamin

Webhooks
Sur cette page

Un webhook Zealy envoie une requête HTTP POST vers une URL de votre choix lorsqu'un des neuf événements communautaires se produit, notamment l'arrivée d'un membre, la réussite ou l'échec d'une claim de quête, le démarrage d'un sprint et le bannissement d'un utilisateur. Chaque payload contient un id d'événement, un type, des données, un horodatage en millisecondes et le secret qui prouve l'authenticité de la requête.

Bases

Zealy fournit des webhooks qui vous permettent de recevoir des notifications push HTTP à chaque création ou mise à jour de données. Cela vous permet de construire des intégrations au-dessus de Zealy. Vous pouvez déclencher des builds CI, effectuer des calculs sur les données de quêtes ou envoyer des messages selon des conditions spécifiques – à vous de voir.

Veuillez vous rendre dans Settings > Integrations > Zapier & Webhooks pour configurer vos webhooks.

Comment fonctionne un Webhook ?

Un push Webhook est simplement une requête HTTP POST envoyée à l'URL de votre choix. Le push est automatiquement déclenché par Linear lors d'une mise à jour de données. Pour un exemple du contenu d'un payload, voir Le payload du Webhook.

Votre consommateur de webhook est un simple endpoint HTTP. Il doit remplir les conditions suivantes :

  • Il est disponible via une URL HTTPS accessible publiquement, non localhost
  • Il répond au push Webhook de Zealy (requête HTTP POST) avec une réponse HTTP 200 ("OK")

Si une livraison échoue (par exemple serveur indisponible, réponse prenant plus de 5 secondes, corps de réponse supérieur à 5000 octets ou code de statut HTTP autre que 200), le push sera retenté 15 fois. Un délai de backoff exponentiel est utilisé : la tentative sera retentée après environ 10 minutes, puis 30 minutes, et ainsi de suite. Si l'URL du webhook reste injoignable, le webhook peut être désactivé par Zealy et devra être réactivé manuellement.

Pour garantir qu'un Webhook POST est bien créé par Zealy, nous générons un secret aléatoire qui sera attaché au corps de la requête dans le champ secret .

Pour plus d'informations sur les Webhooks, plusieurs bonnes ressources existent :

À quoi puis-je l'utiliser ?

  • Intégrer avec Zapier
  • Automatiser des récompenses personnalisées
  • Notifier sur Telegram les quêtes en attente de validation

Et bien plus encore !

Démarrer avec les Webhooks Zealy

  1. Identifiez les événements que vous souhaitez surveiller.
  2. Développez une fonction d'endpoint webhook pour recevoir les requêtes POST de données d'événements.
  3. Enregistrez votre endpoint dans Zealy via le tableau de bord Webhooks dans Settings > Integrations > Zapier & Webhooks.
  4. Sécurisez votre endpoint webhook.

Créer un consommateur de Webhook simple

Vous pourriez envisager d'utiliser quelque chose comme Netlify Functions, qui offre un moyen simple de déployer des endpoints HTTP(S) : 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'));

Configuration dans les paramètres

Configurez le webhook et les événements qu'il doit surveiller dans Settings > Integrations > Webhooks.

Le payload du Webhook

Le payload HTTP du webhook inclura des informations à la fois dans ses en-têtes HTTP et dans le corps de sa requête.

Le payload sera envoyé avec les en-têtes HTTP suivants :

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
}

Champ EventData par événement :

// 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;
};

Entités communes :

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
};

Sécuriser les webhooks

Créer un webhook génère un secret aléatoire que vous pouvez utiliser pour vérifier que la requête provient bien des webhooks Zealy. Copiez le secret en haut à droite du panneau d'inspection du webhook et vérifiez que le secret défini dans le corps de la requête POST est identique.

En cas de fuite du secret, vous pouvez le régénérer depuis la même page.

Le panneau d'inspection du webhook avec le bouton Copy secret et un menu ouvert listant Edit webhook, Disable, Trigger test event, Regenerate secret et Delete webhook

Tester les webhooks

Depuis le panneau d'inspection du webhook, vous pouvez déclencher manuellement un événement de test. Cliquez sur le bouton en haut à droite et sélectionnez « Send test event ». Vous pourrez choisir un type d'événement parmi les types surveillés. Un événement sera déclenché avec des données fictives et le statut affiché.

Débogage

Vous pouvez consulter les logs de tous les événements passés déclenchés par le webhook en cliquant sur le webhook depuis la page Webhooks. En filtrant par statut, vous pouvez utiliser les logs pour déboguer en cas de problème. Pour chaque événement, vous pouvez voir le message d'erreur reçu et la requête envoyée.

Vous pouvez également relancer n'importe quel événement depuis cette page.

La liste des logs d'événements du webhook affichant des événements Join community, avec les tentatives de livraison, le payload de requête et la réponse d'erreur d'un événement

FAQ