Pular para o conteúdo
0%

O que é um webhook?

Uttam Singh headshot

Escrito por Uttam Singh

Publicado em 29 de outubro de 202610 min de leitura

O que é um webhook?

Um webhook é uma notificação de evento entregue como um HTTP POST. Quando algo acontece em um sistema, esse sistema envia uma requisição para uma URL que você controla, e o corpo da requisição descreve o que aconteceu. Sua aplicação nunca precisa perguntar se algo mudou.

Em aplicações blockchain, os eventos acontecem onchain. A carteira de um usuário recebe USDC, um NFT muda de dono ou um contrato que você implantou emite um log. Sem um webhook, seu backend faz polling em um node ou em uma API em intervalos fixos e compara os resultados para detectar essas mudanças. Com um webhook, a mudança é enviada ao seu servidor assim que é detectada.

Este guia explica o que são a URL, o endpoint e o payload de um webhook, como um webhook se diferencia de uma API, como funcionam a entrega e as novas tentativas, como verificar uma requisição e como lidar com duplicatas e reorgs em produção.

O que é um webhook?

Um webhook conecta duas partes. O remetente monitora eventos. O destinatário é a sua aplicação, que expõe uma URL. Quando um evento corresponde à sua inscrição, o remetente faz uma requisição HTTP POST para essa URL com um corpo JSON que descreve o evento, e seu servidor responde com um código de status 200 para confirmar que ela chegou. Nenhum dado volta do seu lado, então um webhook é uma mensagem unidirecional, de servidor para servidor.

A alternativa é o polling, que consiste em consultar a origem em busca de atualizações em um intervalo fixo. A maioria dessas requisições volta sem nada novo, e um evento pode passar despercebido por até um intervalo inteiro de polling antes que sua aplicação o veja. Um webhook evita os dois problemas, porque uma requisição só é feita quando há um evento para reportar.

Pense no polling como ligar para uma loja a cada hora para perguntar se o seu pedido chegou. Um webhook é a loja mandando uma mensagem quando ele chega.

O que é uma URL de webhook?

Uma URL de webhook é o endereço público para onde o remetente entrega os eventos, como https://api.example.com/webhooks/alchemy. Você a registra no provedor ao criar o webhook. Os servidores do provedor fazem a requisição, então a URL precisa ser acessível pela internet, e deve usar HTTPS porque o payload descreve a atividade dos seus usuários. Durante o desenvolvimento, uma ferramenta de túnel como o ngrok dá a um servidor no seu laptop uma URL pública temporária. Nosso quickstart de webhooks mostra essa configuração passo a passo.

O que é um endpoint de webhook?

Um endpoint de webhook é a rota no seu servidor que trata as requisições enviadas para a URL de webhook. Os dois termos costumam ser usados como sinônimos. A URL é o endereço, e o endpoint é o código por trás dele.

Mantenha a função do endpoint pequena. Ele verifica se a requisição veio do provedor, armazena o evento e retorna um 200. Trabalhos mais lentos, como atualizar saldos ou enviar notificações push, devem ficar em um worker em segundo plano. Se esse trabalho rodar dentro da requisição, uma chamada lenta ao banco de dados pode fazer o provedor concluir que a entrega falhou.

O que é um payload de webhook?

O payload é o corpo JSON da requisição. Todos os nossos webhooks compartilham o mesmo envelope, e o campo event contém os dados daquele tipo de webhook. Aqui está um payload de um webhook Address Activity, o tipo que monitora uma lista de endereços de carteira, para uma transferência de USDC na Ethereum. Alguns campos foram cortados para encurtar o exemplo.

json
Copied
{ "webhookId": "wh_k63lg72rxda78gce", "id": "whevt_vq499kv7elmlbp2v", "createdAt": "2024-01-23T07:42:26.411977228Z", "type": "ADDRESS_ACTIVITY", "event": { "network": "ETH_MAINNET", "activity": [ { "blockNum": "0xdf34a3", "hash": "0x7a4a39da2a3fa1fc2ef88fd1eaea070286ed2aba21e0419dcfb6d5c5d9f02a72", "fromAddress": "0x503828976d22510aad0201ac7ec88293211d23da", "toAddress": "0xbe3f4b43db5eb49d1f48f53443b9abce45da3b79", "value": 293.092129, "asset": "USDC", "category": "token", "rawContract": { "address": "0xa0b86991c6218b36c1d19d4a2e9eb0ce3606eb48", "decimals": 6 }, "log": { "logIndex": "0x6e", "removed": false } } ] } }

webhookId indica qual webhook disparou, id identifica este evento e type informa o tipo de webhook. Cada entrada em activity é uma transferência que envolveu um endereço monitorado. Para identificar o token, use rawContract.address, o endereço do contrato do token. O símbolo em asset vem do próprio contrato do token, e qualquer pessoa pode implantar um token que se apresente como USDC.

Como um webhook se diferencia de uma API?

Uma API espera que você a chame. Sua aplicação envia uma requisição e recebe dados de volta. Um webhook inverte a direção, porque o provedor chama a sua aplicação quando tem algo a reportar. Essa inversão é o motivo pelo qual webhooks às vezes são chamados de APIs reversas.

Requisição de API
Polling
Webhook
Quem inicia a troca
Sua aplicação
Sua aplicação, em intervalos fixos
O provedor
Quando os dados trafegam
Quando você pede
A cada intervalo, mesmo sem mudanças
Somente quando ocorre um evento
Uso típico
Ler o estado atual sob demanda
Verificações simples em que algum atraso é aceitável
Reagir a eventos no seu servidor

A maioria das aplicações em produção usa os dois. O webhook avisa que algo aconteceu, e uma chamada de API completa o resto. Um backend de pagamentos pode receber um webhook de depósito e depois chamar a Token API para ler o saldo atual da carteira antes de mostrá-lo ao usuário.

Webhooks são adequados quando o consumidor é um endpoint de servidor. Se o consumidor for um processo de longa duração, como um bot de trading ou um dashboard ao vivo, uma assinatura WebSocket é a melhor opção: ela mantém uma conexão aberta e transmite os eventos por ela. Nossa comparação entre webhooks, WebSockets e gRPC explica como escolher entre eles.

Como os webhooks funcionam?

Uma entrega de webhook passa sempre pelas mesmas etapas:

  • Você se inscreve. Você cria um webhook com uma URL de destino e um filtro que define qual rede monitorar e o que monitorar nela, como uma lista de endereços ou os eventos de um contrato.
  • Um evento corresponde ao filtro. Um novo bloco contém atividade que corresponde ao seu filtro.
  • O provedor envia um POST. A requisição leva o payload e um cabeçalho de assinatura que seu servidor pode verificar.
  • Seu servidor confirma o recebimento. Uma resposta 200 marca o evento como entregue.
  • Entregas com falha são repetidas. Se o seu servidor estiver fora do ar, exceder o tempo limite ou retornar qualquer outro status, o provedor tenta novamente mais tarde.

Na Alchemy, as novas tentativas usam backoff exponencial, ou seja, a espera entre as tentativas aumenta após cada falha. Continuamos tentando por até 10 minutos nos planos Free e Pay As You Go e por até uma hora no Enterprise, como nosso quickstart de webhooks descreve na parte sobre comportamento de entrega.

As notificações enviadas pela primeira vez são entregues em ordem em todas as chains, por mais rápido que cada uma produza blocos. Essa garantia vale para as primeiras tentativas, então um evento reenviado pode chegar depois de eventos mais recentes. Armazene o número do bloco com cada evento e ordene seus registros por ele, e não pelo horário de chegada.

Se o seu servidor ficar fora do ar além da janela de novas tentativas, os eventos desse período não são reenviados, então cubra a lacuna a partir do histórico da chain. Na Ethereum e nas L2s compatíveis com a Transfers API, consulte-a para os endereços e o intervalo de blocos que você perdeu. Na Stellar, o endpoint de transferências da Stellar retorna as transferências de uma conta filtradas por intervalo de ledgers. Na Solana, percorra para trás, página por página, as transações de cada endereço monitorado com getSignaturesForAddress.

Para que os webhooks são usados em aplicações blockchain?

Oferecemos quatro tipos de webhook, e a escolha certa depende do que você precisa monitorar.

Tipo de webhook
O que monitora
Redes
Address Activity
Transferências de token nativo, ERC-20, ERC-721 e ERC-1155 enviadas ou recebidas por até 100.000 endereços
Mais de 30 chains EVM e Solana
NFT Activity
Transferências de um NFT, de uma coleção inteira ou de todos os NFTs de uma chain
Ethereum, Arbitrum, Optimism e Polygon
Custom
Quaisquer dados de bloco, transação ou log que você selecionar com uma query GraphQL
Uma rede por webhook
Stellar Address Activity
Transferências de XLM e de ativos Stellar, ordens executadas em DEX e eventos de contratos Soroban para até 100.000 contas
Stellar

Os webhooks Address Activity cobrem a tarefa mais comum, que é monitorar um conjunto de carteiras. Um backend de pagamentos monitora seus endereços de depósito e credita um usuário quando chega USDC. Uma aplicação de carteira envia uma notificação push quando um usuário recebe tokens. Transferências ERC-20 incluem o endereço do contrato do token, e é assim que o backend de pagamentos confirma que um depósito é USDC de verdade.

Os webhooks NFT Activity fazem o mesmo para contratos de NFT, o que atende marketplaces e dashboards de coleções. Os webhooks Custom cuidam de todo o resto. Você escreve uma query GraphQL que seleciona os dados de bloco que deseja, como logs do seu próprio contrato com uma assinatura de evento específica, e o webhook dispara a cada novo bloco apenas com esses dados. Os webhooks Stellar Address Activity levam o monitoramento de endereços à Stellar, incluindo eventos de contratos Soroban.

Cada webhook monitora uma rede. Para cobrir várias chains, crie um webhook por rede e aponte todos para a mesma URL. Webhooks também são adequados para agentes de IA onchain, que podem ser acionados quando uma carteira monitorada movimenta fundos, em vez de fazer polling em loop.

Como verificar a assinatura de um webhook?

Qualquer pessoa que descubra a URL do seu webhook pode enviar uma requisição a ela, então seu endpoint precisa confirmar que cada requisição veio do provedor antes de agir com base nela. Assinamos toda requisição de webhook com HMAC-SHA256, um hash com chave que só quem tem a chave secreta consegue reproduzir. A chave é a chave de assinatura do seu webhook, a entrada é o corpo da requisição e o resultado em hexadecimal vai no cabeçalho X-Alchemy-Signature. Seu servidor calcula o mesmo hash sobre o corpo que recebeu e compara os dois valores.

Cada webhook tem sua própria chave de assinatura, exibida na página desse webhook no dashboard da Alchemy. Três detalhes determinam se a verificação realmente protege você:

  • Faça o hash dos bytes brutos. A assinatura cobre o corpo exatamente como foi enviado. Se o seu framework fizer o parse do JSON e o seu código serializá-lo de novo, o espaçamento e a ordem das chaves podem mudar, e os hashes não vão bater.
  • Compare em tempo constante. Use crypto.timingSafeEqual no Node ou hmac.compare_digest no Python em vez de === ou ==, para que o tempo de resposta não revele quanto de uma assinatura forjada estava correto.
  • Rejeite antes de fazer qualquer outra coisa. Retorne um 401 e pare. Não faça o parse nem armazene um payload que você não verificou.

Aqui está um endpoint Express mínimo que segue as três regras:

typescript
Copied
import express from "express"; import { createHmac, timingSafeEqual } from "node:crypto"; // enqueue is your own durable queue (a database table, SQS, BullMQ). // It should resolve only after the event is safely stored. import { enqueue } from "./queue"; const signingKey = process.env.ALCHEMY_WEBHOOK_SIGNING_KEY ?? ""; if (!signingKey) throw new Error("Set ALCHEMY_WEBHOOK_SIGNING_KEY"); function isValidSignature(rawBody: Buffer, signature: string | undefined): boolean { if (!signature) return false; const expected = createHmac("sha256", signingKey).update(rawBody).digest(); const received = Buffer.from(signature, "hex"); return received.length === expected.length && timingSafeEqual(received, expected); } const app = express(); // express.raw() keeps the exact bytes Alchemy signed, so don't parse JSON on this route first. app.post("/webhooks/alchemy", express.raw({ type: "*/*" }), async (req, res) => { if (!isValidSignature(req.body, req.get("x-alchemy-signature"))) { res.sendStatus(401); return; } await enqueue(JSON.parse(req.body.toString("utf8"))); res.sendStatus(200); }); app.listen(8080);

Como segunda camada de proteção, você pode liberar no seu firewall apenas os endereços IP dos nossos webhooks. A seção de segurança do quickstart de webhooks lista esses endereços.

Como sua aplicação deve lidar com webhooks duplicados, atrasados ou afetados por reorg?

Trate a entrega de webhooks como "pelo menos uma vez". Uma nova tentativa após um timeout pode entregar um evento que seu servidor já armazenou, então o handler precisa ser idempotente. Processar o mesmo evento duas vezes deve ter o mesmo efeito que processá-lo uma vez.

  • Deduplique por transferência, não por requisição. Um payload pode trazer várias transferências, e uma transação também pode conter várias. Monte uma chave a partir da rede, do hash da transação e da posição da transferência na transação, que é log.logIndex para transferências de token e typeTraceAddress para transferências internas. Uma transferência externa precisa apenas do hash, já que cada transação tem só uma. Armazene a chave em uma tabela com uma restrição de unicidade e ignore uma entrega somente quando tanto a chave quanto o valor de log.removed dela corresponderem ao registro armazenado.
  • Armazene primeiro, depois confirme. Retorne o 200 quando o evento estiver armazenado de forma durável e faça o trabalho real em um worker. Um handler que faz o trabalho antes de responder corre o risco de um timeout, e o timeout dispara uma nova tentativa de um evento com base no qual você talvez já tenha agido.
  • Reverta transferências afetadas por reorg. Uma reorganização da chain, ou reorg, substitui blocos recentes, e as transações nos blocos substituídos saem da chain. Transferências de token trazem um campo log.removed, e true significa que a transação não está mais na chain canônica. Uma entrega com log.removed definido como true traz a mesma chave da transferência original, então trate-a como uma atualização do registro armazenado. Marque o registro como removido e desfaça o que a sua aplicação tiver feito para essa transferência.
  • Aguarde a finalidade antes de ações irreversíveis. Mostrar um depósito pendente imediatamente é razoável. Liberar fundos, enviar mercadorias ou creditar um saldo disponível para saque deve esperar até que o bloco seja finalizado. Na Ethereum, a tag de bloco finalized indica quais blocos chegaram a esse ponto.

Como configurar um webhook na Alchemy?

Comece pelo listener. Nosso quickstart de webhooks tem servidores de exemplo em JavaScript, Python, Go e Rust com verificação de assinatura já incluída, e o repositório de exemplos de webhook tem projetos completos que você pode rodar localmente.

Depois, crie o webhook. O dashboard de webhooks é o caminho mais rápido. Escolha o tipo e a rede, adicione os endereços ou o filtro, cole sua URL e use o botão Test Webhook para enviar um evento de exemplo ao seu endpoint.

Para criar webhooks via código, chame a Notify API com o token de autenticação exibido no topo do seu dashboard de webhooks:

bash
Copied
curl -X POST https://dashboard.alchemy.com/api/create-webhook \ -H "X-Alchemy-Token: $ALCHEMY_WEBHOOK_AUTH_TOKEN" \ -H "Content-Type: application/json" \ -d '{ "network": "BASE_MAINNET", "webhook_type": "ADDRESS_ACTIVITY", "webhook_url": "https://api.example.com/webhooks/alchemy", "addresses": ["0xYOUR_DEPOSIT_ADDRESS"] }'

Você pode adicionar e remover endereços depois pela mesma API, então uma aplicação que cria um endereço de depósito para cada novo usuário mantém um único webhook em vez de criar milhares. A Alchemy CLI encapsula a mesma API com alchemy webhook create, list, update e delete, o que é útil quando um agente de programação gerencia seus webhooks.

Demonstração do dashboard da Alchemy
Free video demo

Veja o dashboard da Alchemy em ação

Tour guiado de 30 minutos: todas as ferramentas do dashboard, demonstradas ao vivo.

Watch the demo

Comece a usar webhooks na Alchemy

Os Alchemy Webhooks estão disponíveis no plano Free, sem contrato e sem compromisso mínimo. Um bom primeiro webhook é um webhook Address Activity em uma carteira que você controla. Envie uma pequena transferência para ela e veja o payload chegar ao seu endpoint. A partir daí, os webhooks Custom permitem monitorar os eventos dos seus próprios contratos com o mesmo comportamento de entrega, novas tentativas e assinatura.

Perguntas frequentes

O que é um webhook, em termos simples?

Um webhook é uma mensagem automática que uma aplicação envia para outra quando algo acontece. A aplicação remetente faz uma requisição HTTP POST para uma URL que você fornece, com os detalhes do evento no corpo da requisição. Sua aplicação não precisa ficar pedindo atualizações, porque a atualização é enviada a ela.

Qual é a diferença entre um webhook e uma API?

Com uma API, sua aplicação envia uma requisição e o servidor responde com dados. Com um webhook, o servidor envia uma requisição para a sua aplicação quando um evento acontece, sem que ela tenha pedido. APIs são adequadas para ler dados sob demanda, e webhooks, para reagir a eventos. A maioria das aplicações usa os dois: recebe um webhook e depois chama uma API para obter os detalhes.

Como recebo uma notificação de webhook quando USDC chega à minha carteira?

Crie um webhook Address Activity da Alchemy na chain em que você recebe USDC, adicione o endereço da sua carteira e aponte o webhook para a URL do seu servidor. Cada transferência recebida chega com o remetente, o valor e o endereço do contrato do token. Faça a correspondência pelo endereço do contrato do USDC, e não pelo símbolo "USDC", porque qualquer pessoa pode implantar um token com esse nome.

Como recebo notificações de webhook para atividade de carteiras Solana?

O webhook Address Activity da Alchemy oferece suporte a Solana, além de mais de 30 chains EVM, então você pode monitorar um conjunto de endereços de carteira Solana e receber uma requisição POST quando houver atividade neles. A documentação do webhook Address Activity tem um link para o guia de configuração específico para Solana. Verifique a assinatura de cada requisição antes de processá-la.

Um webhook pode me notificar quando meu smart contract emite um evento?

Sim. Os webhooks Custom da Alchemy recebem uma query GraphQL, então você pode filtrar logs do endereço do seu contrato com uma assinatura de evento específica. O webhook então dispara a cada novo bloco apenas com os logs correspondentes. Cada webhook Custom monitora uma rede, então crie um para cada chain em que seu contrato estiver implantado.

O que acontece se meu servidor estiver fora do ar quando um webhook disparar?

A Alchemy repete entregas com falha usando backoff exponencial, por até 10 minutos nos planos Free e Pay As You Go e por até uma hora no Enterprise. Uma entrega falha quando seu servidor não retorna um 200. Se o seu servidor ficar fora do ar por mais tempo que isso, recupere a atividade perdida a partir do histórico da chain, usando a Transfers API na Ethereum e nas L2s compatíveis e o próprio endpoint de histórico de cada chain na Solana e na Stellar.

Quantos endereços um webhook pode monitorar?

Um webhook Address Activity da Alchemy monitora até 100.000 endereços, e um webhook Stellar Address Activity também. Você pode adicionar e remover endereços pela Notify API sem recriar o webhook, o que atende aplicações que criam um novo endereço de depósito para cada usuário.

Background gradient

Construa magia blockchain

A Alchemy combina os produtos e ferramentas de desenvolvimento Web3 mais poderosos com recursos, comunidade e suporte lendário.