Eyena Board Embed API — tam rehber
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
PanoIzni) verilmiş bir client_id + client_secret. Pano erişimi varsayılan olarak kapalıdır — mevcut istemciler yalnızca testler için yetkilidir.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ı dinleyinPano 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.
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.
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()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()| Alan | Zorunlu | Not |
|---|---|---|
| role | evet | 'instructor' veya 'student' — varsayılanı yoktur |
| displayName | evet | Diğer katılımcılara gösterilir |
| roomId | öğrenciler için | Yalnızca eğitmen yeni pano açarken boş bırakılır |
| baslik | hayır | Pano başlığı |
| shareUrl | hayır | Kendi 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önderinRol 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:
| instructor | student | |
|---|---|---|
| Göz takibi onayı | gösterilmez | katılırken gösterilir |
| Kalibrasyon ekranı | gösterilmez | onaydan sonra gösterilir |
| Kamera erişimi | istenmez | onaydan sonra istenir |
| Bağlantı kopyala / bakış düğmeleri | gösterilir | gizlidir |
| Bakış verisi | alı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.
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/9f2b7c1d4e6a8b0c2d4eKatı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.
<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.
| event.data.type | Ne zaman | Payload |
|---|---|---|
| eyena-board-ready | Token doğrulandı, katılmadan önce | { roomId, role } |
| eyena-board-joined | Odaya bağlanıldı | { roomId, role } |
| eyena-board-error | Token geçersiz/süresi dolmuş ya da anahtar yok | { reason } |
| eyena-board-share | Eğitmen paylaşım bağlantısını kopyaladı | { roomId, shareUrl } |
| eyena-board-voice-error | Ses başlatılamadı ya da mikrofon açılamadı | { reason } |
reason değeri invalid-token veya missing-room-key olur.
Öğ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.
client_secret veya access_token'ı asla tarayıcıya sızdırmayın.boardToken üretin; oturumlar arasında önbelleğe almayın.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"
}| Durum | Anlamı |
|---|---|
| 400 | role veya displayName eksik, geçersiz role, ya da roomId olmadan student |
| 403 | Bilinmeyen/pasif istemci, pano izni yok, origin izinli değil veya shareUrl origin dışında |
| 404 | roomId bulunamadı |
iframe URL'si
https://board.eyena.net/embed?token={boardToken}#key={roomKey}Çalışan bir örnek için pano demosunu açın; göz takipli test çözme akışı için ödev dökümantasyonuna bakın.