Webhooks
Améliorez les capacités de Zealy avec les connexions Webhook.
Par louis, Fredrika, benjamin

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 :
- RequestBin : Webhooks – Le guide définitif
- requestbin.com est un excellent outil pour tester les webhooks
- Guide développeur GitHub : Webhooks
À 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
- Identifiez les événements que vous souhaitez surveiller.
- Développez une fonction d'endpoint webhook pour recevoir les requêtes POST de données d'événements.
- Enregistrez votre endpoint dans Zealy via le tableau de bord Webhooks dans Settings > Integrations > Zapier & Webhooks.
- 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.

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.
