Documentación de Zealy

Traducción automática · Leer en inglés

Webhooks

Amplía las capacidades de Zealy con conexiones de webhooks.

Por louis, Fredrika, benjamin

Webhooks
En esta página

Un webhook de Zealy envía un HTTP POST a una URL que elijas cuando se produce uno de nueve eventos de la comunidad, entre ellos la incorporación de un miembro, el éxito o fallo de la reclamación de una quest, el inicio de un sprint y el baneo de un usuario. Cada payload incluye un id de evento, un tipo, datos, una marca de tiempo en milisegundos y el secreto que demuestra que la solicitud es auténtica.

Conceptos básicos

Zealy ofrece webhooks , que te permiten recibir notificaciones push HTTP cada vez que se crean o actualizan datos. Esto te permite crear integraciones sobre Zealy. Puedes activar compilaciones de CI, realizar cálculos con los datos de las quests o enviar mensajes en condiciones específicas, lo que se te ocurra.

Visita Ajustes > Integraciones > Zapier y webhooks para configurar tus webhooks.

¿Cómo funciona un Webhook?

Un push de Webhook es simplemente una HTTP POST solicitud, enviada a la URL que elijas. El push se activa automáticamente por Linear cuando los datos se actualizan. Para ver un ejemplo de los datos que contiene un payload, consulta El payload del Webhook.

Tu consumidor de webhook es un endpoint HTTP simple. Debe cumplir las siguientes condiciones:

  • Está disponible en una URL HTTPS públicamente accesible y que no sea localhost
  • Responderá al push del Webhook de Zealy (solicitud HTTP POST) con una HTTP 200 ("OK") respuesta

Si una entrega falla (es decir, servidor no disponible, la respuesta tardó más de 5 segundos, el cuerpo de la respuesta superó los 5000 bytes o respondió con un código de estado HTTP distinto de 200), el envío se reintentará 15 veces. Aquí se usa un retraso de retroceso exponencial: el intento se reintentará después de aproximadamente 10 minutos, luego 30 minutos, y así sucesivamente. Si la URL del webhook sigue sin responder, Zealy podría deshabilitar el webhook, y deberá volver a habilitarse manualmente.

Para asegurarte de que un Webhook POST es realmente creado por Zealy, generamos un secreto aleatorio que se adjuntará al cuerpo de la solicitud en el secret campo.

Para obtener información adicional sobre Webhooks, hay varios buenos recursos:

¿Para qué puedo usarlo?

  • Integrar con Zapier
  • Automatizar recompensas personalizadas
  • Notificar misiones pendientes de revisión en Telegram

¡Y mucho más!

Primeros pasos con los Webhooks de Zealy

  1. Identifica qué eventos quieres monitorear.
  2. Desarrolla una función de endpoint de webhook para recibir solicitudes POST con datos de eventos.
  3. Registra tu endpoint en Zealy usando el Panel de Webhooks en Configuración > Integraciones > Zapier y Webhooks.
  4. Protege tu endpoint de webhook.

Crear un consumidor de webhook simple

Podrías considerar usar algo como Netlify Functions, que ofrece una forma sencilla de desplegar endpoints HTTP(S) simples: 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'));

Configurar en los ajustes

Configura el webhook y los eventos que debe monitorear en Configuración > Integraciones > Webhooks.

El payload del webhook

El payload HTTP del webhook incluirá información tanto en sus encabezados HTTP como en el cuerpo de la solicitud.

El payload se enviará con los siguientes encabezados HTTP:

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
}

Campo EventData por evento:

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

Entidades comunes:

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

Protección de webhooks

Al crear un webhook se generará un secreto aleatorio que puedes usar para verificar que la solicitud proviene de los webhooks de Zealy. Copia el secreto en la esquina superior derecha del panel de inspección del webhook y verifica que el secreto establecido en el cuerpo de la solicitud POST sea el mismo.

Si el secreto se filtra, puedes regenerarlo desde la misma página.

El panel de inspección del webhook con el botón Copiar secreto y un menú abierto que muestra Editar webhook, Deshabilitar, Activar evento de prueba, Regenerar secreto y Eliminar webhook

Probar webhooks

Desde el panel de inspección del webhook puedes activar manualmente un evento de prueba. Haz clic en el botón de la esquina superior derecha y selecciona «Enviar evento de prueba». Podrás elegir un tipo de evento entre los tipos de evento monitorizados. Se activará un evento con datos simulados y se mostrará el estado.

Depuración

Puedes ver los registros de todos los eventos pasados activados por el webhook si haces clic en el webhook desde la página Webhooks. Filtrando por el estado, puedes usar los registros para depurar si algo salió mal. Para cada evento, puedes ver el mensaje de error recibido y la solicitud que se envió.

También puedes reintentar cualquier evento desde esta página.

El registro de eventos del webhook que muestra eventos Join community, con los intentos de entrega de un evento, la carga útil de la solicitud y la respuesta de error mostrados

Preguntas frecuentes