Self-hosted · .NET 10 · SQL Server

WhatsApp gönderimi için
kurum içi API geçidi

WApi, WhatsApp Business API ile aynı yüzeyi sunan, ancak kendi sunucunuzda çalışan bir mesajlaşma ağ geçididir. REST üzerinden mesaj gönderir, Webhook üzerinden gelen mesaj ve durum güncellemelerini sizin uygulamanıza iletir, SignalR üzerinden canlı olay akışı yayınlar. SaaS aboneliği, satır başı ücretlendirme veya kapalı kara kutu yoktur — kaynak kodu sizdedir, veriler sizin SQL Server'ınızda kalır, kimlik doğrulama anahtarları yalnızca sizde durur.

Framework
.NET 10
Veritabanı
SQL Server 2019+
Kimlik Doğrulama
X-API-Key + SHA-256
Engine
Baileys (Multi-Device)

Neden WApi?

Standart bir HTTP kütüphanesi konuşan her ortam, WApi ile dakikalar içinde entegre olabilir. Aşağıdaki yetenekler hazır kurulumda etkindir; ek lisans, ek ücret veya ek modül gerektirmezler.

REST + JSON, Standart HTTP

Tüm uç noktalar /api altında, JSON gövde-yanıt, standart durum kodları. C#, VB.NET, Java, PHP, Python, Node, Go, hatta curl ile çalışır. Swagger UI ile uçları kod yazmadan keşfedebilir, Try-it-out üzerinden anlık deneme yapabilirsiniz.

HMAC İmzalı Webhook

Gelen mesajları, mesaj status değişikliklerini (sent/delivered/read) ve session olaylarını (qr, ready, disconnected) sizin verdiğiniz URL'e POST eder. Her istek X-WApi-Signature başlığında ham gövdenin HMAC-SHA256 imzasını taşır. Başarısız teslim girişimleri yapılandırılabilir sayıda yeniden denenir.

SignalR Canlı Olay Akışı

/api/events hub'ı üzerinden, browser veya .NET istemcileriniz oturuma abone olur ve QR gösterimi, mesaj akışı, status değişikliği gibi olayları gerçek zamanlı izler. Polling gerektirmez.

Toplu Kampanya, Throttling ile

send-bulk uç noktası ile tek istek üzerinden yüzlerce alıcıya gönderim yapın. Her alıcı için özel metin verilebilir, gönderim aralığı (intervalMs) milisaniye cinsinden ayarlanabilir. Süreç boyunca sent, failed ve status sayaçlarını batch dökümünden izleyin.

Rol Tabanlı API Anahtarları

Üç düzey rol — Admin (her şey), Operator (mesaj + webhook yönetimi), Viewer (yalnızca okuma). Her anahtar için isteğe bağlı CIDR allowlist ve oturum-bazlı kısıtlama. Anahtarlar veritabanında SHA-256 hash olarak saklanır; ham değer yalnızca yaratma anında bir kez gösterilir.

SQL Server Yerli, EF Core'suz

Veri katmanı Microsoft.Data.SqlClient üzerine kurulu ince bir SqlHelper ile çalışır — ORM yoktur. Tablolar boot anında idempotent CREATE TABLE ile kurulur. Stored procedure, table-valued parameter ve hand-tuned query'lerle istediğiniz noktayı optimize edebilirsiniz.

Çoklu Oturum, Çoklu Numara

Her WhatsApp hesabı bir session'dır. Birden fazla numarayı tek bir WApi kurulumu içinden yönetin. Her oturumun kendi mesaj geçmişi, webhook yapılandırması, durum bilgisi ve auth-state'i vardır.

Audit Log, İz Sürülebilir

Her API çağrısı — kim, hangi rolle, hangi IP'den, ne yaptı, hangi sonuç — dbo.audit_logs tablosuna yazılır. GET /api/audit ucu üzerinden filtrelenebilir.

Mimari ve Çalışma Yöntemi

WApi katmanlı bir tasarıma sahiptir. Her katmanın bir tek sorumluluğu vardır ve katmanlar yalın arayüzler üzerinden konuşur. Aşağıdaki şema istemci isteğinin uçtan uca yolunu gösterir.

İstemci C# / VB.NET / Java / curl / SDK
HTTPS + X-API-Key
Caddy / Nginx TLS sonlandırma
Forwarded headers
WApi.Api (Kestrel) Controllers · ApiKeyAuthHandler · Swagger
SignalR Hub · Webhook Dispatcher
WApi.Infrastructure SqlHelper · Repositories · Engine seçici
SQL Server sessions · messages · webhooks
api_keys · audit_logs
IWhatsAppEngine null (stub) · node-bridge (Baileys)

Katman Sorumlulukları

WApi.Domain
Saf POCO'lar, enum'lar, IWhatsAppEngine arayüzü ve engine model'leri. Bağımlılığı yok.
WApi.Application
DTO record'ları (SendTextRequest, WebhookDto, vb.) ve Entity ↔ DTO eşleyiciler. Validation attribute'ları burada.
WApi.Infrastructure
SqlHelper (ADO.NET wrapper), per-entity repository'ler, ApiKeyAuthHandler, WebhookDispatcher, ve aktif IWhatsAppEngine uygulamasının kaydı.
WApi.Api
ASP.NET Core Controllers, Swagger pipeline, SignalR hub, UseStaticFiles ile bu sayfa, Forwarded Headers, Windows Service hosting.

Engine Katmanı

WhatsApp protokolü IWhatsAppEngine arkasında soyutlanmıştır. Konfigürasyon (Engine:Type) ile aşağıdaki uygulamalar arasında seçim yapılır:

null varsayılan

İçeriden bir stub. Tüm engine çağrılarına sahte yanıt verir, gönderilen mesajlar dbo.messages'a yazılır ve NULL- önekli senkron sahte mesaj id'leri döner. Gerçek WhatsApp ağına bağlanmaz. Geliştirme, entegrasyon testi ve demo için idealdir.

node-bridge üretim

WApi'nin C# tarafı, aynı sunucuda 127.0.0.1'de çalışan küçük bir Node.js yan-sürecine HTTP üzerinden komut iletir. Yan-süreç @whiskeysockets/baileys kütüphanesini kullanarak gerçek WhatsApp Multi-Device protokolüne bağlanır. Yan-süreç paylaşılan bir bearer (X-Bridge-Token) ile korunur ve loopback dışına dinlemez.

İstek Yaşam Döngüsü

  1. İstemci X-API-Key başlığıyla HTTPS isteği gönderir.
  2. Caddy TLS'i sonlandırır, X-Forwarded-For ve -Proto başlıklarını ekler, isteği 127.0.0.1:2785'e iletir.
  3. Kestrel isteği alır; UseForwardedHeaders ile gerçek istemci IP'si geri kazanılır.
  4. ApiKeyAuthHandler başlığı trim eder, SHA-256 hash'ler, dbo.api_keys'te eşleşme arar. Aktif mi, süresi geçmiş mi, CIDR allowlist'e uygun mu kontrol eder. ClaimsPrincipal oluşturup pipeline'a verir.
  5. Authorization Policy rolün ucu çağırmaya yetkili olup olmadığını doğrular (AdminOnly / OperatorOrAdmin / AnyRole).
  6. Controller validation çalıştırır, IWhatsAppEngine'i çağırır, sonucu dbo.messages'a yazar ve istemciye döner.
  7. WebhookDispatcher (varsa) ilgili event'i o oturumun aktif webhook'larına HMAC-SHA256 imzalı POST ile dağıtır.
  8. SignalR hub aynı event'i o oturuma abone olan tüm canlı istemcilere broadcast eder.

Entegrasyon Kılavuzu

Bir uygulamanın WApi ile uçtan uca konuşmaya başlaması üç adımdır: API anahtarı al, oturum aç, mesaj gönder. Aşağıdaki örnekler tipik bir entegrasyonun her adımını yapay YOUR_API_KEY değişkeniyle gösterir.

  1. 1 · API anahtarı oluşturun

    İlk kurulumda appsettings.json'daki Security:MasterKey değeri ilk Admin anahtarınızdır; sonraki anahtarları bununla yaratırsınız. Operasyonda günlük kullanım için Master yerine rolü uygun (Operator/Viewer) iş-anahtarları kullanılması önerilir.

    curl -X POST https://wapi.erp.tr/api/auth/api-keys \
         -H "X-API-Key: $MASTER_KEY" \
         -H "Content-Type: application/json" \
         -d '{ "name": "billing-app-prod", "role": 1, "allowedIps": "203.0.113.0/24" }'
    
    # Yanıt: oluşturulan apiKey **bir kez** ham olarak döner. Sakla.
    # { "dto": { ... }, "apiKey": "wapi_..." }

    Roller: 0 = Viewer, 1 = Operator, 2 = Admin.

  2. 2 · Bir oturum açın ve telefonu bağlayın

    Her WhatsApp numarası ayrı bir oturum (session) olarak tutulur. node-bridge engine ile, oturum başlatıldığında bir QR kodu üretilir; telefon WhatsApp uygulamasından Ayarlar → Bağlı Cihazlar → Cihaz Bağla ile bu QR'i tarayarak eşleşir. Eşleşme sonrası auth state diskte saklanır; servis yeniden başlasa bile rescan gerekmez.

    # Oturum oluştur
    curl -X POST https://wapi.erp.tr/api/sessions \
         -H "X-API-Key: $YOUR_API_KEY" -H "Content-Type: application/json" \
         -d '{ "name": "satis-departmani", "proxyUrl": null, "proxyType": null }'
    
    # Yanıttaki id'yi sakla; bundan sonra her uçta o id geçecek.
    SESSION_ID=...
    
    # Oturumu başlat (engine'i ayağa kaldırır; QR üretir)
    curl -X POST https://wapi.erp.tr/api/sessions/$SESSION_ID/start \
         -H "X-API-Key: $YOUR_API_KEY"
    
    # QR'i çek — base64 PNG olarak döner (img src'ye doğrudan verilebilir)
    curl https://wapi.erp.tr/api/sessions/$SESSION_ID/qr \
         -H "X-API-Key: $YOUR_API_KEY"
    # { "sessionId": "...", "qrCode": "data:image/png;base64,iVBORw...", "status": 0 }
  3. 3 · Mesaj gönderin

    Oturum connected duruma geçtikten sonra herhangi bir mesaj uç noktası çağrılabilir. Aşağıda her dilde, gerçek üretim koduna yakın bir minimal entegrasyon vardır.

    // .NET 8+ — HttpClient ile minimal istemci
    using System.Net.Http.Headers;
    using System.Net.Http.Json;
    
    var http = new HttpClient { BaseAddress = new Uri("https://wapi.erp.tr") };
    http.DefaultRequestHeaders.Add("X-API-Key", "YOUR_API_KEY");
    
    // Mesaj gönder
    var payload = new { chatId = "905321234567@s.whatsapp.net", text = "Merhaba!" };
    var res = await http.PostAsJsonAsync($"/api/sessions/{sessionId}/messages/send-text", payload);
    res.EnsureSuccessStatusCode();
    var msg = await res.Content.ReadFromJsonAsync<MessageDto>();
    Console.WriteLine($"WApi message id: {msg!.Id}  WhatsApp id: {msg.WaMessageId}");
    
    // Hata kontrolü
    if (msg.Status == MessageStatus.Failed)
        throw new Exception("Mesaj engine tarafından kabul edilmedi.");
    
    public record MessageDto(Guid Id, Guid SessionId, string? WaMessageId,
        string ChatId, string? Body, int Type, int Direction, int Status,
        long Timestamp, DateTime CreatedAt);
    
    public enum MessageStatus { Pending = 0, Sent = 1, Delivered = 2, Read = 3, Failed = 4 }
    

Kimlik Doğrulama ve Yetkilendirme

WApi tek bir kimlik doğrulama mekanizması kullanır: HTTP başlığındaki anahtar. Anahtar kayıt ve doğrulamasının her detayı aşağıda açıklanmıştır.

Anahtar formatı ve gönderim

Her API anahtarı wapi_ öneki + 64 karakter hex (32 bayt rastgele) olarak üretilir. Tüm istekler anahtarı X-API-Key başlığında taşır:

GET /api/sessions HTTP/1.1
Host: wapi.erp.tr
X-API-Key: wapi_xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
Accept: application/json

Saklama

Veritabanında yalnızca SHA-256 hash + ilk 8 karakter (prefix, gösterim için) tutulur. Ham anahtar asla saklanmaz. Anahtar oluşturulduğu anda POST /api/auth/api-keys'in yanıtında bir kez döner; kaybedilirse yenisi yaratılmalı, eski iptal edilmelidir (POST /api/auth/api-keys/{id}/revoke).

Roller

RolDeğerErişim
Viewer 0Tüm okuma uçları: GET sessions, messages, groups, contacts, stats, audit (kendi yetkisindekiler).
Operator 1Viewer + oturum başlat/durdur, mesaj gönder (send-text/-image/-video/-audio/-document/-sticker/-location), bulk kampanya, webhook ekle/güncelle/sil.
Admin 2Operator + API anahtar yönetimi, audit log, infra uçları.

İsteğe bağlı kısıtlamalar

  • CIDR allowlistAllowedIps alanına virgülle ayrılmış CIDR'lar yazılır (örn. "203.0.113.0/24,198.51.100.42"). Başka IP'den çağrı 401 alır.
  • Oturum kısıtlamasıAllowedSessions alanına bir GUID JSON dizisi verilebilir; anahtar yalnızca o oturumlara erişebilir. Multi-tenant senaryolar için.
  • Son kullanmaExpiresAt UTC tarih; sonrasında anahtar otomatik 401 verir.

Anahtar yönetimi uçları (Admin)

  • GET /api/auth/api-keys — Tüm anahtarları listele (prefix + meta; ham anahtar dönmez).
  • POST /api/auth/api-keys — Yeni anahtar yarat (ham anahtar yanıt gövdesinde bir kez döner).
  • PUT /api/auth/api-keys/{id} — Rol, allowlist, aktiflik, expiry güncelle.
  • POST /api/auth/api-keys/{id}/revoke — Anahtarı iptal et.
  • DELETE /api/auth/api-keys/{id} — Anahtarı kalıcı sil.

API Referansı

Tüm uçlar /api altındadır ve (anonim olarak işaretlenenler dışında) X-API-Key ister. Bütün şemalar ve örnek istek/yanıt'lar Swagger UI'da yer alır: /api/docs.

Sağlık & Kimlik

MethodYolRolAçıklama
GET /api/health anonim Sağlık + DB bağlantısı kontrolü
GET /api/health/live anonim Liveness probe (proseste sağlıklı?)
GET /api/health/ready anonim Readiness probe (DB ulaşılabilir?)
POST /api/auth/validate anonim Verilen anahtarın geçerliliğini, adını, rolünü döner

Oturumlar

MethodYolRolAçıklama
GET /api/sessions Viewer+ Oturumları listele
POST /api/sessions Operator Yeni oturum oluştur
GET /api/sessions/{id} Viewer+ Oturum detayı
DELETE /api/sessions/{id} Operator Oturumu sil (auth state dahil)
POST /api/sessions/{id}/start Operator Engine'i ayağa kaldır (QR üretir)
POST /api/sessions/{id}/stop Operator Engine'i durdur
GET /api/sessions/{id}/qr Operator QR kodu (base64 PNG)
GET /api/sessions/{id}/groups Viewer+ Katıldığı gruplar
GET /api/sessions/{id}/contacts Viewer+ Kişi listesi

Mesajlar

MethodYolRolAçıklama
GET /api/sessions/{id}/messages Viewer+ Mesaj geçmişi (skip / take)
POST /api/sessions/{id}/messages/send-text Operator Metin
POST /api/sessions/{id}/messages/send-image Operator Görsel (caption ile)
POST /api/sessions/{id}/messages/send-video Operator Video
POST /api/sessions/{id}/messages/send-audio Operator Ses
POST /api/sessions/{id}/messages/send-document Operator Doküman
POST /api/sessions/{id}/messages/send-sticker Operator Sticker
POST /api/sessions/{id}/messages/send-location Operator Konum (lat/lng/label)
POST /api/sessions/{id}/messages/send-bulk Operator Toplu kampanya
POST /api/sessions/{id}/messages/react Operator Mesaja emoji tepkisi
POST /api/sessions/{id}/messages/delete Operator Mesajı sil
GET /api/sessions/{id}/messages/batch/{batchId} Viewer+ Batch durumu
POST /api/sessions/{id}/messages/batch/{batchId}/cancelOperator Batch iptal

Webhook'lar, İstatistik, Audit

MethodYolRolAçıklama
GET /api/sessions/{id}/webhooks Viewer+ Webhook listesi
POST /api/sessions/{id}/webhooks Operator Webhook ekle
PUT /api/sessions/{id}/webhooks/{wid} Operator Güncelle
DELETE /api/sessions/{id}/webhooks/{wid} Operator Sil
POST /api/sessions/{id}/webhooks/{wid}/test Operator Test isteği gönder
GET /api/stats/overview Viewer+ Toplam mesaj/oturum sayıları
GET /api/stats/messages Viewer+ Zaman bazlı mesaj istatistikleri
GET /api/stats/sessions/{id} Viewer+ Oturum bazlı istatistik
GET /api/audit Admin Audit log (kim, ne, ne zaman)
GET /api/infra Admin Infra/engine durumu
WS /api/events Viewer+ SignalR canlı olay hub'ı

Webhook Entegrasyonu

Bir webhook eklediğinizde, WApi o oturum üzerinde gerçekleşen olayları sizin verdiğiniz URL'e HTTP POST olarak iletir. Aşağıdaki olay tipleri varsayılan olarak yayımlanır.

Olay tipleri

OlayTetiklendiğindeTipik payload
message.in Yeni bir gelen mesaj alındığında { chatId, from, body, type, timestamp, waMessageId }
message.out Bir giden mesaj engine'e teslim edildiğinde { chatId, body, type, waMessageId }
message.ack Mesaj durumu değiştiğinde (sent/delivered/read) { waMessageId, status }
session.qr Yeni QR üretildiğinde { qrCode }
session.status Oturum durumu değiştiğinde { status, phone, pushName }

İstek formatı

Her webhook çağrısı aşağıdaki yapıda gelir:

POST /your/webhook/path HTTP/1.1
Host: your-app.example.com
Content-Type: application/json
X-WApi-Event: message.in
X-WApi-Session: 3b358e5f-5fc4-4198-8457-c1983baad23a
X-WApi-Timestamp: 1779186278776
X-WApi-Signature: sha256=<hex>
User-Agent: WApi/1.1 (+https://wapi.erp.tr)

{
  "event": "message.in",
  "sessionId": "3b358e5f-5fc4-4198-8457-c1983baad23a",
  "at": "2026-05-19T10:24:38.7757623Z",
  "payload": {
    "chatId": "905321234567@s.whatsapp.net",
    "from": "905321234567@s.whatsapp.net",
    "body": "Merhaba!",
    "type": 0,
    "timestamp": 1779186278776,
    "waMessageId": "3EB09535AA6578CE1FC528"
  }
}

İmza doğrulaması

İmza X-WApi-Signature başlığında sha256=<hex> formatındadır. Hesaplama: HMAC-SHA256( secret = webhook.Secret, message = ham_istek_gövdesi ). Doğrulama örneği:

// ASP.NET Core (örnek)
[HttpPost("wapi/incoming")]
public async Task<IActionResult> Incoming()
{
    using var reader = new StreamReader(Request.Body);
    var raw = await reader.ReadToEndAsync();

    var sig = Request.Headers["X-WApi-Signature"].ToString();
    if (!sig.StartsWith("sha256=")) return Unauthorized();

    var expected = Convert.ToHexString(
        new HMACSHA256(Encoding.UTF8.GetBytes("shared-hmac-secret"))
            .ComputeHash(Encoding.UTF8.GetBytes(raw))
    ).ToLowerInvariant();

    if (!CryptographicOperations.FixedTimeEquals(
            Encoding.ASCII.GetBytes(sig[7..]),
            Encoding.ASCII.GetBytes(expected)))
        return Unauthorized();

    var evt = JsonSerializer.Deserialize<WebhookEnvelope>(raw);
    // ... işle
    return Ok();
}

Yeniden deneme ve idempotency

  • 2xx dışındaki yanıtlar başarısız sayılır. WApi retryCount (varsayılan 3) kadar üstel geri çekilme (1s, 2s, 4s, 8s…) ile yeniden dener.
  • Aynı olayın birden fazla kez gelmesine karşı, X-WApi-Timestamp + waMessageId ikilisi ile idempotent davranan endpoint'ler önerilir.
  • Webhook tarafındaki maksimum işleme süresi Webhook:TimeoutSeconds ile sınırlıdır (varsayılan 10 saniye). Uzun süren işleri kuyruğa alın ve hemen 200 dönün.

Hata Yönetimi

WApi standart HTTP durum kodlarını kullanır ve hatalar için RFC 9457 — Problem Details şeklinde yapılandırılmış gövde döner.

KodAnlamıTipik nedenDavranış
200 / 201 / 204Başarı
400Geçersiz istekEksik veya tip hatası içeren gövde (örn. chatId boş)Düzelt ve yeniden gönder; gövdedeki errors alanını incele.
401Kimlik doğrulanmadıEksik/hatalı anahtar, IP allowlist'e dışarıdan istek, süresi geçmiş anahtarDoğru anahtar başlığını ekle, IP'yi allowlist'e ekle.
403Yetki yokAnahtarın rolü ucu çağırmaya yetmiyor (örn. Viewer ile send-text)Daha yüksek rolde anahtar kullan veya rolü güncelle.
404BulunamadıSession/Message/Webhook id'si yokId'yi doğrula.
409ÇakışmaOturum henüz connected değil; aynı isimde oturum varÖnce start + QR taraması; veya farklı isim seç.
429Hız limitiAşırı gönderim (üstte uygulanan global throttling)Retry-After başlığı kadar bekleyip yeniden dene.
500 / 502 / 503Sunucu hatasıEngine bağlantı kopması, DB erişim hatasıÜstel geri çekilme ile yeniden dene; ısrarlıysa /api/health ve /api/infra'ya bak.

Önerilen istemci davranışı

  • İdempotency anahtarı: aynı mesajın iki kez gönderilmesini önlemek için istemci tarafında bir tekil id tutun ve mesaj id'lerini DB'de saklayın.
  • Üstel geri çekilme: 429/5xx için 1s, 2s, 4s, 8s, 16s gibi artan aralıklarla en fazla 5 deneme. Toplu kampanyalarda intervalMs'i artırın.
  • Devre kesici: 5 dakikada %50'den fazla 5xx ise istemci tarafından gönderimi geçici durdurun; /api/health 200 dönene kadar bekleyin.
  • Loglama: traceId alanını (Problem Details içinde) kendi log'unuza işleyin — sunucu loglarıyla birebir eşleşir.

Kurulum ve Dağıtım

WApi tipik bir Windows veya Linux sunucuda saatler içinde devreye alınır. Aşağıda Windows + Caddy + SQL Server kurulumunun referans yapılandırması verilmiştir.

Ön gereksinimler

  • .NET 10 SDK (build için) + .NET 10 ASP.NET Core Runtime (çalışma için)
  • SQL Server 2019+ (LocalDB, on-prem, Docker veya Azure SQL)
  • Reverse proxy (önerilen: Caddy, otomatik TLS için)
  • Gerçek WhatsApp gönderimi için Node.js 22 LTS (yan-süreç için, sistem PATH'ına eklemek zorunlu değil)

1 · API'yi Windows Service olarak yayınla

# 1. Build + publish (framework-dependent; .NET 10 runtime sunucuda olmalı)
dotnet publish src/WApi.Api -c Release -o C:\.MyApps\Wapi\Api

# 2. Production appsettings'i bin yanına yaz (ConnectionStrings, Security:MasterKey, ...)
#    Dosyayı sınırlı erişimle kilitle:
icacls C:\.MyApps\Wapi\Api\appsettings.Production.json /inheritance:r `
    /grant:r "NT AUTHORITY\SYSTEM:R" "BUILTIN\Administrators:F"

# 3. Servisi oluştur
sc.exe create WApi.Api binPath= "\"C:\.MyApps\Wapi\Api\WApi.Api.exe\" `
    --contentRoot \"C:\.MyApps\Wapi\Api\" --urls \"http://127.0.0.1:2785\"" `
    start= auto obj= LocalSystem DisplayName= "WApi — WhatsApp API Gateway"

# 4. Production environment'ı registry env-var olarak set et
New-ItemProperty -Path HKLM:\SYSTEM\CurrentControlSet\Services\WApi.Api `
    -Name Environment -PropertyType MultiString `
    -Value @("ASPNETCORE_ENVIRONMENT=Production","DOTNET_ENVIRONMENT=Production") -Force

Start-Service WApi.Api

2 · Caddy ile TLS ve reverse proxy

wapi.example.com {
    encode zstd gzip
    header {
        Strict-Transport-Security "max-age=31536000; includeSubDomains; preload"
        X-Content-Type-Options "nosniff"
        Referrer-Policy "strict-origin-when-cross-origin"
    }

    # SignalR uzun-yaşam bağlantıları için
    @signalr path /api/events*
    handle @signalr {
        reverse_proxy 127.0.0.1:2785 {
            flush_interval -1
            stream_close_delay 5m
            transport http { keepalive 60s }
        }
    }

    reverse_proxy 127.0.0.1:2785
}

3 · Gerçek WhatsApp için node-bridge yan-süreci

Üretim kurulumunda nodebridge/ klasörü ayrı bir Windows Service olarak (örn. WinSW ile) çalışır, Baileys'i ayağa kaldırır ve 127.0.0.1:2787'de loopback dinler. WApi.Api ona paylaşılan bir WAPI_BRIDGE_TOKEN bearer ile erişir. appsettings.Production.json:

{
  "Engine": { "Type": "node-bridge" },
  "NodeBridge": {
    "BaseUrl": "http://127.0.0.1:2787",
    "Token": "",
    "TimeoutSeconds": 60
  }
}

Yan-süreç Baileys'in useMultiFileAuthState mekanizmasıyla her oturum için ayrı bir auth state klasörü tutar. Servis yeniden başlatıldığında bu klasörden cred'ler yüklenir; rescan gerekmez.

4 · Docker ile tek-komut tüm-stack

SQL Server + API + Dashboard'u tek bir compose dosyasıyla ayağa kaldırmak için:

docker compose up --build
# API:        http://localhost:2785/api/docs
# Dashboard:  http://localhost:2886

Sık Sorulanlar

WApi resmi bir WhatsApp Business çözümü müdür?

Hayır. WApi, WhatsApp Multi-Device protokolüne (whatsapp-web.js / Baileys aileti) istemci olarak bağlanan açık-kaynak bir ağ geçididir. Resmi WhatsApp Business API ile aynı yüzeyde değildir; Meta'nın yayımladığı resmi REST API'siyle karıştırılmamalıdır. Resmi ToS gereği toplu/spam gönderim hesabın engellenmesine yol açabilir; kullanım kalıbınızı kişisel iletişim profiline yakın tutun.

SaaS olarak mı yoksa kendi sunucumda mı çalıştırırım?

WApi self-hosted çalıştırılır. Tüm veriler (mesajlar, kişiler, anahtarlar, audit log) sizin SQL Server'ınızda kalır. Üçüncü taraf bir bulut bağımlılığı yoktur. Bu sayede KVKK/GDPR kapsamındaki kişisel veri akışını tamamen kontrol edebilirsiniz.

Birden fazla numarayı tek WApi kurulumunda yönetebilir miyim?

Evet. Her numara bir session'dır. Tek bir WApi.Api ve tek bir Node.js yan-süreci ile sınırsız sayıda oturum tutulabilir. Her oturumun kendi Baileys auth state'i, mesaj geçmişi ve webhook yapılandırması olur.

Mesajlar uçtan uca şifreli mi?

WhatsApp Multi-Device protokolü Signal Double Ratchet uçtan uca şifrelemeyi kullanır; bu uçtan uca şifre WApi'nin görmediği bir protokol katmanında uygulanır. WApi'nin gördüğü ham mesaj metni (sizin yazdığınız ya da Baileys'in açtığı) tabii ki SQL Server'a düz şekilde yazılır — ihtiyaç halinde SQL Server TDE veya kolon-level encryption kullanın.

WhatsApp'ım banlanır mı?

WhatsApp Business olmayan istemcilere karşı koruyucu davranır. Aşırı/sıralı/identik mesaj gönderimi otomatik tetikleyicileri çalıştırır. Düşük hacim ve kişiselleştirilmiş içerik genelde sorun çıkarmaz; toplu kampanyalarda intervalMs'i 1500ms üzerinde tutmak, her alıcı için en azından farklı bir kelime üretmek ve "opt-out" mekaniği uygulamak risk azaltır. Yine de tüm risk kullanıcıdadır.

Yedekleme nasıl yapılır?

İki bileşen yedeklenir: SQL Server veritabanı (standart BACKUP DATABASE) ve Node yan-sürecindeki auth/ klasörü (oturum cred'leri). Bu iki şey beraber yedeklenirse sistem başka bir makineye birebir taşınabilir — rescan gerektirmez.

Üretim kullanımı için lisans gerekir mi?

Hayır. WApi MIT lisansı altındadır. Ticari ürün içine gömme, kapalı bir dağıtım yapma, fork etme tamamen serbesttir. Atıf zorunluluğu yoktur.

Hazırsanız Swagger ile başlayın

Tüm uçları ve şemaları kendi anahtarınızla canlı deneyin.