Przejdź do głównej treści

Webhooki

Webhooki umozliwiaja odbieranie wywolan zwrotnych HTTP w czasie rzeczywistym, gdy zdarzenia wystepuja na Twoich instancjach WhatsApp. Zamiast odpytywac API, Wappfy przesyla zdarzenia na Twoj serwer w momencie ich wystapienia.

Obslugiwane zdarzenia

Wappfy obsluguje 12 typow zdarzen webhook:
ZdarzenieOpis
message.receivedOtrzymano nowa wiadomosc przychodzaca.
message.sentWiadomosc wychodzaca zostala pomyslnie wyslana.
message.deliveredWyslana wiadomosc zostala dostarczona na urzadzenie odbiorcy (podwojny znacznik).
message.readWyslana wiadomosc zostala przeczytana przez odbiorce (niebieskie znaczniki).
message.failedWiadomosc wychodzaca nie zostala wyslana.
message.reactionKtos zareagowal na wiadomosc za pomoca emoji.
ZdarzenieOpis
instance.connectedInstancja pomyslnie polaczyla sie z WhatsApp.
instance.disconnectedInstancja utracila polaczenie z WhatsApp.
instance.qrDostepny jest nowy kod QR do zeskanowania.
ZdarzenieOpis
group.joinedUczestnik dolaczyl do grupy (w tym sam bot).
group.leftUczestnik opuscil grupe.
contact.createdNowy kontakt zostal zapisany lub wykryty.

Tworzenie webhooka

Zarejestruj endpoint webhook, aby zaczac odbierac zdarzenia.
curl -X POST https://api.wappfy.io/api/webhooks \
  -H "X-Api-Key: YOUR_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "url": "https://your-server.com/webhooks/wappfy",
    "events": ["message.received", "message.sent", "message.delivered"],
    "instance_id": "inst_abc123",
    "secret": "whsec_my_signing_secret",
    "retry_count": 3,
    "timeout_ms": 10000
  }'
Odpowiedz:
{
  "data": {
    "id": "wh_xyz789",
    "url": "https://your-server.com/webhooks/wappfy",
    "events": ["message.received", "message.sent", "message.delivered"],
    "instance_id": "inst_abc123",
    "is_active": true,
    "retry_count": 3,
    "timeout_ms": 10000,
    "created_at": "2026-02-10T12:00:00Z"
  }
}

Opcje konfiguracji

PoleTypDomyslnaOpis
urlstringwymaganeAdres URL HTTPS, ktory bedzie odbierac zapytania POST webhook.
eventsstring[]wymaganeTablica typow zdarzen do subskrypcji.
instance_idstringnullOgraniczenie webhooka do konkretnej instancji. Jesli null, odbiera zdarzenia ze wszystkich instancji.
secretstringnullSekret uzywany do generowania sygnatur HMAC do weryfikacji danych.
retry_countnumber3Liczba ponownych prob dostarczenia w przypadku niepowodzenia (0-5).
timeout_msnumber10000Limit czasu zapytania w milisekundach (1000-30000).
Pole instance_id jest opcjonalne. Jesli pominiesz je, webhook bedzie odbierac zdarzenia ze wszystkich instancji na Twoim koncie.

Lista webhookow

curl https://api.wappfy.io/api/webhooks \
  -H "X-Api-Key: YOUR_API_KEY"
Odpowiedz:
{
  "data": [
    {
      "id": "wh_xyz789",
      "url": "https://your-server.com/webhooks/wappfy",
      "events": ["message.received", "message.sent", "message.delivered"],
      "instance_id": "inst_abc123",
      "is_active": true,
      "retry_count": 3,
      "timeout_ms": 10000
    }
  ]
}

Aktualizacja webhooka

Zaktualizuj URL, zdarzenia lub konfiguracje istniejacego webhooka.
curl -X PATCH https://api.wappfy.io/api/webhooks/wh_xyz789 \
  -H "X-Api-Key: YOUR_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "events": ["message.received", "message.sent", "message.delivered", "message.read"],
    "is_active": true
  }'

Usuwanie webhooka

curl -X DELETE https://api.wappfy.io/api/webhooks/wh_xyz789 \
  -H "X-Api-Key: YOUR_API_KEY"

Format danych dostarczenia

Gdy wystapi zdarzenie, Wappfy wysyla zapytanie POST na URL webhooka z nastepujaca struktura:
{
  "id": "dlv_abc123def456",
  "event": "message.received",
  "instance_id": "inst_abc123",
  "timestamp": "2026-02-10T14:30:00Z",
  "data": {
    "message_id": "BAE5F2C4D3B2A1",
    "chat_id": "[email protected]",
    "from": "[email protected]",
    "type": "text",
    "text": "Hello!",
    "timestamp": "2026-02-10T14:30:00Z"
  }
}

Pola danych

PoleOpis
idUnikalny identyfikator dostarczenia. Uzyj go do deduplikacji.
eventTyp zdarzenia, ktore wyzwolilo to dostarczenie.
instance_idInstancja, ktora wygenerowala zdarzenie.
timestampZnacznik czasu ISO 8601 wystapienia zdarzenia.
dataDane specyficzne dla zdarzenia. Zawartosc rozni sie w zaleznosci od typu zdarzenia.

Weryfikacja sygnatury HMAC

Jesli podales secret podczas tworzenia webhooka, kazde dostarczenie bedzie zawierac naglowek X-Wappfy-Signature z sygnatura HMAC-SHA256 tresci zapytania. Zawsze weryfikuj te sygnature, aby upewnic sie, ze zapytanie pochodzi od Wappfy i nie zostalo zmodyfikowane.

Przyklady weryfikacji

const crypto = require("crypto");

function verifyWebhookSignature(req, secret) {
  const signature = req.headers["x-wappfy-signature"];
  if (!signature) return false;

  const expectedSignature = crypto
    .createHmac("sha256", secret)
    .update(JSON.stringify(req.body))
    .digest("hex");

  return crypto.timingSafeEqual(
    Buffer.from(signature),
    Buffer.from(expectedSignature)
  );
}

// Express middleware
app.post("/webhooks/wappfy", (req, res) => {
  const isValid = verifyWebhookSignature(req, "whsec_my_signing_secret");

  if (!isValid) {
    return res.status(401).json({ error: "Invalid signature" });
  }

  const { event, data } = req.body;
  console.log(`Received event: ${event}`, data);

  // Always respond with 200 quickly to prevent retries
  res.status(200).json({ received: true });
});
Zawsze uzywaj porownania staloczasowego (jak timingSafeEqual lub hmac.compare_digest) przy weryfikacji sygnatur, aby zapobiec atakom czasowym.

Polityka ponownych prob

Jesli Twoj serwer nie odpowie kodem statusu 2xx w skonfigurowanym czasie timeout_ms, Wappfy ponowi probe dostarczenia.
ProbaOpoznienie
1. ponowna proba10 sekund
2. ponowna proba60 sekund
3. ponowna proba5 minut
4. ponowna proba30 minut
5. ponowna proba2 godziny
Ponowne proby sa przerywane po otrzymaniu odpowiedzi 2xx lub wyczerpaniu retry_count. Domyslna liczba ponownych prob to 3.

Przegladanie historii dostarczen

Sprawdz dziennik dostarczen webhooka, aby zobaczyc poprzednie proby dostarczenia i ich wyniki.
curl https://api.wappfy.io/api/webhooks/wh_xyz789/deliveries \
  -H "X-Api-Key: YOUR_API_KEY"
Odpowiedz:
{
  "data": [
    {
      "id": "dlv_abc123def456",
      "event": "message.received",
      "status": "delivered",
      "http_status": 200,
      "attempts": 1,
      "created_at": "2026-02-10T14:30:00Z",
      "delivered_at": "2026-02-10T14:30:01Z"
    },
    {
      "id": "dlv_ghi789jkl012",
      "event": "message.sent",
      "status": "failed",
      "http_status": 500,
      "attempts": 3,
      "created_at": "2026-02-10T14:31:00Z",
      "last_error": "Server returned 500 Internal Server Error"
    }
  ]
}

Przyklady danych zdarzen

{
  "id": "dlv_abc123",
  "event": "message.received",
  "instance_id": "inst_abc123",
  "timestamp": "2026-02-10T14:30:00Z",
  "data": {
    "message_id": "BAE5F2C4D3B2A1",
    "chat_id": "[email protected]",
    "from": "[email protected]",
    "type": "text",
    "text": "Hello, I need help with my order",
    "timestamp": "2026-02-10T14:30:00Z"
  }
}
{
  "id": "dlv_def456",
  "event": "message.delivered",
  "instance_id": "inst_abc123",
  "timestamp": "2026-02-10T14:30:05Z",
  "data": {
    "message_id": "BAE5A1B2C3D4E5",
    "chat_id": "[email protected]",
    "status": "delivered"
  }
}
{
  "id": "dlv_ghi789",
  "event": "message.read",
  "instance_id": "inst_abc123",
  "timestamp": "2026-02-10T14:31:00Z",
  "data": {
    "message_id": "BAE5A1B2C3D4E5",
    "chat_id": "[email protected]",
    "status": "read"
  }
}
{
  "id": "dlv_jkl012",
  "event": "message.reaction",
  "instance_id": "inst_abc123",
  "timestamp": "2026-02-10T14:32:00Z",
  "data": {
    "message_id": "BAE5F2C4D3B2A1",
    "chat_id": "[email protected]",
    "from": "[email protected]",
    "reaction": "\u2764\ufe0f"
  }
}
{
  "id": "dlv_mno345",
  "event": "instance.connected",
  "instance_id": "inst_abc123",
  "timestamp": "2026-02-10T12:00:00Z",
  "data": {
    "instance_id": "inst_abc123",
    "status": "connected",
    "phone_number": "5511999998888"
  }
}
{
  "id": "dlv_pqr678",
  "event": "instance.qr",
  "instance_id": "inst_abc123",
  "timestamp": "2026-02-10T11:59:00Z",
  "data": {
    "instance_id": "inst_abc123",
    "qr": "data:image/png;base64,iVBORw0KGgo..."
  }
}
{
  "id": "dlv_stu901",
  "event": "group.joined",
  "instance_id": "inst_abc123",
  "timestamp": "2026-02-10T15:00:00Z",
  "data": {
    "group_id": "[email protected]",
    "participant": "[email protected]"
  }
}

Dobre praktyki

Odpowiadaj szybko

Zwroc status 200 w ciagu 5 sekund. Przetwarzaj zdarzenie asynchronicznie, aby uniknac limitow czasu.

Deduplikuj

Uzyj id dostarczenia do wykrywania i pomijania zduplikowanych dostarczen spowodowanych ponownymi probami.

Weryfikuj sygnatury

Zawsze waliduj naglowek X-Wappfy-Signature, jesli skonfigurowales sekret.

Uzywaj HTTPS

Adresy URL webhookow musza uzywac HTTPS. Endpointy HTTP beda odrzucane.