B

Pano Entegrasyon Dökümantasyonu

Eyena Board Embed API — tam rehber

Genel Bakış

Göz takipli ortak çalışma panosunu kendi sitenize iframe ile gömün. İstemci modeli ödev entegrasyonuyla aynıdır; mevcut bir Embed İstemcisi varsa yalnızca bir izin daha gerekir.

Ön koşullar

  • · Eyena Sistem Yetkilisi tarafından pano izni (PanoIzni) verilmiş bir client_id + client_secret. Pano erişimi varsayılan olarak kapalıdır — mevcut istemciler yalnızca testler için yetkilidir.
  • · Kayıtlı bir veya daha fazla izinli origin.
Sizin Backend'iniz                     Eyena
──────────────────────────             ────────────────────────────────
1. POST /connect/token          ─────► eyena-giris → M2M access token
2. POST /api/embed/board-session ────► eyena-api   → boardToken + roomId
3. Oda anahtarını siz üretirsiniz (aşağıya bakın)
4. boardToken + roomId + key → frontend'inize

Sizin Frontend'iniz
───────────────────
5. iframe src = https://board.eyena.net/embed?token={boardToken}#key={roomKey}
6. postMessage olaylarını dinleyin

Oda Anahtarını Siz Üretirsiniz

Pano içeriği uçtan uca şifrelidir. Oda anahtarı Eyena'ya hiçbir zaman gönderilmez — URL fragment'inde durur ve tarayıcılar fragment'i sunucuya iletmez. Pano başına bir anahtar üretin ve o panonun tüm katılımcıları için aynısını kullanın.

// 128-bit AES anahtarı, padding'siz base64url
const raw = crypto.getRandomValues(new Uint8Array(16))
const roomKey = btoa(String.fromCharCode(...raw))
  .replace(/\+/g, '-').replace(/\//g, '_').replace(/=+$/, '')

Anahtarı kendi pano kaydınızın yanında saklayın. Kaybederseniz panonun içeriği geri getirilemez — Eyena sizin için çözemez.

Panolar oturum bitince silinir

Bir pano tek bir oturuma bağlıdır, arşivlenmez. Odada bir süre (varsayılan 2 saat) canlı katılımcı kalmazsa pano ve dosyaları silinir. Bağlı istemciler canlılık sinyali gönderdiği için, çizim yapılmayıp yalnızca konuşulan bir oda da canlı sayılır. Eğitmen pano içinden oturumu anında sonlandırarak panoyu hemen silebilir.

İçeriğe sonradan ihtiyacınız varsa oturum sırasında dışa aktarın — tasarım gereği sonradan erişim yoktur.

Entegrasyon Adımları

1

M2M access token alın (sunucu tarafı)

const res = await fetch('https://giris.eyena.net/connect/token', {
  method: 'POST',
  headers: { 'Content-Type': 'application/x-www-form-urlencoded' },
  body: new URLSearchParams({
    grant_type: 'client_credentials',
    client_id: 'embed-abc123',
    client_secret: 'GIZLI_SECRET',
    scope: 'api',
  }),
})
const { access_token } = await res.json()
2

Pano oturumu oluşturun veya katılın (sunucu tarafı)

const res = await fetch('https://api.eyena.net/api/embed/board-session', {
  method: 'POST',
  headers: {
    'Content-Type': 'application/json',
    Authorization: `Bearer ${access_token}`,
    Origin: 'https://sizin-siteniz.com',   // kayıtlı origin ile eşleşmeli
  },
  body: JSON.stringify({
    role: 'instructor',                    // ZORUNLU — 'instructor' | 'student'
    displayName: 'Ayşe Öğretmen',
    baslik: 'Ders 3 — Kesirler',           // opsiyonel, yalnızca eğitmen
    shareUrl: 'https://sizin-siteniz.com/board/{roomId}',  // kendi katılım sayfanız
    // roomId: 'abc123…'                   // öğrenciler için ZORUNLU; yeni pano için boş bırakın
  }),
})
const { boardToken, roomId, expiresAt } = await res.json()
AlanZorunluNot
roleevet'instructor' veya 'student' — varsayılanı yoktur
displayNameevetDiğer katılımcılara gösterilir
roomIdöğrenciler içinYalnızca eğitmen yeni pano açarken boş bırakılır
baslikhayırPano başlığı
shareUrlhayırKendi katılım sayfanız — aşağıya bakın

role katılımcının ne göreceğini belirler — açıkça gönderin

Rol boardToken'a işlenir ve tarayıcıda değiştirilemez. Gömülü panonun eğitmen ile öğrenciyi ayırt etmek için kullandığı tek bilgi budur:

instructorstudent
Göz takibi onayıgösterilmezkatılırken gösterilir
Kalibrasyon ekranıgösterilmezonaydan sonra gösterilir
Kamera erişimiistenmezonaydan sonra istenir
Bağlantı kopyala / bakış düğmelerigösterilirgizlidir
Bakış verisialır (çözer)gönderir (eğitmene şifreli)

role gönderilmezse istek 400 döner; sessizce student sayılmaz. Eski davranış buydu ve kafa karıştırıcı bir hataya yol açıyordu: eğitmenin kendi çerçevesi kamera onayı soruyor, kalibrasyona sokuyor ve eğitmen düğmelerini gizliyordu. Böyle bir durumda çerçevede öğrenci jetonu vardır — boardToken'ın roleclaim'ine bakın ya da çözümlenen rolü bildiren eyena-board-ready mesajını dinleyin.

Paylaşım bağlantıları bize değil, size işaret eder

Pano içindeki "bağlantıyı kopyala" düğmesi sizinURL'nizi verir; çünkü öğrenciler sizin sayfanızdan katılır — oturumu sizin backend'iniz üretir, iframe'i sizin sayfanız açar. Bir board.eyena.net bağlantısı onların işine yaramaz.

shareUrl: 'https://sizin-siteniz.com/board/{roomId}'
        → https://sizin-siteniz.com/board/9f2b7c1d4e6a8b0c2d4e

Katılım sayfanız bu roomId'yi okur, o oda için bir studentoturumu oluşturur ve iframe'i Adım 3'teki gibi render eder. Önce eğitmen oturumunu oluşturup roomId'yi alın, sonra aynı oda için öğrenci oturumları üretin. Bir pano onu oluşturan istemciye aittir; başka bir istemci o pano için oturum üretemez.

shareUrlkayıtlı origin'lerinizden birinde olmalıdır — aksi hâlde istek 403 ile reddedilir. Göndermezseniz kopyalama düğmesi hiç gösterilmez. Token'lar 2 saatsonra dolar ve kayıtlı origin'inize bağlıdır.

3

iframe'i render edin (istemci tarafı)

<iframe
  id="eyena-board"
  style="width: 100%; height: 700px; border: none;"
  allow="camera; microphone; fullscreen"
></iframe>

<script>
  const res = await fetch('/api/my-board-session')     // kendi endpoint'iniz
  const { boardToken, roomKey } = await res.json()

  document.getElementById('eyena-board').src =
    `https://board.eyena.net/embed?token=${encodeURIComponent(boardToken)}#key=${roomKey}`

  window.addEventListener('message', (event) => {
    if (event.origin !== 'https://board.eyena.net') return
    switch (event.data?.type) {
      case 'eyena-board-ready':  console.log('oturum geçerli', event.data.roomId); break
      case 'eyena-board-joined': console.log('bağlandı:', event.data.role);        break
      case 'eyena-board-error':  console.warn('pano hatası', event.data.reason);   break
      case 'eyena-board-voice-error':
        console.warn('ses kullanılamıyor', event.data.reason);              break
    }
  })
</script>

allow="camera; microphone; fullscreen" zorunludur: camera göz takibi ve kalibrasyon için, microphone sesli konuşma için. Bir mesaja güvenmeden önce her zaman event.origin'i kontrol edin.

Faz 7 ile değişti. Ses özelliginden önce gömülen panolar allow="camera; fullscreen"ile belgelenmişti. O iframe'ler çalışmaya devam eder, ancak içlerinde ses mikrofon açamaz: tarayıcı öğrenciye hiç sormadan reddeder. Pano bu durumu eyena-board-voice-error / embed-permission-missing olarak bildirir.microphone iznini eklemek sorunu çozer.

postMessage Olayları

event.data.typeNe zamanPayload
eyena-board-readyToken doğrulandı, katılmadan önce{ roomId, role }
eyena-board-joinedOdaya bağlanıldı{ roomId, role }
eyena-board-errorToken geçersiz/süresi dolmuş ya da anahtar yok{ reason }
eyena-board-shareEğitmen paylaşım bağlantısını kopyaladı{ roomId, shareUrl }
eyena-board-voice-errorSes başlatılamadı ya da mikrofon açılamadı{ reason }

reason değeri invalid-token veya missing-room-key olur.

Gömülü Panolarda Göz Takibi

Öğrencilerin bakışı yalnızca eğitmenin okuyabileceği şekilde şifrelenir — diğer katılımcılar gizlenmiş değil, çözülemez bir veri alır. Bakış paylaşımını eğitmen açıp kapatır; öğrenciler yalnızca izlenirken veri gönderir.

Gömülü öğrenciler board.eyena.net üzerinde barındırılan panolarla aynı Tobii göz takibinialır: lisans isteğinde pano token'ı Eyena girişinin yerine geçer, dolayısıyla Eyena kullanıcı hesabı gerekmez.

Öğrencilere katılmadan önce 9 noktalı kalibrasyon adımı gösterilir. Cihazda kamera yoksa, öğrenci izni reddederse veya kullanılabilir bir Tobii izleyici bulunamazsa pano engellemek yerine yalnızca fare moduna düşer.

allow="camera; microphone; fullscreen" bu yüzden opsiyonel değildir — camera olmadan tarayıcı kamera erişimini reddeder ve her öğrenci sessizce yalnızca fare moduna düşer; microphone olmadan ise öğrenci ne kabul ederse etsin ses hiç açılamaz.

Güvenlik Notları

  • · client_secret veya access_token'ı asla tarayıcıya sızdırmayın.
  • · Her sayfa yüklemesinde yeni bir boardToken üretin; oturumlar arasında önbelleğe almayın.
  • · Token'lar origin'e bağlıdır: ele geçirilen bir token başka yerde yüklenemez.
  • · Oda anahtarı Eyena'ya hiç ulaşmaz. Onu panonun içeriği gibi koruyun — anahtara vegeçerli bir token'a sahip olan panoyu okuyabilir.

API Referansı

POST https://api.eyena.net/api/embed/board-session

Başlıklar: Authorization: Bearer {access_token}, Content-Type: application/json, Origin: {kayıtlı origin}.

{
  "boardToken": "eyJhbGci...",
  "expiresAt": "2026-08-07T14:00:00Z",
  "roomId": "9f2b7c1d4e6a8b0c2d4e",
  "role": "instructor"
}
DurumAnlamı
400role veya displayName eksik, geçersiz role, ya da roomId olmadan student
403Bilinmeyen/pasif istemci, pano izni yok, origin izinli değil veya shareUrl origin dışında
404roomId bulunamadı

iframe URL'si

https://board.eyena.net/embed?token={boardToken}#key={roomKey}

Sırada ne var?

Çalışan bir örnek için pano demosunu açın; göz takipli test çözme akışı için ödev dökümantasyonuna bakın.