Dokümantasyon

İki dakika kurulum, kalanı senin.

Widget public API, REST uçları ve socket event kontratı — geliştiricilerin başlaması için yeterli referans burada.

Kurulum

Tek satırlık script etiketiyle ya da npm paketiyle. Kayıt olduktan sonra panelden siteKey'ini kopyala, aşağıdaki snippet'a yapıştır.

<script
  src="https://cdn.iha-chat.com/loader.js"
  data-site-id="SITE_ANAHTARINIZ"
></script>

Data attribute'ları

AttrZorunluAçıklama
data-site-idevetPublic siteKey.
data-api-urlhayırProd'da https://api.iha-chat.com.
data-realtime-urlhayırProd'da https://rt.iha-chat.com.
data-themehayırlight veya dark.
data-bundle-urlhayırÖzel CDN kullanacaksan.

Widget public API

Widget yüklendikten sonra global window.IhaChat üzerinden komut çağırırsın. Yüklenmeden önce çağırırsan komut queue'ya alınır, hazır olduğunda oynatılır.

Komutlar
IhaChat('open')

Sohbet balonunu programatik olarak açar.

IhaChat('close')

Açık olan sohbet balonunu kapatır.

IhaChat('identify', { externalId, hmac, name?, email?, phone? })

Ziyaretçiyi hesabınızdaki kullanıcıyla eşler. HMAC yoksa isim/e-posta anonim olarak kabul edilir.

IhaChat('on', 'ready', handler)

Widget yüklenip mount edildiğinde tetiklenir.

IhaChat('on', 'open' | 'close', handler)

Sohbet balonu açıldığında / kapandığında tetiklenir.

IhaChat('on', 'message', ({ from, body }) => …)

Yeni gelen mesajlarda tetiklenir; from: 'visitor' | 'agent'.

HMAC identify örneği (Node)

import { createHmac } from "node:crypto";

const hmac = createHmac("sha256", SITE_SECRET)
  .update(user.id)
  .digest("hex");

// Sonra clientside:
IhaChat("identify", {
  externalId: user.id,
  hmac,
  name: user.name,
  email: user.email,
});

Not: SITE_SECRET asla widget'a gönderilmez — yalnız sunucuda hmac üret.

REST API

Panel scope'undaki uçlar httpOnly cookie (ihachat_access) ya da mobil için Bearer token kabul eder. Public uçlar CORS'a açık ve credential taşımaz.

Public uçlar

MethodPathAuthAçıklama
GET/public/widget-config?siteKey=…publicWidget'ın kendini kurabilmesi için tema, dil, çalışma saatleri ve özellik bayrakları.
GET/public/conversations/:id/messagespublicZiyaretçi geçmişi (cursor pagination: before/after, x-visitor-token header).

Panel uçları (yalnız görünüm)

MethodPathAuthAçıklama
POST/auth/loginpublicE-posta + şifre ile giriş; client:'panel' | 'mobile'.
POST/auth/refreshcookieRefresh token rotation (15 sn grace, reuse tespitinde iptal).
GET/auth/mecookieOturum sahibinin profili + org üyeliği.
GET/conversations?siteIds=&status=&search=&labels=cookieKonuşma listesi. Çoklu-site + arama + etiket filtreleri.
GET/conversations/:idcookieTek konuşma detayı: ziyaretçi, etiketler, ekip görünürlüğü.
GET/conversations/:id/messagescookieCursor pagination'lı mesaj geçmişi.
POST/conversations/:id/labelscookieKonuşmaya etiket ekle / çıkar.
GET/sitescookieOrganizasyonun siteleri.
POST/sitescookieYeni site oluştur (Pro planda sınırsız).
PATCH/sites/:idcookieSite ayarları: renk, tema, çalışma saatleri, offline mesaj.
POST/sites/:id/regenerate-keycookiesiteKey yenile (OWNER/ADMIN). Eski embed'ler kırılır.
GET/analytics/summary?from=&to=&siteIds=cookieKonuşma hacmi, CSAT, ort. yanıt, kırılım, heatmap.

Hata formatı: REST hataları { code: "…", message: "…" }. Kullanıcıya dönen mesajlar Türkçe ve teknik detaysız; log'lar sunucuda İngilizce ve detaylı.

Rate limit: visitor mesaj limiti Redis sliding window (10 msg / 10 sn / visitor). REST tarafında da IP-bazlı limit vardır.

Socket eventleri

Realtime tamamen websocket üzerinde (polling fallback yok, sticky session gerekmez). Client için Socket.IO 4 uyumlu; widget kendi minik EIO4 istemcisini kullanır. Tüm payload'lar Zod ile @ihachat/shared'da tanımlı.

/visitor namespace

EventYönAçıklama
visitor:session→ clientBağlantıda imzalı visitor token + aktif konuşma bilgisi.
visitor:identify→ serverexternalId + HMAC-SHA256(siteSecret, externalId). Doğrulanmazsa anonim devam.
visitor:prechat→ serverSohbet öncesi form yanıtları + departman seçimi.
message:send→ server{clientMessageId, body, attachmentId?}. Aynı clientMessageId iki kez gitmez.
message:ack→ client{clientMessageId, serverId, createdAt, duplicate}. Gönderene tekil.
message:new→ clientKonuşma odasına yayın.
typingYazıyor göstergesi.
conversation:status→ clientOPEN | PENDING | RESOLVED | ARCHIVED değişimleri.
conversation:rate→ serverCSAT: 1 (olumlu) / 0 (olumsuz) + isteğe bağlı yorum.

/agent namespace

EventYönAçıklama
conversation:list-delta→ clientKonuşma listesindeki değişimler (patch).
conversation:assign→ serverKonuşmayı üstlen.
conversation:resolve→ serverKonuşmayı RESOLVED olarak kapat.
conversation:transfer→ serverKonuşmayı başka departmana / agent'a taşı.
conversation:view→ serverBir konuşmayı açtığını bildir (viewing:true/false). TTL 30 sn, heartbeat 12 sn.
conversation:viewers→ clientSite room'unda o an bakan agent'lar.
visitor:presence→ clientZiyaretçi online / uzakta / offline + gezdiği URL.
presence:heartbeat→ serverAgent presence (Redis TTL 60 sn).
server:restart→ clientGraceful drain: 300ms → disconnect → client otomatik reconnect.

Room modeli: /visitor → conversation:<id>; /agent → site:<siteId> + agent:<agentId>.

Heartbeat: pingInterval: 25000, pingTimeout: 20000. Mesaj tutarlılığı için client her mesajda UUID clientMessageId üretir; duplicate'te message:ack { duplicate: true } döner.

Webhook'lar

Dış sistemlerden gelen olaylar — Instagram Graph ve Stripe.

GET /webhooks/instagram

Meta challenge doğrulama — text/plain hub.challenge cevabı.

POST /webhooks/instagram

Instagram DM olayları. X-Hub-Signature-256 doğrulanır, rawBody + timingSafeEqual.

POST /billing/webhook

Stripe: checkout.session.completed, customer.subscription.*, invoice.*. Idempotency StripeEvent tablosunda.

API URL'leri (bu ortam)

Landing'in NEXT_PUBLIC_* env'lerinden okunur; kendi kurulumunda değiştir.

  • panel: https://panel.iha-chat.com
  • api: https://api.iha-chat.com
  • rt: https://rt.iha-chat.com

Framework'e özel entegrasyon örnekleri ve daha fazlası için: