File size: 9,920 Bytes
c551e64
 
 
 
 
 
 
 
 
 
 
40911ca
b7231b5
 
 
 
 
 
 
 
 
 
 
 
 
 
659efa8
 
 
 
b7231b5
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
bac7ea5
b7231b5
 
 
 
 
bac7ea5
b7231b5
 
 
 
 
bac7ea5
 
 
b7231b5
 
 
 
 
 
 
 
 
 
 
bac7ea5
b7231b5
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
bac7ea5
b7231b5
 
 
 
 
 
 
 
 
 
 
 
 
bac7ea5
b7231b5
 
 
 
 
659efa8
b7231b5
 
 
bac7ea5
b7231b5
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
659efa8
b7231b5
bac7ea5
b7231b5
bac7ea5
 
 
 
b7231b5
bac7ea5
b7231b5
bac7ea5
b7231b5
 
 
659efa8
b7231b5
bac7ea5
b7231b5
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
bac7ea5
b7231b5
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
bac7ea5
b7231b5
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
659efa8
b7231b5
 
 
bac7ea5
b7231b5
bac7ea5
b7231b5
 
 
 
 
 
 
 
 
 
 
bac7ea5
b7231b5
 
 
bac7ea5
b7231b5
 
 
 
 
 
 
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
---
title: CAPS04 FE REFACTOR
emoji: πŸš€
colorFrom: blue
colorTo: indigo
sdk: docker
app_port: 7860
pinned: false
---

# CAPS04 FE REFACTOR
A Syududu
---

## Embed Widget β€” Integration Guide

RAG Hub menyediakan widget chat berbasis `<iframe>` yang dapat diintegrasikan ke situs web pihak ketiga manapun. Widget ini mendukung autentikasi berbasis API Key, kustomisasi tampilan penuh melalui query string, serta komunikasi dua arah dengan halaman induk melalui `postMessage`.

---

### Table of Contents

1. [Quick Start](#1-quick-start)
2. [Authentication](#2-authentication)
3. [URL Parameters Reference](#3-url-parameters-reference)
4. [Theming & Customization](#4-theming--customization)
5. [postMessage Events](#5-postmessage-events)
6. [Session Persistence](#6-session-persistence)
7. [Full Integration Examples](#7-full-integration-examples)
8. [Troubleshooting](#8-troubleshooting)

---

### 1. Quick Start

Tambahkan `<iframe>` berikut ke halaman HTML Anda:

```html
<iframe
  src="https://your-raghub-domain.com/embed?api_key=YOUR_API_KEY"
  width="420"
  height="680"
  style="border: none; border-radius: 16px;"
  allow="clipboard-write"
></iframe>
```

Ganti `YOUR_API_KEY` dengan API Key yang digenerate dari halaman **Admin β†’ API Keys**.

---

### 2. Authentication

Widget menggunakan API Key untuk autentikasi. Saat pertama kali dimuat, widget menukar API Key dengan bearer token melalui endpoint `/auth/login/api-key`, lalu menyimpan token tersebut ke cookie browser selama **7 hari**.

```
/embed?api_key=sk-xxxxxxxxxxxxxxxx
```

Selama cookie masih valid, widget tidak akan login ulang meski halaman di-refresh. Cookie otomatis dihapus setelah 7 hari atau jika browser cookie dibersihkan.

#### Token Resolution Priority

Widget menyelesaikan autentikasi dengan urutan berikut:

1. Cek cookie β€” jika token sudah tersimpan dan belum expired, langsung digunakan.
2. Cek parameter `?api_key` di URL, tukar dengan token via API, simpan ke cookie.
3. Jika tidak ada keduanya β†’ widget menampilkan pesan error autentikasi.

---

### 3. URL Parameters Reference

Semua konfigurasi dilakukan melalui query string pada URL `src` iframe.

#### 3.1 Authentication

| Parameter | Tipe     | Keterangan |
|-----------|----------|------------|
| `api_key` | `string` | API Key dari Admin Panel. Widget otomatis login dan menyimpan token ke cookie. |

#### 3.2 Behavior

| Parameter    | Tipe     | Default | Keterangan |
|--------------|----------|---------|------------|
| `course_id`  | `string` | β€”       | Pra-pilih mata kuliah tertentu. Widget langsung menggunakan course ini tanpa perlu user memilih. |
| `session_id` | `string` | β€”       | Buka riwayat sesi chat tertentu langsung saat widget dimuat. |
| `user_name`  | `string` | `User`  | Nama yang ditampilkan di greeting ("Good Morning, ..."). Jika tidak diisi, diambil dari data user saat login via `api_key`. |

#### 3.3 Appearance

| Parameter    | Tipe     | Default | Keterangan |
|--------------|----------|---------|------------|
| `title`      | `string` | `RAG Hub` | Judul widget (tab browser & empty state). |
| `subtitle`   | `string` | *(default text)* | Teks deskripsi di bawah judul pada empty state. |

---

### 4. Theming & Customization

Semua warna dikustomisasi via query string. Format nilai warna: hex 3-digit (`#fff`) atau 6-digit (`#ffffff`), dengan atau tanpa `#` di depan.

Format radius: nilai numerik diikuti unit `px` atau `rem` (maks. 2 digit), contoh: `20px`, `1rem`.

| Parameter            | Default     | Keterangan |
|----------------------|-------------|------------|
| `primary`            | `#2764eb`   | Warna utama β€” tombol kirim, avatar asisten, border composer. |
| `primary_gradient`   | `#ccdcff`   | Warna lembut primary β€” background avatar user & aksen gradient. |
| `background`         | `#ffffff`   | Background utama widget. |
| `background_profile` | `#ffffff`   | Background bubble chat asisten dan composer. |
| `text_primary`       | `#0a0a0a`   | Warna teks utama. |
| `text_secondary`     | `#737373`   | Warna teks sekunder / placeholder. |
| `border`             | `#739af1`   | Warna border composer dan bubble. |
| `danger`             | `#ef4444`   | Warna aksi destruktif (tombol hapus sesi). |
| `radius`             | `20px`      | Border radius bubble chat dan composer. |

**Contoh URL dengan tema gelap:**

```
/embed?api_key=YOUR_KEY
  &background=1a1a2e
  &background_profile=16213e
  &text_primary=e0e0e0
  &text_secondary=8892b0
  &primary=4f8ef7
  &primary_gradient=1e3a6e
  &border=2a3f6f
  &danger=ff6b6b
  &radius=16px
```

---

### 5. postMessage Events

Widget berkomunikasi dengan halaman induk melalui `window.postMessage`. Dengarkan event ini di halaman yang meng-embed iframe untuk mendapat notifikasi dari widget.

#### 5.1 Events yang Dikirim Widget (Outbound)

| Event type                  | Kapan dikirim |
|-----------------------------|---------------|
| `sevima-raghub:close`       | User menekan tombol **βœ•** di sudut kanan atas widget. |

**Contoh listener di halaman induk:**

```javascript
window.addEventListener('message', (event) => {
  // Selalu validasi origin di produksi
  if (event.origin !== 'https://your-raghub-domain.com') return;

  if (event.data?.type === 'sevima-raghub:close') {
    // Sembunyikan atau hancurkan iframe
    document.getElementById('raghub-iframe').style.display = 'none';
  }
});
```

---

### 6. Session Persistence

Widget menyimpan data sesi di **cookie browser** dengan masa berlaku 7 hari. Cookie diset pada domain RAG Hub (domain iframe), sehingga tidak dapat diakses oleh halaman induk.

| Cookie name                  | Isi | TTL |
|------------------------------|-----|-----|
| `sevima_raghub_embed_token`  | Bearer token aktif. | 7 hari |
| `sevima_raghub_embed_user`   | Objek user JSON (`id`, `name`, `email`, `role`). | 7 hari |

Selama cookie masih valid, widget tidak akan memanggil ulang `/auth/login/api-key` meski halaman di-refresh atau tab ditutup lalu dibuka kembali.

Untuk memaksa login ulang (reset sesi), reload iframe dengan mengganti `src` β€” cookie lama akan diabaikan saat API Key baru ditukar.

---

### 7. Full Integration Examples

#### 7.1 Embed Sederhana

```html
<!DOCTYPE html>
<html lang="id">
<head>
  <meta charset="UTF-8" />
  <title>My App</title>
</head>
<body>

  <iframe
    id="raghub-widget"
    src="https://your-raghub-domain.com/embed?api_key=sk-xxxx&user_name=Budi&title=Asisten+Akademik"
    width="420"
    height="680"
    style="border: none; border-radius: 20px; box-shadow: 0 8px 32px rgba(0,0,0,0.15);"
    allow="clipboard-write"
  ></iframe>

  <script>
    window.addEventListener('message', (event) => {
      if (event.origin !== 'https://your-raghub-domain.com') return;
      if (event.data?.type === 'sevima-raghub:close') {
        document.getElementById('raghub-widget').style.display = 'none';
      }
    });
  </script>

</body>
</html>
```

#### 7.2 Floating Chat Button

```html
<style>
  #raghub-fab {
    position: fixed;
    bottom: 24px;
    right: 24px;
    width: 56px;
    height: 56px;
    border-radius: 50%;
    background: #2764eb;
    border: none;
    cursor: pointer;
    color: #fff;
    font-size: 24px;
    box-shadow: 0 4px 16px rgba(39,100,235,0.4);
    z-index: 1000;
  }

  #raghub-container {
    display: none;
    position: fixed;
    bottom: 96px;
    right: 24px;
    width: 420px;
    height: 680px;
    z-index: 1000;
    border-radius: 20px;
    overflow: hidden;
    box-shadow: 0 12px 48px rgba(0,0,0,0.2);
  }

  #raghub-container iframe {
    width: 100%;
    height: 100%;
    border: none;
  }
</style>

<button id="raghub-fab" onclick="toggleWidget()">πŸ’¬</button>

<div id="raghub-container">
  <iframe
    id="raghub-iframe"
    src="https://your-raghub-domain.com/embed?api_key=sk-xxxx&primary=2764eb&radius=16px"
    allow="clipboard-write"
  ></iframe>
</div>

<script>
  function toggleWidget() {
    const container = document.getElementById('raghub-container');
    container.style.display = container.style.display === 'none' ? 'block' : 'none';
  }

  window.addEventListener('message', (event) => {
    if (event.origin !== 'https://your-raghub-domain.com') return;
    if (event.data?.type === 'sevima-raghub:close') {
      document.getElementById('raghub-container').style.display = 'none';
    }
  });
</script>
```

#### 7.3 Pra-pilih Mata Kuliah & Langsung ke Sesi Tertentu

```html
<iframe
  src="https://your-raghub-domain.com/embed
    ?api_key=sk-xxxx
    &course_id=COURSE_UUID
    &session_id=SESSION_UUID
    &user_name=Mahasiswa+A"
  width="420"
  height="680"
  style="border: none; border-radius: 20px;"
></iframe>
```

---

### 8. Troubleshooting

#### Widget menampilkan "Token iframe tidak tersedia"

Pastikan parameter `?api_key=` ada di URL `src` iframe dan API Key tersebut masih aktif serta belum direvoke di Admin Panel.

Jika cookie lama ada tapi sudah expired, hapus cookie `sevima_raghub_embed_token` dari browser lalu reload.

#### Mata kuliah tidak muncul di dropdown

Pastikan akun yang terkait dengan `api_key` memiliki akses ke setidaknya satu course. Periksa di Admin Panel bahwa course sudah berstatus **active**.

#### Widget tidak merespons tombol βœ• di halaman induk

Pastikan listener `message` event sudah terpasang sebelum iframe dimuat, dan validasi `event.origin` sesuai domain RAG Hub.

#### Token expired di tengah sesi

Widget tidak melakukan refresh token otomatis. Jika token expired, cukup reload iframe β€” widget akan menukar `api_key` yang sama dengan token baru dan menyimpannya ke cookie:

```javascript
const iframe = document.getElementById('raghub-iframe');
iframe.src = iframe.src; // trigger reload
```

#### Warna tidak berubah setelah mengubah query string

Pastikan nilai warna dalam format hex yang valid: 3 atau 6 digit, dengan atau tanpa `#`. Karakter selain `0-9` dan `a-f` akan diabaikan dan diganti nilai default.

---