Ana içeriğe atla

Webhook’lar

Webhook’lar, WhatsApp \u00f6rneklerinizde olaylar ger\u00e7ekle\u015fti\u011finde ger\u00e7ek zamanl\u0131 HTTP geri \u00e7a\u011fr\u0131lar\u0131 alman\u0131z\u0131 sa\u011flar. API’yi s\u00fcrekli sorgulamak yerine, Wappfy olaylar\u0131 ger\u00e7ekle\u015ftik\u00e7e sunucunuza iletir.

Desteklenen Olaylar

Wappfy 12 webhook olay t\u00fcr\u00fcn\u00fc destekler:
OlayA\u00e7\u0131klama
message.receivedYeni bir gelen mesaj al\u0131nd\u0131.
message.sentGiden bir mesaj ba\u015far\u0131yla g\u00f6nderildi.
message.deliveredG\u00f6nderilen mesaj al\u0131c\u0131n\u0131n cihaz\u0131na teslim edildi (\u00e7ift onay i\u015fareti).
message.readG\u00f6nderilen mesaj al\u0131c\u0131 taraf\u0131ndan okundu (mavi onay i\u015faretleri).
message.failedGiden bir mesaj g\u00f6nderilemedi.
message.reactionBirisi bir mesaja emoji ile tepki verdi.
OlayA\u00e7\u0131klama
instance.connectedBir \u00f6rnek WhatsApp’a ba\u015far\u0131yla ba\u011fland\u0131.
instance.disconnectedBir \u00f6rne\u011fin WhatsApp ba\u011flant\u0131s\u0131 kesildi.
instance.qrTarama i\u00e7in yeni bir QR kod mevcut.
OlayA\u00e7\u0131klama
group.joinedBir kat\u0131l\u0131mc\u0131 gruba kat\u0131ld\u0131 (bot kendisi dahil).
group.leftBir kat\u0131l\u0131mc\u0131 gruptan ayr\u0131ld\u0131.
contact.createdYeni bir ki\u015fi kaydedildi veya alg\u0131land\u0131.

Webhook Olu\u015fturma

Olaylar\u0131 almaya ba\u015flamak i\u00e7in bir webhook ucu noktas\u0131 kaydedin.
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
  }'
Yan\u0131t:
{
  "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"
  }
}

Yap\u0131land\u0131rma Se\u00e7enekleri

AlanT\u00fcrVarsay\u0131lanA\u00e7\u0131klama
urlstringzorunluWebhook POST isteklerini alacak HTTPS URL’si.
eventsstring[]zorunluAbone olunacak olay t\u00fcrleri dizisi.
instance_idstringnullWebhook’\u0131 belirli bir \u00f6rnekle s\u0131n\u0131rlay\u0131n. Null ise t\u00fcm \u00f6rneklerden olaylar\u0131 al\u0131r.
secretstringnullVeri y\u00fck\u00fc do\u011frulamas\u0131 i\u00e7in HMAC imzalar\u0131 olu\u015fturmak \u00fczere kullan\u0131lan gizli anahtar.
retry_countnumber3Teslimat ba\u015far\u0131s\u0131zl\u0131\u011f\u0131nda yeniden deneme say\u0131s\u0131 (0-5).
timeout_msnumber10000Milisaniye cinsinden istek zaman a\u015f\u0131m\u0131 (1000-30000).
instance_id alan\u0131 iste\u011fe ba\u011fl\u0131d\u0131r. Belirtilmezse webhook, hesab\u0131n\u0131zdaki t\u00fcm \u00f6rneklerden olaylar\u0131 alacakt\u0131r.

Webhook’lar\u0131 Listeleme

curl https://api.wappfy.io/api/webhooks \
  -H "X-Api-Key: YOUR_API_KEY"
Yan\u0131t:
{
  "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 G\u00fcncelleme

Mevcut bir webhook’\u0131n URL’sini, olaylar\u0131n\u0131 veya yap\u0131land\u0131rmas\u0131n\u0131 g\u00fcncelleyin.
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 Silme

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

Teslimat Veri Y\u00fck\u00fc Format\u0131

Bir olay ger\u00e7ekle\u015fti\u011finde, Wappfy webhook URL’nize a\u015fa\u011f\u0131daki yap\u0131da bir POST iste\u011fi g\u00f6nderir:
{
  "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"
  }
}

Veri Y\u00fck\u00fc Alanlar\u0131

AlanA\u00e7\u0131klama
idBenzersiz teslimat kimli\u011fi. Tekrar\u0131 \u00f6nleme i\u00e7in kullan\u0131n.
eventBu teslimati tetikleyen olay t\u00fcr\u00fc.
instance_idOlay\u0131 \u00fcreten \u00f6rnek.
timestampOlay\u0131n ger\u00e7ekle\u015fti\u011fi ISO 8601 zaman damgas\u0131.
dataOlaya \u00f6zel veri y\u00fck\u00fc. \u0130\u00e7eri\u011fi olay t\u00fcr\u00fcne g\u00f6re de\u011fi\u015fir.

HMAC \u0130mza Do\u011frulamas\u0131

Webhook olu\u015ftururken bir secret sa\u011flarsan\u0131z, her teslimat istek g\u00f6vdesinin HMAC-SHA256 imzas\u0131n\u0131 i\u00e7eren bir X-Wappfy-Signature ba\u015fl\u0131\u011f\u0131 i\u00e7erecektir. \u0130ste\u011fin Wappfy’den geldi\u011finden ve de\u011fi\u015ftirilmedi\u011finden emin olmak i\u00e7in bu imzay\u0131 her zaman do\u011frulay\u0131n.

Do\u011frulama \u00d6rnekleri

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 });
});
Zamanlama sald\u0131r\u0131lar\u0131n\u0131 \u00f6nlemek i\u00e7in imzalar\u0131 do\u011frularken her zaman sabit zamanl\u0131 kar\u015f\u0131la\u015ft\u0131rma (timingSafeEqual veya hmac.compare_digest gibi) kullan\u0131n.

Yeniden Deneme Davran\u0131\u015f\u0131

Sunucunuz yap\u0131land\u0131r\u0131lm\u0131\u015f timeout_ms s\u00fcresi i\u00e7inde 2xx durum kodu ile yan\u0131t vermezse, Wappfy teslimati yeniden dener.
DenemeGecikme
1. yeniden deneme10 saniye
2. yeniden deneme60 saniye
3. yeniden deneme5 dakika
4. yeniden deneme30 dakika
5. yeniden deneme2 saat
2xx yan\u0131t al\u0131nd\u0131\u011f\u0131nda veya retry_count t\u00fckendi\u011finde yeniden denemeler durur. Varsay\u0131lan yeniden deneme say\u0131s\u0131 3’t\u00fcr.

Teslimat Ge\u00e7mi\u015fini G\u00f6r\u00fcnt\u00fcleme

Ge\u00e7mi\u015f teslimat denemelerini ve sonu\u00e7lar\u0131n\u0131 g\u00f6rmek i\u00e7in webhook teslimat g\u00fcnl\u00fc\u011f\u00fcn\u00fc kontrol edin.
curl https://api.wappfy.io/api/webhooks/wh_xyz789/deliveries \
  -H "X-Api-Key: YOUR_API_KEY"
Yan\u0131t:
{
  "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"
    }
  ]
}

Olay Veri Y\u00fck\u00fc \u00d6rnekleri

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

En \u0130yi Uygulamalar

H\u0131zl\u0131 yan\u0131t verin

5 saniye i\u00e7inde 200 durumu d\u00f6nd\u00fcr\u00fcn. Zaman a\u015f\u0131m\u0131n\u0131 \u00f6nlemek i\u00e7in olay\u0131 asenkron olarak i\u015fleyin.

Tekrar\u0131 \u00f6nleyin

Yeniden denemelerden kaynaklanan tekrar teslimatlar\u0131 tespit etmek ve atlamak i\u00e7in teslimat id’sini kullan\u0131n.

\u0130mzalar\u0131 do\u011frulay\u0131n

Bir gizli anahtar yap\u0131land\u0131rd\u0131ysan\u0131z her zaman X-Wappfy-Signature ba\u015fl\u0131\u011f\u0131n\u0131 do\u011frulay\u0131n.

HTTPS kullan\u0131n

Webhook URL’leri HTTPS kullanmal\u0131d\u0131r. HTTP ucu noktalar\u0131 reddedilecektir.