Hipcall Geliştirici Bilgi Bankası / Webkancası

ASP.NET Core İle Hipcall Webhook Alıcısı Oluşturma

ASP.NET Core kullanarak Hipcall webhook alıcısı geliştirin. Çağrıları tekilleştirerek veritabanınıza kaydedin, ses arşivinizi oluşturun ve gece mutabakatı ile veri kaybını önleyin.

Güncellendi October 11, 2026
Oku 8 dk
Bu sayfada

Genel bakış

Çağrı kayıtlarını API üzerinden periyodik olarak çekmek (polling) kota tüketir ve veriyi gecikmeli almanıza neden olur.

Webhook'lar olayları uygulamanıza anında iletir. Bir çağrı başladığında, bağlandığında veya bittiğinde Hipcall santrali uygulamanıza bir HTTP POST gönderir. Çağrı bittiği an görüşme süresi ve ses kaydı bağlantısı doğrudan veritabanınıza ulaşır.

Üretim ortamına hazır bir webhook alıcısının dört görevi vardır:

  • Zaman aşımını önlemek için 50 milisaniyenin altında HTTP 200 dönmek.
  • Uç noktayı gizli bir rota anahtarıyla korumak.
  • Aynı çağrının farklı olaylarını ve mutabakat verilerini UUID ile tekilleştirmek.
  • Sunucu kesintilerini telafi etmek için gece mutabakatı yapmak.

Bu sayfada Hipcall panelinde webhook ayarlamayı, gerçek istekleri incelemeyi ve ASP.NET Core Minimal API ile bir alıcı yazmayı anlatıyoruz.

Başlamadan önce

Şunlara ihtiyacınız var:

  • .NET 8 SDK (dotnet --version 8.0 veya üstü olmalı).
  • Dışarıdan erişilebilir bir HTTPS adresi. Yerel ortamda port 5080'i dışarı açmak için ngrok kullanın:
    ngrok http 5080
  • Hipcall panelinde entegrasyon ekleme yetkisi.
  • Test için çevrimiçi bir Hipcall uygulaması (web veya masaüstü).

Webhook kurulumu

Webhook'u Hipcall panelinden oluşturun:

  1. Ayarlar > Entegrasyonlar > Kataloğa Göz At bölümüne gidin.
  2. Web kancası (Webhook) seçeneğine tıklayın.
  3. Detayları girin:
    • Ad: Üretim CDR Alıcısı gibi bir isim verin.
    • URL: İçinde gizli bir yol bulunan HTTPS adresinizi yazın: https://your-server.example.com/hipcall/events/whsec_live_xxxxxxxxxxxxxxxx.
    • Olaylar: call_init, call_bridged ve call_hangup seçeneklerini işaretleyin.
  4. Kayıtlar sekmesini açın. Hata Ayıklama Modu'nu etkinleştirdiğinizde sistem iki saat boyunca istek gövdelerini ve HTTP yanıtlarını loglar.

Gövde yapısı ve curl testi

Hipcall, istekleri application/json olarak gönderir. Paket, bir event anahtarı ve çağrı detaylarını barındıran data nesnesi içerir.

Terminalinizde aşağıdaki curl komutunu çalıştırarak yerel alıcınıza sahte bir Hipcall call_init olayı gönderebilirsiniz:

curl -X POST http://localhost:5080/hipcall/events/whsec_live_xxxxxxxxxxxxxxxx \
-H "Content-Type: application/json" \
-d '{
"data": {
"credited": null,
"team_touch_at": null,
"first_touch_duration": null,
"contact_id": null,
"callee_id": null,
"answered_at": null,
"voicemail_url": null,
"caller_number": "+90850XXXXXXX",
"missing_call_reason": null,
"call_duration": null,
"callback_time": null,
"call_flow": [
{
"action": "init",
"detail": {
"id": null,
"type": "contact"
},
"timestamp": 1790691203
}
],
"direction": "outbound",
"callee_number": "+90530XXXXXXX",
"voicemail_id": null,
"callback_user_id": null,
"callee_type": "contact",
"ended_at": null,
"missing_call": null,
"channel_type": "number",
"callback_cdr_uuid": null,
"voicemail_type": null,
"caller_id": null,
"started_at": "2026-09-29T14:13:23Z",
"bridged_at": null,
"channel_id": 942,
"caller_type": null,
"user_id": 4200,
"hangup_by": null,
"uuid": "410c92c5-...masked...",
"record_url": null,
"number_id": 942,
"company_id": 80719
},
"event": "call_init"
}'

İstek başlıklarının incelenmesi

Gelen HTTP başlıkları şu şekildedir:

Host: your-server.example.com
User-Agent: mint/1.9.0
Content-Type: application/json
Accept-Encoding: gzip
X-Forwarded-For: 31.192.211.2
X-Forwarded-Proto: https

Hipcall webhook istekleri X-Signature gibi HMAC imza başlıkları içermez.

Olayların taşıdığı veriler

Tek bir çağrı birden fazla olay tetikler.

Olay Tetiklenme Anı Öne Çıkan Alanlar Kullanım Amacı
call_init Santralde çağrı başladığında uuid, direction, caller_number, started_at Oturum başlangıcını tespit etme.
call_bridged Temsilci bağlandığında uuid, direction, user_id, call_flow Temsilcinin katıldığını doğrulama.
call_hangup Çağrı kapandığında uuid, call_duration, hangup_by, record_url Görüşme özeti ve ses arşivi oluşturma.

Tıklayıp arama (Click-to-Call) akışı

API üzerinden arama başlatıldığında Hipcall telefonu temsilciyi otomatik yanıtlar. Temsilci hemen santrale bağlandığı için, müşteri tarafı çalarken call_init ve call_bridged olayları peş peşe ulaşır.

Ses kaydı bağlantısı

call_hangup olayındaki data.record_url, 7 gün geçerli geçici bir AWS S3 bağlantısıdır (X-Amz-Expires=604800).

Ses dosyasını webhook geldiği anda arka planda indirin ve kurumunuzun kendi depolama alanına kaydedin. Geçici bağlantıyı veritabanına yazmayın.

Güvenilir mimari tasarımı

Üretim ortamı için şu dört ilkeyi uygulayın:

flowchart TD
    A["Gelen Webhook İsteği"] --> B{"Gizli URL Şifresini Doğrula"}
    B -- "Geçersiz" --> C["401 Unauthorized"]
    B -- "Geçerli" --> D["Gövdeyi Ayrıştır ve UUID Kontrolü Yap"]
    D --> E["Anında HTTP 200 OK Dön (< 50 ms)"]

    subgraph BG ["Arka Plan Asenkron İşleme"]
        F["Veritabanına Tekil Kayıt Yaz (Upsert)"]
        F --> G{"record_url Var mı?"}
        G -- "Evet" --> H["MP3 Dosyasını İndir"]
        G -- "Hayır" --> I["Tamamlandı"]
        H --> I
    end

    D -.->|Asenkron Görev| F

    subgraph REC ["Gece Mutabakat Görevi"]
        J["Zamanlanmış Görev: Gece 02:00"] --> K["Hipcall REST API: GET /api/v3/calls"]
        K --> L["UUID Küme Farkını Hesapla"]
        L --> M["Kaçan Çağrıları ve Sesleri Arşive Ekle"]
    end

1. Hızlı cevap verin, ağır işleri arka plana devredin

Hipcall yanıtı 15 saniye içinde bekler. Alıcı ses kaydı indirmek için beklerse bağlantı zaman aşımına uğrar.

İşlem sırası:

  1. Gizli anahtarı doğrulayın.
  2. JSON gövdesini çözün.
  3. Veriyi kuyruğa alın.
  4. Anında HTTP 200 OK dönün (50 ms altı).
  5. Ses indirme ve veritabanı işlemlerini arka planda yapın.

2. Tekilleştirme (Idempotency)

Aynı çağrıya ait call_init, call_bridged ve call_hangup olayları farklı zamanlarda aynı uuid'yi taşıyarak ulaşır. Sisteminiz bunları yeni kayıt olarak değil, mevcut kaydın güncellemeleri olarak işlemelidir. Ayrıca, gece mutabakatı (nightly reconciliation) sırasında API'den günün tüm çağrılarını çektiğinizde, webhook ile zaten kaydedilmiş çağrılar da gelecektir. Veri kirliliğini önlemek için:

  • Tekilleştirme anahtarı olarak data.uuid kullanın.
  • Zaman damgası veya telefon numarası üzerinden tekilleştirme yapmayın.
  • Gelen kayıtlarla mevcut kaydı güncelleyin (upsert).

3. Gece mutabakatı

Yalnızca webhook kullanan bir sistemde sunucu yeniden başlatmaları sırasında veri kaçabilir.

Eksiksiz bir arşiv için:

  • Her gece çalışan bir görev oluşturun.
  • API'den günün çağrılarını çekin:
    GET /api/v3/calls?started_at[gte]=...&started_at[lte]=...&limit=100
  • API'deki UUID'ler ile kendi veritabanınızı karşılaştırın.
  • Eksik çağrıları ve ses kayıtlarını API üzerinden tamamlayın.

4. İmzasız uç noktaları koruma

HMAC başlığı olmadığı için alıcı adresinizi korumanız gerekir:

  1. Gizli URL yolu: URL'nizde gizli bir anahtar bulundurun (/hipcall/events/whsec_live_...). Anahtar yoksa HTTP 401 Unauthorized dönün.
  2. IP beyaz listesi: Güvenlik duvarınızda (Nginx, Cloudflare) sadece Hipcall çıkış IP adresine (31.192.211.2) izin verin.

Minimal API alıcı örneği

Aşağıdaki ASP.NET Core Minimal API uç noktası, JSON gövdesini ayrıştırır, gizli anahtarı doğrular, işlemi arka plana devredip santrale derhal 200 OK döner.

using System;
using System.Text.Json;
using System.Threading.Tasks;
using Microsoft.AspNetCore.Builder;
using Microsoft.AspNetCore.Http;
using Microsoft.Extensions.DependencyInjection;
var builder = WebApplication.CreateBuilder(args);
builder.WebHost.ConfigureKestrel(options => options.ListenAnyIP(5080));
var app = builder.Build();
var expectedSecret = Environment.GetEnvironmentVariable("HIPCALL_WEBHOOK_SECRET")
?? throw new InvalidOperationException("HIPCALL_WEBHOOK_SECRET ortam değişkeni bulunamadı.");
var jsonOptions = new JsonSerializerOptions
{
PropertyNamingPolicy = JsonNamingPolicy.SnakeCaseLower,
PropertyNameCaseInsensitive = true
};
app.MapPost("/hipcall/events/{secret?}", async (string? secret, HttpRequest request) =>
{
if (string.IsNullOrEmpty(secret) || !string.Equals(secret, expectedSecret, StringComparison.Ordinal))
{
return Results.Unauthorized();
}
HipcallWebhookPayload? payload;
try
{
payload = await JsonSerializer.DeserializeAsync<HipcallWebhookPayload>(request.Body, jsonOptions);
}
catch
{
return Results.Ok();
}
if (payload?.Data?.Uuid != null)
{
// Veritabanı ve ses indirme işlemlerini arka plana devret
_ = Task.Run(() => ProcessWebhookAsync(payload.Event, payload.Data.Uuid));
}
// Bekletmeden anında HTTP 200 OK dön
return Results.Ok();
});
app.Run();
async Task ProcessWebhookAsync(string? eventName, string uuid)
{
// Tekilleştirme (Idempotency) ve ses indirme kodları buraya gelir
Console.WriteLine($"Arka planda işleniyor: {eventName} - {uuid}");
await Task.CompletedTask;
}
public class HipcallWebhookPayload
{
public string? Event { get; set; }
public CallDataPayload? Data { get; set; }
}
public class CallDataPayload
{
public string? Uuid { get; set; }
public string? Direction { get; set; }
public string? CallerNumber { get; set; }
public string? CalleeNumber { get; set; }
public int? CallDuration { get; set; }
public string? RecordUrl { get; set; }
public string? HangupBy { get; set; }
public string? VoicemailId { get; set; }
public DateTime? StartedAt { get; set; }
public DateTime? AnsweredAt { get; set; }
public DateTime? BridgedAt { get; set; }
public DateTime? EndedAt { get; set; }
}

Hata aldığınızda

1. HTTP 500 yanıtı

Sunucunuz 500 Internal Server Error döndürdüğünde:

  • Telefon görüşmesi etkilenmez. Webhook dağıtımı ile telefon trafiği bağımsızdır.
  • Hipcall hatayı loglara yazar.
  • Hipcall istekleri tekrar denemez (at-most-once). Bu yüzden 200 dönmek ve kaçan kayıtları gece tamamlamak zorunludur.

2. Zaman aşımı

Alıcınız 15 saniyeden geç yanıt verirse Hipcall bağlantıyı keser ve olayı başarısız sayar.

3. Kırık durumu

Alıcınız bir saat içinde 4 kez başarısız yanıt (200 dışı kod veya 15 saniye zaman aşımı) verirse:

  • Hipcall entegrasyonu Kırık (Broken) duruma alır.
  • Siz tekrar Aktif konuma getirene kadar yeni webhook göndermez.
  • Düzeltmek için paneli açın, durumu Aktif yapıp kaydedin.

Daha fazla bilgi için Hipcall API Referansı sayfasına bakın. Bu kurallar Webkancaları v1 için geçerlidir.

Parametre listesi

Çağrı olaylarında data içindeki temel alanlar:

Parametre Tip Örnek Açıklama
uuid string "9a266251-d2a3-44fc-b422-9486ddf880c7" Çağrının tekil kimliği.
direction string "outbound" "inbound" veya "outbound".
caller_number string "+90850XXXXXXX" Arayan numara.
callee_number string "+90530XXXXXXX" Aranan numara.
call_duration integer 14 Toplam konuşma süresi (saniye).
missing_call boolean false Yanıtsız gelen çağrılarda true.
hangup_by string "contact" Kapatan taraf ("user", "contact", "system").
record_url string/null "https://storage.hipcall.com.tr/..." AWS S3 ses indirme bağlantısı.
started_at string "2026-09-21T10:37:07Z" Çağrının başlama anı (UTC).
answered_at string/null "2026-09-21T10:37:07Z" Çağrının yanıtlanma anı (UTC).
ended_at string/null "2026-09-21T10:37:21Z" Çağrının kapanma anı (UTC).

Sonraki adımlar

  • HTTP alıcısı ile veritabanı arasına RabbitMQ ekleyin.
  • PostgreSQL kullanarak uuid alanını eşsiz (unique) ayarlayın.
  • Gece mutabakatını GET /api/v3/calls ile otomatikleştirin.
  • Sorularınızı Hipcall Topluluk platformunda paylaşın.

Bu makale yardımcı oldu mu?

Hâlâ yardıma mı ihtiyacınız var?

Aradığınızı bulamıyor musunuz? Bize ulaşın, yardımcı olalım.