Zum Hauptinhalt springen

Webhooks

Webhooks ermoeglichen es Ihnen, HTTP-Callbacks in Echtzeit zu empfangen, wenn Ereignisse auf Ihren WhatsApp-Instanzen auftreten. Anstatt die API abzufragen, sendet Wappfy Ereignisse an Ihren Server, sobald sie eintreten.

Unterstuetzte Ereignisse

Wappfy unterstuetzt 12 Webhook-Ereignistypen:
EreignisBeschreibung
message.receivedEine neue eingehende Nachricht wurde empfangen.
message.sentEine ausgehende Nachricht wurde erfolgreich gesendet.
message.deliveredEine gesendete Nachricht wurde an das Geraet des Empfaengers zugestellt (doppeltes Haekchen).
message.readEine gesendete Nachricht wurde vom Empfaenger gelesen (blaue Haekchen).
message.failedEine ausgehende Nachricht konnte nicht gesendet werden.
message.reactionJemand hat auf eine Nachricht mit einem Emoji reagiert.
EreignisBeschreibung
instance.connectedEine Instanz hat sich erfolgreich mit WhatsApp verbunden.
instance.disconnectedEine Instanz hat die WhatsApp-Verbindung verloren.
instance.qrEin neuer QR-Code steht zum Scannen bereit.
EreignisBeschreibung
group.joinedEin Teilnehmer ist einer Gruppe beigetreten (einschliesslich des Bots selbst).
group.leftEin Teilnehmer hat eine Gruppe verlassen.
contact.createdEin neuer Kontakt wurde gespeichert oder erkannt.

Webhook erstellen

Registrieren Sie einen Webhook-Endpunkt, um Ereignisse zu empfangen.
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
  }'
Antwort:
{
  "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"
  }
}

Konfigurationsoptionen

FeldTypStandardBeschreibung
urlstringerforderlichDie HTTPS-URL, die Webhook-POST-Anfragen empfaengt.
eventsstring[]erforderlichArray von Ereignistypen, die abonniert werden sollen.
instance_idstringnullWebhook auf eine bestimmte Instanz beschraenken. Bei null werden Ereignisse aller Instanzen empfangen.
secretstringnullGeheimnis zur Erzeugung von HMAC-Signaturen fuer die Payload-Verifizierung.
retry_countnumber3Anzahl der Wiederholungsversuche bei Zustellungsfehlern (0-5).
timeout_msnumber10000Anfrage-Timeout in Millisekunden (1000-30000).
Das Feld instance_id ist optional. Wenn es weggelassen wird, empfaengt der Webhook Ereignisse von allen Instanzen in Ihrem Konto.

Webhooks auflisten

curl https://api.wappfy.io/api/webhooks \
  -H "X-Api-Key: YOUR_API_KEY"
Antwort:
{
  "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
    }
  ]
}

Webhook aktualisieren

Aktualisieren Sie die URL, Ereignisse oder Konfiguration eines bestehenden Webhooks.
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
  }'

Webhook loeschen

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

Zustellungs-Payload-Format

Wenn ein Ereignis eintritt, sendet Wappfy eine POST-Anfrage an Ihre Webhook-URL mit folgender Struktur:
{
  "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"
  }
}

Payload-Felder

FeldBeschreibung
idEindeutige Zustellungs-ID. Verwenden Sie diese zur Deduplizierung.
eventDer Ereignistyp, der diese Zustellung ausgeloest hat.
instance_idDie Instanz, die das Ereignis erzeugt hat.
timestampISO-8601-Zeitstempel des Ereignisses.
dataEreignisspezifischer Payload. Der Inhalt variiert je nach Ereignistyp.

HMAC-Signaturverifizierung

Wenn Sie beim Erstellen eines Webhooks ein secret angeben, enthaelt jede Zustellung einen X-Wappfy-Signature-Header mit einer HMAC-SHA256-Signatur des Anfrageinhalts. Verifizieren Sie diese Signatur immer, um sicherzustellen, dass die Anfrage von Wappfy stammt und nicht manipuliert wurde.

Verifizierungsbeispiele

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 });
});
Verwenden Sie immer einen zeitkonstanten Vergleich (wie timingSafeEqual oder hmac.compare_digest) bei der Signaturverifizierung, um Timing-Angriffe zu verhindern.

Wiederholungsverhalten

Wenn Ihr Server nicht innerhalb der konfigurierten timeout_ms mit einem 2xx-Statuscode antwortet, wiederholt Wappfy die Zustellung.
VersuchVerzoegerung
1. Wiederholung10 Sekunden
2. Wiederholung60 Sekunden
3. Wiederholung5 Minuten
4. Wiederholung30 Minuten
5. Wiederholung2 Stunden
Wiederholungen werden gestoppt, wenn eine 2xx-Antwort empfangen wird oder die retry_count-Anzahl erschoepft ist. Der Standard-Wiederholungszaehler betraegt 3.

Zustellungsverlauf einsehen

Pruefen Sie das Zustellungsprotokoll eines Webhooks, um vergangene Zustellungsversuche und deren Ergebnisse einzusehen.
curl https://api.wappfy.io/api/webhooks/wh_xyz789/deliveries \
  -H "X-Api-Key: YOUR_API_KEY"
Antwort:
{
  "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"
    }
  ]
}

Beispiele fuer Ereignis-Payloads

{
  "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]"
  }
}

Best Practices

Schnell antworten

Geben Sie innerhalb von 5 Sekunden einen 200-Status zurueck. Verarbeiten Sie das Ereignis asynchron, um Timeouts zu vermeiden.

Deduplizieren

Verwenden Sie die Zustellungs-id, um doppelte Zustellungen durch Wiederholungen zu erkennen und zu ueberspringen.

Signaturen verifizieren

Validieren Sie immer den X-Wappfy-Signature-Header, wenn Sie ein Geheimnis konfiguriert haben.

HTTPS verwenden

Webhook-URLs muessen HTTPS verwenden. HTTP-Endpunkte werden abgelehnt.