TL;DR: calls.post'a abone olun, iki saniye içinde HTTP 200 döndürün ve CRM mantığını düz JSON durumlarından (initiated, ringing, answered, missed, canceled) yönetin. id ve timestamp ile tekrarları ayıklayın. WebRTC olmadan gözlemlenebilir yaşam döngüsünün tamamını alırsınız; arama süresi gelecekteki terminate webhook'unu bekliyor.
Whapi calls.post, WebRTC veya SDP olmadan hem 1:1 hem grup aramaları için düz JSON webhook'larla gözlemlenebilir arama yaşam döngüsünün tamamını iletir. Node.js backend'iniz her çalma ve cevaplamaya normal bir HTTPS handler üzerinden tepki verir. Sınır nettir: bu API yüzeyinde terminate event'i yoktur; arama süresi bugün kullanılamaz.
Önce mesaj webhook'larını bağlayıp arama event'lerini atlayan ekipler, ses WhatsApp Web'e geldiği anda CRM görünürlüğünü kaybeder.
WhatsApp Web'de Grup Aramaları — Arama Webhook'ları Neden Şimdi Önemli
WhatsApp Web'de grup ses ve video, beta kanalları üzerinden yayılıyor; 32 katılımcıya kadar, seçici çaldırma ve paylaşılabilir arama linkleri rapor ediliyor.
WABetaInfo, Web grup araması yayılımını istemci özelliği olarak takip etti. Backend sistemlerinin hâlâ WhatsApp Web grup aramaları için sunucu tarafı duruma ihtiyacı var: kim çaldırdı, kim açtı, kim kaçırdı — sizin kontrol ettiğiniz bir endpoint'e iletilmeli. calls.post tam bunun içindir: medya akışları değil, gözlemlenebilir sinyal event'leri.
Birlikte çalıştığımız bir klinik ekibi, calls.post etkinleştirildikten sonra WebRTC yığını olmadan bir gün içinde missed event'lerini metin geri dönüş akışına bağladı.
Whapi calls.post 60 saniyede
Kanal webhook URL'nizde calls.post'u etkinleştirin, POST payload'larını kabul edin, hızlı yanıt verin ve yan etkiler çalışmadan önce her arama satırını kalıcı hale getirin.
Düz JSON webhook'lar, WebRTC SDP değil. Her teslimat, üst düzey calls dizisi altında bir veya daha fazla nesne sarar. Alanlar doğrudan OpenAPI CallEvent şemasından gelir: oturum açıklaması yok, ICE adayı yok, sunucunuzda medya müzakeresi yok.
Tipik zarf yapısı:
{
"event": { "type": "calls", "event": "post" },
"channel_id": "YOUR-CHANNEL-ID",
"calls": [
{
"id": "3EB0C767F26DEECBBE",
"chat_id": "[email protected]",
"status": "ringing",
"from": "[email protected]",
"timestamp": 1721641200,
"group_call": false,
"video_call": true,
"offline_call": false,
"latency": 842
}
]
}
URL'yi kanal ayarlarında belirtin, arama event'lerine abone olun ve bağlı cihazdan test edin. Ortak zarf alanları için gelen webhook format referansına bakın. 200 dışı yanıtlar yeniden denemeyi tetikler.
Arama yaşam döngüsü: initiated → ringing → answered / missed / canceled
Initiated, ringing, answered, missed, canceled: medya olmadan gözlemlenebilir. OpenAPI, CallEvent.status üzerinde beş durumun tamamını listeler. Handler'ınız her POST'u bağımsız bir bildirim değil, durum geçişi olarak ele almalıdır.
Durum: initiated
Arama nesnesi oluşturulduğunda, aranan tarafın cihazı çalmadan önce tetiklenir. CRM satırı ayırmak veya deneme sayaçlarını artırmak için kullanın.
{
"calls": [{
"id": "3EB0A1B2C3D4E5F6",
"chat_id": "[email protected]",
"status": "initiated",
"from": "[email protected]",
"timestamp": 1721641180,
"group_call": false,
"video_call": false,
"offline_call": false,
"latency": 120
}]
}
Durum: ringing
Aranan tarafta aktif çalma sinyali verir. Çalma gecikmesini ölçmek veya temsilciler için ekran açmak için initiated ile eşleştirin.
{
"calls": [{
"id": "3EB0A1B2C3D4E5F6",
"chat_id": "[email protected]",
"status": "ringing",
"from": "[email protected]",
"timestamp": 1721641184,
"group_call": false,
"video_call": false,
"offline_call": false,
"latency": 310
}]
}
Durum: answered
Terminal başarı yolu. Yeniden deneme zamanlayıcılarını durdurun, konuşmayı aktif işaretleyin ve ses yolunu bu webhook dışında ürününüzün kullandığı akışa devredin.
{
"calls": [{
"id": "3EB0A1B2C3D4E5F6",
"chat_id": "[email protected]",
"status": "answered",
"from": "[email protected]",
"timestamp": 1721641192,
"group_call": false,
"video_call": true,
"offline_call": false,
"latency": 905
}]
}
Durum: missed
Zaman aşımından önce cevap yok. Cevapsız arama webhook'ları CRM metin geri dönüşünü tetikler: takip mesajları, bilet oluşturma veya geri arama kuyruğuna ekleme.
{
"calls": [{
"id": "3EB0A1B2C3D4E5F6",
"chat_id": "[email protected]",
"status": "missed",
"from": "[email protected]",
"timestamp": 1721641240,
"group_call": false,
"video_call": false,
"offline_call": true,
"latency": 2100
}]
}
canceled da OpenAPI'de görünür: arayan cevap gelmeden kapattığında veya davet geri çekildiğinde. Eski yardım masası örnekleri bazen yalnızca dört durum listeler; şemaya güvenin ve canceled'ı durum makinenizde ayrı bir terminal dal olarak ele alın.
Grup arama webhook'ları: 1:1 ve grup payload farkları
group_call:true payload yapısını değiştirir — boolean düzeyinde. Aynı status enum geçerlidir, ancak chat_id bir grup JID'sine işaret eder ve yönlendirme mantığı birden fazla temsilciye dağıtılmalıdır.
OpenAPI şemasından türetilmiş örnek (alan değerleri, kanalınız canlı grup araması kaydedene kadar örnektir). Giden grup mesajlaşma kalıpları için WhatsApp Groups API genel bakışına bakın.
{
"calls": [{
"id": "3EB0GROUPCALL001",
"chat_id": "[email protected]",
"status": "ringing",
"from": "[email protected]",
"timestamp": 1721641300,
"group_call": true,
"video_call": true,
"offline_call": false,
"latency": 640
}]
}
| Alan | 1:1 arama (group_call: false) |
Grup araması (group_call: true) |
|---|---|---|
chat_id |
Bireysel JID (@s.whatsapp.net) |
Grup JID (@g.us) |
from |
Arayan kişi ID'si | Arayan kişi ID'si (aynı alan) |
status enum |
initiated → ringing → answered / missed / canceled | Aynı enum; seçici çaldırma birden fazla ringing POST'u üretebilir |
video_call |
Davet için ses veya video | Aynı; Web'de grup videosu aynı bayrağı kullanır |
| CRM yönlendirme | chat_id'yi tek sahibe eşle |
Grup üyeliğini veya paylaşılan kuyruğu eşle; katılımcı başına yinelenen metin geri dönüşlerinden kaçın |
Whapi ve Resmi Cloud API: Durum eşlemesi
Resmi WhatsApp Business API'de Cloud API arama eğitimleri WebRTC bağlantı akışları, SDP değişimi ve süre içeren terminate payload'larına odaklanır. Whapi.Cloud'da medya müzakeresini sunucunuza yüklemeden web oturumu soketleri üzerinden yalnızca sinyal webhook'ları alırsınız.
Whapi ringing ve answered eşler; Meta VoIP webhook modelinde farklı durum adları kullanır. Meta Terminate süreyi açar; Whapi'de terminate event'i yoktur. Faturalandırma ve kapanış mantığını buna göre planlayın. Resmi ve gayri resmi maliyet çerçevesi için resmi API'nin küçük ekipleri neden kaçırdığına bakın.
| Meta Cloud API arama durumu (referans) | Whapi calls.post status |
Notlar |
|---|---|---|
| Connect / RINGING | ringing |
İkisi de aktif çalmayı sinyaller; yalnızca adlandırma farklı |
| ACCEPTED | answered |
Aranan açtı; Whapi'de medya istemci tarafında kalır |
| REJECTED | missed veya canceled |
Whapi enum'unda açık red ile zaman aşımını ayırır |
| Terminate (süre dahil) | mevcut değil | Bugün bu yüzeyde arama sonu webhook'u yok |
| -- | initiated |
Çalmadan önce ek erken sinyal; CRM hazırlığı için kullanışlı |
Yalnızca calls.post'tan Terminate tarzı süre beklemek API kapsam boşluğudur, webhook yanlış yapılandırması değil.
Arama event handler'ı: durum makinesi deseni
Her call.id'yi bir arama durum defteri satırı olarak modelleyin. Yalnızca gelen status kayıtlı sıralamayı geçtiğinde ve timestamp daha yeniyse ilerleyin.
Webhook'lara 200 ile hızlı yanıt verin; arama id ve timestamp ile tekrarları ayıklayın. CRM yan etkilerini asenkron kuyruğa alın. Aynı event-reaksiyon deseni burada da geçerli: al, kalıcı hale getir, tepki ver. Yavaş handler'lar yeniden deneme ve yinelenen satırlara yol açar.
// Returning 500 here retries the webhook and can double-send CRM text-backs
app.post('/webhooks/whapi', express.json(), async (req, res) => {
res.sendStatus(200); // ACK first; process after response
for (const call of req.body.calls ?? []) {
const key = `${call.id}:${call.status}:${call.timestamp}`;
if (await seen(key)) continue;
const prev = await db.getCall(call.id);
const next = rank(call.status); // initiated<ringing<answered|missed|canceled
if (prev && (next < prev.rank || call.timestamp < prev.timestamp)) continue;
await db.upsertCall({ ...call, rank: next });
if (call.status === 'missed') {
await queueTextBack(call.chat_id, call.from);
}
}
});
Geçiş koruması için sözde kod:
STATE ranks: initiated=1, ringing=2, answered=3, missed=3, canceled=3
ON calls.post:
ACK 200 immediately
FOR each call in payload:
IF dedupe_key(id, status, timestamp) exists: SKIP
IF stored.rank > new.rank: SKIP
IF stored.timestamp > call.timestamp: SKIP
UPSERT call row
IF status == missed AND policy allows: ENQUEUE text-back job
IF status == answered: CANCEL pending retry timers
200 ACK'ten önce işlem yapmak, yeniden denemede cevapsız arama yan etkilerini çoğaltır. Whapi web oturumu soketleri kullandığından kanallar arama event'lerini otomatikleştirmek için yeterince kararlı kalır. Tam webhook başlangıcı için Node.js WhatsApp bot eğitimine bakın.
calls.post size ne söyleyemez
Arama süresi bu webhook yüzeyinde mevcut değildir. Whapi desteği, hat üzerindeki saniyeleri hesaplamak için terminate veya call-end event'i olmadığını doğrular.
Meta Terminate süreyi açar; Whapi'de terminate event'i yoktur. Konuşma süresini answered timestamp'lerinden çıkarmayın. Meta App Dashboard sağlama ve SDP hata ayıklama Cloud API VoIP eğitimlerine aittir, Whapi kanal ayarlarına değil.
Payload alanları: video_call, offline_call, latency
video_call, offline_call, latency teslimat bağlamını açıklar, medyayı değil. Kayıt API'si veya akış metadata'sının yerini tutmazlar.
video_call ses ve video davetlerini işaretler; offline_call çevrimdışı teslimatı; latency sinyal milisaniyelerini raporlar (RTP kalitesi değil).
Temsilci geri aramalarını önceliklendirirken üç bayrağı status ile birleştirin: yüksek latency ve offline_call: true olan cevapsız bir video_call, aranan tarafın Web'de çalmayı hiç görmemiş olabileceğini gösterir.
Sırada ne var: Whapi'de arama başlatma
Bugün aramaları bağlı WhatsApp istemcilerinden gözlemlersiniz; programlı giden arama ve call-end webhook'ları yakın vadeli yol haritasındadır.
POST /calls ve call-end webhook'ları yol haritasında. create-call endpoint'i event oluşturma için zaten mevcut; grup Web araması olgunlaştıkça daha zengin başlatma ve sonlandırma yüzeyleri bekleyin.
# POST https://gate.whapi.cloud/calls - create call event (start_time required today)
curl -X POST "https://gate.whapi.cloud/calls" \
-H "Authorization: Bearer $WHAPI_TOKEN" \
-H "Content-Type: application/json" \
-d '{"start_time":"1721641200"}'
Whapi, Web istemcileri grup ses ve video kazandıkça arama API'lerini aktif olarak genişletiyor. calls.post'a abone olun, durum defterini kurun; terminate event'leri geldiğinde süreyi ekleyin. Sürümleri ürün changelog'unda takip edin. Gözlemlenebilir yaşam döngüsünün tamamı 1:1 ve grup aramaları için düz JSON olarak zaten geliyor; süre bir sonraki webhook türünü bekliyor.









