Lunachat
Geliştirici

Widget JavaScript API

Sohbet widget'ını sayfadan kontrol et: başlat, aç, kapat, ziyaretçi hakkında bildiklerini gönder.

Bu sayfa uygulanmış olanı anlatır. Burada yazmayan bir çağrı sessizce yok sayılır.

Embed kodu

Panelde Web siteleri → site → Kurulum altındaki kodu </body> kapanışından önce yapıştır.

index.html
<script>
  window.lunachat = window.lunachat || function () {
    (lunachat.q = lunachat.q || []).push(arguments);
  };
  lunachat('init', 'pk_live_7f3a9c2e8b1d4a6f');
</script>
<script async src="https://cdn.lunachat.co/w.js"></script>

İlk blok bir kuyruk kurar. Asıl betik async yüklenir ve sayfanın çizimini engellemez; yüklendiğinde kuyruktaki çağrıları sırasıyla işler. Bu yüzden betik yüklenmeden önce komut çağırmak güvenlidir — kaybolmaz. Kuyruktaki bozuk bir çağrı diğerlerini düşürmez.

Komutlar

KomutİmzaNe yapar
init(publicKey, options?)Widget'ı başlatır
set(attributes)Özel değişken gönderir
identify(token)Kullanıcıyı doğrulanmış olarak tanıtır
track(event, payload)Dönüşüm bildirir (sipariş)
open()Sohbeti açar
close()Sohbeti kapatır
shutdown()Oturumu temizler
on(event, callback)Olay dinler

init(publicKey, options?)

lunachat('init', 'pk_live_7f3a9c2e8b1d4a6f');

// Dili sabitle
lunachat('init', 'pk_live_7f3a9c2e8b1d4a6f', { lang: 'en' });

publicKey site kimliğidir, gizli değildir. Widget'ın hangi alan adlarında çalışacağı panelden sınırlanır; kodu kopyalayan başka bir site onu çalıştıramaz.

lang 'tr' veya 'en'. Verilmezse ziyaretçinin tarayıcı dili kullanılır. /en gibi ayrı bir dizin sunuyorsan dili sabitlemek isteyebilirsin — tarayıcı dili bunu bilemez.

Sabitlediğin dil panelde açık dillerden biri değilse birincil dil gösterilir. Yani { lang: 'en' } yazmak, panelde İngilizceyi açmadıkça İngilizce göstermez. Sitenin cevap veremeyeceği bir dilde konuşuyor görünmemek için böyle.

init birden çok kez çağrılırsa ikincisi yok sayılır.

set(attributes)

Ziyaretçi hakkında sitenin bildiği veriyi panele taşır; temsilci bunları kişi panelinde görür.

lunachat('set', {
  plan: 'premium',
  sepetTutari: 1250,
  uyeMi: true,
});

Değerler metin (en fazla 500 karakter), sayı, doğru/yanlış veya boş olabilir; en fazla 30 alan. init öncesinde çağrılabilir, widget başlayınca gönderilir.

Bu veri doğrulanmamıştır. Sayfanın JavaScript'inden gelir, yani tarayıcı konsolunu açan herkes değiştirebilir. Kimlik birleştirmede kullanılmaz ve kişi kaydının ad/e-posta/telefon alanlarına yazılmaz — ziyaretçinin forma kendi eliyle yazdığı bilgiden bu yüzden ayrı tutulur. Faturalama ya da yetki kararı verirken bunlara güvenme.

identify(token)

Siteye giriş yapmış kullanıcıyı doğrulanmış olarak tanıtır. set ile gönderilen veriden farkı: bu jetonu senin sunucun imzalıyor, dolayısıyla ad ve e-posta kişi kaydının kendi alanlarına yazılır ve aynı kullanıcı başka bir cihazdan yazdığında kayıtlar birleşir.

// SUNUCUNDA — anahtar tarayıcıya asla inmez
const jeton = jwt.sign(
  {
    sub: kullanici.id,        // zorunlu
    name: kullanici.ad,
    email: kullanici.eposta,
    attrs: { plan: 'pro' },   // doğrulanmış özel alanlar
    exp: Math.floor(Date.now() / 1000) + 3600,
  },
  process.env.LUNACHAT_SECRET,
  { algorithm: 'HS256' },
);

// Sayfada
lunachat('identify', jeton);

Gizli anahtarı Ayarlar → Web siteleri → Kurulum bölümünden üretirsin. Üretildiği anda bir kez gösterilir; yeni anahtar üretmek eskisini geçersiz kılar.

AlanAçıklama
subZorunlu. Kendi kullanıcı kimliğin; eşleştirme buna göre yapılır.
expZorunlu. En fazla 24 saat ileri olabilir.
name / email / phoneİsteğe bağlı. Kişi kaydında boş olan alanları doldurur.
attrsİsteğe bağlı. Doğrulanmış özel alanlar; en fazla 30 tane.
Jetonu sunucunda üret. Anahtar sayfaya inerse özelliğin hiçbir anlamı kalmaz: onu gören herkes istediği kullanıcı adına jeton yazabilir. Doğrulama geçmezse sohbet yine açılır, kullanıcı yalnızca anonim görünür.

track(event, payload)

Siparişi Lunachat'e bildirir. Raporlar ekranındaki ciro ve "sohbet eden ziyaretçilerin dönüşüm oranı" bu çağrıdan besleniyor. Bugün tek olay var: 'purchase'.

lunachat('track', 'purchase', {
  value: 1250,          // lira, KDV dahil sepet toplamı
  orderId: 'SP-88421',  // aynı siparişin iki kez sayılmasını engeller
});
AlanTipAçıklama
valuenumberTutar, LİRA cinsinden. Kuruşa çevirme.
orderIdstringSipariş numaran. Verilmezse çift sayım engellenemez.
currencystringBugün yalnızca 'TRY'. Verilmezse varsayılan.

Çağrı sohbet açmaz ve ziyaretçiye hiçbir şey göstermez. Widget henüz yüklenmediyse kuyruğa alınır, bağlantı kurulunca gönderilir — teşekkür sayfasında çağrının kaybolması diye bir durum yok.

Sipariş numarasını göndermeyi ihmal etme. Teşekkür sayfası yenilenebilir, geri tuşuyla dönülebilir, bazı altyapılarda yönlendirme iki kez çalışır. Numara varsa aynı sipariş bir kez sayılır; yoksa ciro raporu sessizce şişer.

Sipariş, ziyaretçinin son 7 gün içinde konuştuğu sohbete bağlanır. Hiç konuşmamışsa kayıt yine tutulur: karşılaştırmalı dönüşüm raporunun diğer yarısı o satırlardan çıkıyor.

open() / close()

Sitenin kendi düğmesinden sohbeti açmak için.

document.querySelector('#destek').addEventListener('click', () => {
  lunachat('open');
});

Widget henüz yüklenmediyse çağrı sessizce geçer.

shutdown()

// Kullanıcı sitede çıkış yaptığında
lunachat('shutdown');

Ziyaretçi jetonunu siler, bağlantıyı kapatır ve widget'ı kaldırır.

Ortak cihazda bu çağrı zorunludur. Jeton temizlenmezse aynı tarayıcıda giriş yapan bir sonraki kişi, öncekinin sohbet geçmişini görür. Çıkış akışına eklemeyi unutma.

on(event, callback)

lunachat('on', 'ready', () => {
  console.log('widget hazır');
});

lunachat('on', 'message', (message) => {
  console.log('temsilciden mesaj', message);
});
OlayNe zamanYük
readyWidget yüklendi ve çizildiyok
openSohbet paneli açıldıyok
closeSohbet paneli kapandıyok
messageTemsilciden mesaj geldimesaj nesnesi
automationOtomasyon baloncuğu gösterildi{ runId, body }

Dinleyicinin fırlattığı hata widget'ı düşürmez. message yükü sunucudan geldiği gibi verilir; alanları sürümler arasında değişebilir, şemasına bağımlı kod yazma.

Google Analytics için bu olayları dinlemene gerek yok. Panelde Ayarlar → Web siteleri → Kurulum sekmesindeki anahtar açıkken widget, sohbet olaylarını sayfandaki mevcut gtag ya da dataLayer kurulumuna kendisi yazıyor (lunachat_chat_opened, lunachat_conversation_started, lunachat_message_sent, lunachat_lead_captured, lunachat_rating_submitted). Mesaj metni ve iletişim bilgisi bu olaylarla taşınmıyor. Ayrıntı: Sohbet olaylarını Google Analytics'e gönderin.

Sık kullanılan kalıplar

Giriş yapmış kullanıcıyı tanıt

lunachat('init', 'pk_live_…');

// Doğrulanmış: jeton sunucunda imzalanır, ad ve e-posta kişi kaydına yazılır
lunachat('identify', jeton);

// Doğrulanmamış: yalnızca temsilciye bilgi olsun diye
lunachat('set', { sepetTutari: 1250 });

Kullanıcının kim olduğunu identify söyler; set yalnızca doğrulanması gerekmeyen ek bilgi için. İkisini karıştırma: sepet tutarı yanlışsa temsilci bir şey kaybetmez, kimlik yanlışsa yanlış kişiyle konuşur.

Dili sayfanın diline bağla

lunachat('init', 'pk_live_…', {
  lang: document.documentElement.lang.startsWith('en') ? 'en' : 'tr',
});

Siparişi ölç

<!-- sipariş tamamlandı sayfası -->
<script>
  lunachat('track', 'purchase', {
    value: {{ siparis.toplam }},
    orderId: '{{ siparis.no }}',
  });
</script>

Şablon değişkenleri e-ticaret altyapına göre değişir. Tek kural şu: tutar lira ve sipariş numarası gerçek numara olsun.

Bilinmesi gerekenler

Sayfa geçişleri. Widget adres değişimini kendi izler, tek sayfa uygulamalarında her geçişte yeniden initçağırma. Temsilcinin gördüğü "bulunduğu sayfa" birkaç saniye gecikebilir.

Otomasyon. Panelde kurduğun kurallar (ziyaretçi bir sayfada beklerse, ayrılmak üzereyken …) baloncuğun yanında mesaj gösterir. Mesaj metni ve kuralın kendisi sunucuda kalır; sayfaya yalnızca tarayıcının zaten bildiği koşullar iner. set ile gönderdiğin özel değişkenler kural koşulu olarak kullanılabilir.

Tetiklenen mesaj konuşma açmaz. Ziyaretçi cevaplarsa konuşma o an açılır ve otomatik mesaj temsilcinin gördüğü yazışmanın başına eklenir. Aynı ziyaretçiye 30 dakikada birden fazla otomatik mesaj gitmez; kapatılan mesaj o ziyaret boyunca geri gelmez.

Stil çakışması.Widget Shadow DOM içinde yaşar, sitenin CSS'i içeri sızmaz ve widget da siteyi bozmaz. Görünümü sayfadan CSS ile değiştiremezsin; renk, konum ve metinler panelden ayarlanır.

Boyut.Betik gzip sonrası 40 KB'ın altındadır ve async yüklenir; sayfa hızına ölçülebilir etkisi yoktur.

Hata durumu. Başlatma başarısız olursa (yanlış anahtar, izinsiz alan adı) sayfada hiçbir iz bırakılmaz — bozuk bir baloncuk, hiç olmayan baloncuktan kötüdür. Konsolda hata görmezsin; panelden alan adı listesini kontrol et.