Documentação do Zealy

Tradução automática · Ler em inglês

Webhooks

Amplie os recursos do Zealy com conexões de webhook.

Por louis, Fredrika, benjamin

Webhooks
Nesta página

Um webhook do Zealy envia um HTTP POST para uma URL que você escolher quando um dos nove eventos da comunidade ocorrer, entre eles a entrada de um membro, o sucesso ou a falha de uma claim de quest, o início de um sprint e o banimento de um usuário. Cada payload carrega um id de evento, tipo, dados, um timestamp em milissegundos e o segredo que comprova que a requisição é genuína.

Noções básicas

O Zealy oferece webhooks , que permitem receber notificações push HTTP sempre que dados forem criados ou atualizados. Isso permite criar integrações sobre o Zealy. Você pode acionar builds de CI, realizar cálculos com dados de quests ou enviar mensagens em condições específicas – as possibilidades são inúmeras.

Acesse Configurações > Integrações > Zapier & Webhooks para configurar seus webhooks.

Como funciona um Webhook?

Um push de Webhook é simplesmente uma HTTP POST requisição, enviada para a URL de sua escolha. O push é acionado automaticamente pelo Linear quando os dados são atualizados. Para um exemplo do que um payload de dados contém, veja O Payload do Webhook.

Seu consumidor de webhook é um endpoint HTTP simples. Ele deve atender às seguintes condições:

  • Está disponível em uma URL HTTPS publicamente acessível, que não seja localhost
  • Ele responderá ao push do Webhook do Zealy (requisição HTTP POST) com uma HTTP 200 ("OK") resposta

Se uma entrega falhar (ou seja, servidor indisponível, resposta levou mais de 5 segundos, corpo da resposta maior que 5000 bytes ou resposta com código de status HTTP diferente de 200), o envio será repetido 15 vezes. Aqui é usado um atraso exponencial: a tentativa será repetida após aproximadamente 10 minutos, depois 30 minutos, e assim por diante. Se a URL do webhook continuar sem responder, o webhook pode ser desativado pelo Zealy e precisará ser reativado manualmente.

Para garantir que um Webhook POST seja realmente criado pelo Zealy, geramos um segredo aleatório que será anexado ao corpo da requisição no secret campo.

Para informações adicionais sobre Webhooks, existem vários bons recursos:

Para que posso usar?

  • Integrar com Zapier
  • Automatizar recompensas personalizadas
  • Notificar quests aguardando revisão no Telegram

E muito mais!

Começando com Zealy Webhooks

  1. Identifique quais eventos você deseja monitorar.
  2. Desenvolva uma função de endpoint de webhook para receber requisições POST de dados de eventos.
  3. Registre seu endpoint no Zealy usando o Webhooks Dashboard em Settings > Integrations > Zapier & Webhooks.
  4. Proteja seu endpoint de webhook.

Criando um consumidor de webhook simples

Você pode considerar usar algo como Netlify Functions, que oferece uma forma simples de implantar 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'));

Configurando nas configurações

Configure o webhook e os eventos que ele deve monitorar em Settings > Integrations > Webhooks.

O payload do Webhook

O payload HTTP do webhook incluirá informações tanto nos cabeçalhos HTTP quanto no corpo da requisição.

O payload será enviado com os seguintes cabeçalhos 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 comuns:

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

Protegendo webhooks

Criar um webhook gerará um segredo aleatório que você pode usar para verificar se a requisição vem dos webhooks do Zealy. Copie o segredo no canto superior direito do painel de inspeção do webhook e verifique se o segredo definido no corpo da requisição POST é o mesmo.

Caso o segredo seja vazado, você pode regenerá-lo na mesma página.

O painel de inspeção do webhook com o botão Copiar segredo e um menu aberto listando Editar webhook, Desativar, Acionar evento de teste, Regenerar segredo e Excluir webhook

Testando webhooks

No painel de inspeção do webhook, você pode acionar manualmente um evento de teste. Clique no botão no canto superior direito e selecione ‘Enviar evento de teste’. Você poderá selecionar um tipo de evento entre os tipos monitorados. Um evento será acionado com dados simulados e o status será exibido.

Depuração

Você pode ver os logs de todos os eventos passados acionados pelo webhook ao clicar no webhook na página Webhooks. Filtrando por status, você pode usar os logs para depurar se algo deu errado. Para cada evento, você pode ver a mensagem de erro recebida e a requisição enviada.

Você também pode tentar novamente qualquer evento nesta página.

O log de eventos do webhook listando eventos Join community, com as tentativas de entrega de um evento, o payload da requisição e a resposta de erro exibidos

Perguntas frequentes