PintellyPintelly

Kullanıcı Tanımlama

Sitenizde hangi kullanıcınızın gezindiğini Pintelly'ye bildirin. O kişinin oturumları, olayları ve oturum kayıtları sizin kullanıcı kimliğinizle kaydedilir. Girişten sonra Pintelly.identify(), çıkışta Pintelly.reset() çağırın.

Hızlı başvuru

ÇağrıNe zamanEtkisi
Pintelly.identify(userId)Girişten sonra ve oturum açıkken her sayfa yüklemesindeZiyaretçiyi userId ile kaydeder ve o kişi için tam takibi başlatır.
Pintelly.reset()ÇıkıştaKimliği sonlandırır ve yeni bir oturum kaydı başlatır.
Pintelly.setConsent(false)Bu ziyaretçinin takibini geri çektiğinizdeKimliği sonlandırır, takibi durdurur ve gönderilmemiş olayları siler.
Pintelly.getUserId()Hata ayıklamaGeçerli kullanıcı kimliğini, takip kapalıyken null döndürür.

Onay: sizin kararınız, sizin sorumluluğunuz

identify(), site sahibi ve veri sorumlusu olarak o kişiyi kendi kimliğinizle izleme kararınızdır. Pintelly bu çağrıyı sizin onay beyanınız olarak işler:

  • O ziyaretçi için tam takip başlar: oturum kaydı ve Proje Ayarları'nda açık olan diğer tüm özellikler. Ziyaretçi onay penceresine henüz yanıt vermemiş olsa bile bu geçerlidir.
  • Ziyaretçi tarafındaki ret takibi durdurmaz. Bu, Pintelly'nin kendi onay penceresini ve onay yönetim aracınızı (Cookiebot, OneTrust vb.) kapsar. Pintelly'nin penceresi kapanır ve tanımlanmış ziyaretçiye gösterilmez.
  • Takibi yalnızca siz sonlandırabilirsiniz: reset() veya setConsent(false) ile.
  • Bu yolla toplanan kayıtlar identify tabanlı olarak işaretlenir. Paneldeki Yalnızca onaylı filtresi sadece kendi onayını vermiş ziyaretçileri gösterir, bu yüzden bu kayıtları dışarıda bırakır.

identify() çağırmadan önce o kişiyi izlemek için hukuki bir sebebiniz olduğundan ve kişiyi bilgilendirdiğinizden emin olun; örneğin aydınlatma metninizde veya kullanım koşullarınızda. Pintelly gönderdiğiniz veriyi kaydeder ve doğrular. Gönderip gönderemeyeceğinize sizin yerinize karar vermez.

identify(), Proje Ayarları'nda kapalı olan veya planınızda bulunmayan özellikleri açmaz.

Kullanıcı kimliği

  • 1 ile 256 karakter arasında bir metin olmalı, satır sonu veya sekme gibi kontrol karakteri içermemeli.
  • Sabit olmalı: aynı kişi her cihazda ve her ziyarette aynı kimliği almalı. Veritabanınızdaki kullanıcı kimliğini kullanın.
  • Anlamsız olmalı: e-posta adresi veya ad yerine usr_8f3a2c gibi bir iç kimlik ya da UUID tercih edin. Kimlik Pintelly ekibinizdeki herkese görünür ve her olayla birlikte saklanır.
  • Büyük/küçük harfe duyarlıdır: User_1 ve user_1 iki farklı kişidir.

Geçersiz bir kimlik gönderilmez. Tarayıcı konsolunda [Pintelly] Invalid userId… uyarısı görünür, Pintelly sunucuları da bu kimliği reddeder.

Kurulum

Pintelly script'i asenkron yüklenir, bu yüzden kodunuz çalıştığında window.Pintelly henüz tanımlı olmayabilir. SDK hazır olmadan yapılan çağrılar saklanır ve SDK hazır olunca uygulanır. Sizin yalnızca window.Pintelly'nin kendisini beklemeniz yeterli:

// Pintelly script'i yüklendiğinde fn'i çalıştırır (10 saniyeye kadar kontrol eder).
function withPintelly(fn, tries = 100) {
  if (window.Pintelly) fn(window.Pintelly);
  else if (tries > 0) setTimeout(() => withPintelly(fn, tries - 1), 100);
  else console.warn('Pintelly did not load; check that its script tag is on this page.');
}

Düz JavaScript

// Başarılı girişten sonra ve oturum açıkken her sayfa yüklemesinde:
withPintelly((p) => p.identify(currentUser.id));

// Çıkışta, yönlendirmeden önce:
withPintelly((p) => p.reset());

React

Örneklerin hepsi yukarıdaki withPintelly fonksiyonunu kullanır. Fonksiyonu ortak bir modüle koyup oradan import edin.

import { useEffect } from 'react';

export function PintellyIdentity({ user }) {
  useEffect(() => {
    if (user) withPintelly((p) => p.identify(String(user.id)));
  }, [user?.id]);
  return null;
}

// Çıkış fonksiyonunuzda:
async function logout() {
  withPintelly((p) => p.reset());
  await api.logout();
}

Next.js (App Router)

'use client';
import { useEffect } from 'react';

declare global {
  interface Window { Pintelly?: { identify(id: string): void; reset(): void } }
}

export function PintellyIdentity({ userId }: { userId: string | null }) {
  useEffect(() => {
    if (userId) withPintelly((p) => p.identify(userId));
  }, [userId]);
  return null;
}

<PintellyIdentity userId={session?.user.id ?? null} /> bileşenini kök layout'ta render edin. Kullanıcıyı çıkaran istemci kodunda withPintelly((p) => p.reset()) çağırın.

Vue

import { watch } from 'vue';

watch(() => auth.user?.id, (id) => {
  if (id) withPintelly((p) => p.identify(String(id)));
}, { immediate: true });

Davranış ayrıntıları

  • Kalıcılık: Kimlik, kök alan adınızdaki birinci taraf bir çerezde iki yıla kadar tutulur. Böylece sayfalar ve alt alan adları arasında taşınır. Yine de her sayfa yüklemesinde identify() çağırmanız önerilir. Oturum başına bir UserIdentified olayı kaydedilir; aynı oturumdaki tekrar çağrılar bir şey göndermez.
  • Kullanıcı değişimi: Farklı bir kimlikle identify() çağrılırsa önce önceki kimlik sonlandırılır. Yeni kişi yeni bir oturum ve yeni bir kayıt alır; bir kişinin hareketleri başka birinin altında görünmez.
  • Çıkış: reset() önce kuyruktaki olayları sahibinin kimliğiyle gönderir, sonra kimliği sonlandırır. Ziyaretçi kendisi onay vermişse takip yeni bir anonim ziyaretçi olarak sürer. Vermemişse yalnızca anonim ölçüm devam eder.
  • Geri çekme: setConsent(false) kimliği sonlandırır ve henüz gönderilmemiş olayları siler. Daha önce ulaşmış veriler silinmez.
  • Geçmiş: Tanımlama, çağrı anından itibaren geçerlidir. Daha önce gönderilmiş olayları yeniden yazmaz.
  • Botlar: Bilinen bot user-agent'larından gelen trafik, tanımlanmış olsun olmasın, bot trafiği olarak işaretlenir ve ayrı bot görünümünde gösterilir.

Kullanıcıyı panelde bulma

Projenizde Ziyaretçiler sayfasını açın ve kimliği kullanıcı kimliğinizle eşleşen ziyaretçiyi seçin. Profil, o kişinin bütün oturumlarını en yeniden eskiye listeler: giriş ve çıkış sayfası, süre, sayfa sayısı, öfkeli tıklamalar, hatalar, anomaliler ve geri bildirimler. Kaydı izle kaydı, kişinin ne yaptığını gösteren tıklanabilir bir zaman çizelgesiyle açar. Girişten önce başlamış bir oturum bütünüyle dahildir, yani kişinin giriş yapmadan önce ne yaptığını da görürsünüz.

Kullanıcının kayıtlarını kendi yönetim panelinizde gösterme

Bir kullanıcının oturum listesini ve kayıtlarını kendi yönetim panelinize, örneğin o kullanıcının profil sayfasına gömebilirsiniz. Sayfa Pintelly tarafından bir iframe içinde sunulur. Kayıt içeriği hiçbir zaman sizin alan adınızda çalışmaz ve Pintelly oturumu gerekmez.

  1. Ayarlar → Güvenlik → API token'ları bölümünde Replay gömme türünde bir token oluşturun. Bu token yalnızca sunucunuzda kalmalı.
  2. Bir yönetici kullanıcı profilini açtığında sunucunuz, Pintelly'den yalnızca o kullanıcı için kısa ömürlü bir gömme anahtarı ister:
// Node.js (sunucu tarafı)
const res = await fetch('https://pintelly.com/api/embed/sessions', {
  method: 'POST',
  headers: { Authorization: `Bearer ${process.env.PINTELLY_EMBED_TOKEN}`, 'Content-Type': 'application/json' },
  body: JSON.stringify({ domainId: 'PROJE_KIMLIGINIZ', userId: user.id }),
});
const { url, expiresAt } = await res.json();
// PHP (sunucu tarafı)
$ch = curl_init('https://pintelly.com/api/embed/sessions');
curl_setopt_array($ch, [
  CURLOPT_POST => true,
  CURLOPT_RETURNTRANSFER => true,
  CURLOPT_HTTPHEADER => ['Authorization: Bearer ' . getenv('PINTELLY_EMBED_TOKEN'), 'Content-Type: application/json'],
  CURLOPT_POSTFIELDS => json_encode(['domainId' => 'PROJE_KIMLIGINIZ', 'userId' => (string) $user->id]),
]);
$embed = json_decode(curl_exec($ch), true);
  1. Dönen url'yi bir iframe'e koyun. # işaretinden önce Türkçe arayüz için &lang=tr, koyu tema için &theme=dark ekleyin (varsayılan açık temadır).
<iframe src="EMBED_URL" style="width:100%;height:900px;border:0" title="Oturum kayıtları"></iframe>
  1. Sayfa açık ve görünür olduğu sürece iframe anahtarını birkaç dakikada bir yeniler, böylece gezinirken ya da izlerken kimse dışarı atılmaz. Kapatılan veya arka planda kalan sayfa yenilemeyi bırakır ve anahtarı en geç 10 dakika içinde düşer. Ne kadar yenilenirse yenilensin, bir anahtar oluşturulduktan 8 saat sonra çalışmayı bırakır. Bu olduğunda oynayan kayıt oynamaya devam eder, bir uyarı çıkar ve iframe postMessage ile { type: 'pintelly:embed-expired' } gönderir. Yeni bir adres alıp iframe'i yenileyin:
window.addEventListener('message', (e) => {
  if (e.origin === 'https://pintelly.com' && e.data?.type === 'pintelly:embed-expired') reloadEmbed();
});

Güvenlik modeli:

  • Gömme anahtarı tek bir projede tek bir kullanıcının oturumlarını ve kayıtlarını salt okunur açar. Her kaydın o kullanıcıya ait olduğu Pintelly sunucularında kontrol edilir.
  • Gömme anahtarının yalnızca özeti saklanır. API token'ını iptal etmek, token sahibinin projeye erişimini kaldırmak veya oturum kaydı içermeyen bir plana geçmek gömmeyi süre dolmadan, anında sonlandırır.
  • Sayfa yalnızca projenizin doğrulanmış alan adı ve alt alan adları tarafından iframe'e alınabilir; örneğin https://example.com ve https://admin.example.com. Farklı bir alan adındaki yönetim paneli onu gömemez.
  • Anahtar, tarayıcıların sunuculara ve Referer başlığına hiç göndermediği URL fragment'ı içinde taşınır ve sayfa yüklenince adres çubuğundan silinir.
  • Her anahtar oluşturma, listeleme ve oynatma 90 gün boyunca kayıt altında tutulur. Token'ın sahibi bu kaydı Ayarlar → Güvenlik → API token'ları → Erişimler altında görür.
  • API token'ını asla tarayıcı koduna koymayın. Gömme anahtarını yalnızca kendi yönetici yetki kontrolünüzden sonra oluşturun.

Kullanıcının verisini silme

Bir silme talebini karşılamak için (KVKK m.11, GDPR m.17) kullanıcıyı Ziyaretçiler'de açın ve Bu kişinin verisini sil seçeneğini kullanın. Aynı işlemi Ziyaretçi verisi silme türünde bir API token'ıyla sunucunuzdan da yapabilirsiniz:

const res = await fetch('https://pintelly.com/api/analytics/visitor-deletions/PROJE_KIMLIGINIZ', {
  method: 'POST',
  headers: { Authorization: `Bearer ${process.env.PINTELLY_DELETE_TOKEN}`, 'Content-Type': 'application/json' },
  body: JSON.stringify({ userId: user.id }),
});
const request = await res.json(); // 202 { id, status: 'pending' }
// Durum 'done' veya 'failed' olana kadar sorgulayın:
// GET https://pintelly.com/api/analytics/visitor-deletions/PROJE_KIMLIGINIZ/{request.id}

Silme işlemi o projede kullanıcının olaylarını ve oturumlarının bütün olaylarını (identify() öncesi kısım dahil), oturum kayıtlarını, ekran görüntüleriyle birlikte geri bildirimlerini, anomali ve AI analiz kayıtlarını kaldırır. Arka planda çalışır ve genellikle birkaç dakikada tamamlanır. Başka kayıtlarla aynı içeriği paylaşan kayıt depolaması bir sonraki saklama temizliğinde kaldırılır.

Her talep ve sonucu projenin Ayarlar → Data deletions sekmesinde listelenir. Bir kişinin verisini yalnızca proje sahibi ve rolünde Analitik için yazma yetkisi olan ekip üyeleri silebilir.

Talepten sonra gelen veriler silinmez. Önce o kullanıcı için Pintelly.reset() çağırın veya identify() çağırmayı bırakın. Grafiklerdeki toplu sayımlar kişi bazlı değildir ve korunur.

Entegrasyonu doğrulama

  1. Sitenizde giriş yapın, tarayıcı konsolunu açın ve Pintelly.getUserId() çalıştırın. Kullanıcı kimliğiniz dönmeli.
  2. Ziyaretçiler sayfasında bu kimliği bulun. Test oturumunuz bir dakika içinde görünmeli.
  3. Çıkış yapın ve Pintelly.getUserId() komutunu tekrar çalıştırın. Farklı bir kimlik dönmeli; ziyaretçi olarak onay vermediyseniz null dönmeli.
  4. Aynı tarayıcıda ikinci bir kullanıcıyla giriş yapın ve Ziyaretçiler'de iki kullanıcının oturumlarının ayrı olduğunu doğrulayın.
  5. Onay penceresi kullanıyorsanız girişten önce reddedin ve tanımlanmış oturumun yine de kaydedildiğini doğrulayın. Bu beklenen davranıştır (yukarıdaki "Onay" bölümüne bakın).

Sorun giderme

BelirtiKontrol
Girişten sonra Pintelly.getUserId() null dönüyoridentify() çağrılmamış veya geçersiz bir kimlik almış. Konsolda [Pintelly] uyarılarına bakın.
window.Pintelly undefinedScript etiketi bu sayfada yok, bir içerik engelleyici veya CSP tarafından engellenmiş, ya da kodunuz script yüklenmeden çalışmış. withPintelly kullanın.
Ziyaretçi görünüyor ama kaydı yokOturum Kaydı Proje Ayarları'nda kapalı, planınızda yok ya da kaydın saklama süresi dolmuş.
İki kişi tek profilde görünüyorÇıkışta reset() çağrılmıyor veya iki hesap aynı kimliği gönderiyor.
Tanımlanmış ziyaretçiler grafiklerde yokYalnızca onaylı filtresi açık. Bu filtre identify tabanlı kayıtları bilerek dışarıda bırakır.

AI kodlama asistanları için talimat

Bu bloğu, bu sayfanın adresiyle birlikte kodlama asistanınıza yapıştırın. Talimat, asistanların en tutarlı izlediği dil olan İngilizcedir.

Integrate Pintelly user identification into this codebase.

Context:
- The Pintelly script is already installed and exposes window.Pintelly once loaded.
- Pintelly.identify(userId) records the visitor under userId and starts full tracking,
  including session replay. It is the site owner's consent declaration and overrides a
  visitor-side refusal. Only Pintelly.reset() or Pintelly.setConsent(false) ends it.
- Calls made before the SDK is ready are kept; only window.Pintelly must exist.

Do:
1. Add this helper once, in a shared client-side module:
   function withPintelly(fn, tries = 100) {
     if (window.Pintelly) fn(window.Pintelly);
     else if (tries > 0) setTimeout(() => withPintelly(fn, tries - 1), 100);
     else console.warn('Pintelly did not load; check that its script tag is on this page.');
   }
2. Call withPintelly((p) => p.identify(String(user.id))) wherever the authenticated user
   becomes known: after login, after signup, and on app start when a session is restored.
3. Call withPintelly((p) => p.reset()) in every logout path, before redirecting.
4. Use the application's stable internal user ID (database primary key or UUID).

Do not:
- Do not pass an email address, name, phone number or other personal data as the ID.
- Do not pass IDs longer than 256 characters or containing control characters.
- Do not call identify() for anonymous or guest users.
- Do not call identify() on the server; it runs in the browser only.
- Do not add Pintelly.setConsent(true) next to identify(); identify already starts tracking.
- Do not remove or change the existing consent banner integration.

Optional, only if asked to embed replays in the admin panel:
5. Add a server-side endpoint, callable only by authorized admins, that POSTs
   { domainId, userId } to https://pintelly.com/api/embed/sessions with
   "Authorization: Bearer <PINTELLY_EMBED_TOKEN from server env>" and returns { url }.
6. Render that url in an <iframe> on the user's admin profile page. On a window
   "message" event from origin https://pintelly.com with data.type ===
   'pintelly:embed-expired', fetch a new url and replace the iframe src.
7. Never expose the API token to the browser; never mint without the admin check.

Afterwards, list every file you changed and every login, signup, session-restore and
logout path you found, and say which of them now call identify() or reset().