tracking-lib-ott 1.0.13 → 1.0.14

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md CHANGED
@@ -1,8 +1,6 @@
1
1
  # Tracking Library OTT
2
2
 
3
- Thư viện tracking events dành cho các dự án OTT (Web, iOS, Android).
4
- npm version patch
5
- npm publish
3
+ Thư viện tracking events dành cho các dự án OTT (Web, Smart TV).
6
4
 
7
5
  ## Cài đặt
8
6
 
@@ -12,6 +10,21 @@ npm install tracking-lib-ott
12
10
  yarn add tracking-lib-ott
13
11
  ```
14
12
 
13
+ ---
14
+
15
+ ## API Endpoint
16
+
17
+ | Property | Value |
18
+ | ------------ | --------------------------------- |
19
+ | Method | `POST` |
20
+ | URL | `/v2/event_batch` |
21
+ | Content-Type | `application/json` |
22
+ | Giới hạn | Tối đa **200 events** mỗi request |
23
+
24
+ > **Cơ chế**: Thông tin chung đặt ở cấp top-level, phần sự kiện nằm trong mảng `events`. Server sẽ hợp nhất thông tin chung vào từng event trước khi gửi vào Kafka.
25
+
26
+ ---
27
+
15
28
  ## Sử dụng cơ bản
16
29
 
17
30
  ### 1. Khởi tạo (Init)
@@ -20,442 +33,321 @@ yarn add tracking-lib-ott
20
33
  import tracking from "tracking-lib-ott";
21
34
 
22
35
  tracking.init({
23
- baseURL: "https://api.example.com/v1/event_batch",
24
- debug: true, // Bật log để debug
36
+ baseURL: "https://api.example.com/v2/event_batch",
37
+ debug: true,
25
38
 
26
- // Thông tin bắt buộc
27
- session_id, // Sẽ được tự sinh ra khi init session tracking và K cần thêm vì đã trong thư viện đã tự động làm việc đó
28
- session_sign: "session-signature", // Mỗi SDK client init bằng một key sign cho message. Sử dụng phương thức sign như sau:MD5(append(session_id,secret_key)) secret_key: Server cùng cấp để init SDK
29
- user_id: 12345,
39
+ // Required fields
40
+ appId: "ONPlus", // ONPlus, ONLiveTV
41
+ packageId: "com.vtvcab.onsportstv",
42
+ sessionId: "uuid-v4-session-id", // Hoặc để trống sẽ tự động tạo từ cookie
43
+ sessionSign: "md5_signature", // MD5(append(session_id, secret_key))
30
44
  deviceId: "device-unique-id",
31
- deviceModel: "iPhone 14",
32
- deviceBrand: "Apple",
33
- ip_address: "192.168.1.1",
34
-
35
- // Thông tin tuỳ chọn
36
- appName: "app_name",
37
- appId: "app-id",
38
- packageId: "Là package hoặc bundle id nếu website là domain website",
39
- platform: "Web", // 'Web' | 'Ios' | 'Android'
40
- os_version: "17.0",
41
- app_version: "1.0.0",
42
- language: "vi",
43
- country: "VN",
44
- net_type: "Loại mạng mà khác hàng đang kết nối",
45
+ platform: "SmartTV", // WebPC | WebMobile | SmartTV | AndroidTV
46
+ deviceModel: "Samsung TV 2024",
47
+ deviceBrand: "Samsung",
48
+ events: [],
49
+
50
+ // Optional fields
51
+ adId: "gaid-or-idfa",
52
+ deviceOsVersion: "17.0",
53
+ sdkVersion: "1.0.0",
45
54
  });
46
55
  ```
47
56
 
48
- ### 2. Track Page View
57
+ ### 2. Set User Info
58
+
59
+ ```javascript
60
+ // Khi user đăng nhập -> set userId
61
+ // userId sẽ tự động được thêm vào mỗi event
62
+ tracking.setUserInfo({ userId: 12345 });
63
+
64
+ // Khi user đăng xuất
65
+ tracking.setUserInfo({ userId: -1 });
66
+ ```
67
+
68
+ ### 3. Track Page View
49
69
 
50
70
  ```javascript
51
- // Track khi user vào một trang
52
71
  tracking.trackPageView("/home");
53
72
  tracking.trackPageView("/detail/123");
54
73
  tracking.trackPageView("/live/channel-1");
55
74
  ```
56
75
 
57
- ### 3. Track Custom Event
76
+ ### 4. Track Custom Event
58
77
 
59
78
  ```javascript
60
- // Track event tuỳ ý với params
61
79
  tracking.trackEvent("button_click", {
62
80
  button_id: "subscribe_btn",
63
81
  page_id: "detail",
64
82
  });
65
83
 
66
- tracking.trackEvent("video_play", {
67
- video_id: "12345",
68
- video_title: "Trận đấu hay nhất",
69
- duration: 3600,
70
- });
71
-
72
84
  tracking.trackEvent("search", {
73
85
  keyword: "bóng đá",
74
86
  results_count: 25,
75
87
  });
76
88
  ```
77
89
 
78
- ### 4. Send Event trực tiếp
79
-
80
- ```javascript
81
- // Gửi event với full control payload
82
- await tracking.sendEvent({
83
- event_name: "custom_event",
84
- custom_field_1: "value1",
85
- custom_field_2: "value2",
86
- });
87
- ```
88
-
89
90
  ---
90
91
 
91
- ## Tích hợp Next.js (Pages Router)
92
+ ## Video Playback Events
92
93
 
93
- ### Trong `_app.js` hoặc `_app.tsx`
94
+ Thư viện hỗ trợ các events cho video player:
94
95
 
95
- ```javascript
96
- import { useEffect } from "react";
97
- import { useRouter } from "next/router";
98
- import tracking from "tracking-lib-ott";
99
-
100
- function MyApp({ Component, pageProps }) {
101
- const router = useRouter();
96
+ ### Flow tracking video
102
97
 
103
- useEffect(() => {
104
- // Khởi tạo tracking
105
- tracking.init({
106
- baseURL: process.env.NEXT_PUBLIC_TRACKING_URL,
107
- session_id: "session-id-from-somewhere",
108
- session_sign: "session-sign",
109
- user_id: 12345,
110
- deviceId: "device-id",
111
- deviceModel: navigator.userAgent,
112
- deviceBrand: "Web Browser",
113
- ip_address: "", // Lấy từ API hoặc để trống
114
- debug: process.env.NODE_ENV === "development",
115
- });
116
-
117
- // Auto track page views
118
- const cleanup = tracking.usePageViewTracking(router);
119
-
120
- return cleanup;
121
- }, [router]);
122
-
123
- return <Component {...pageProps} />;
124
- }
125
-
126
- export default MyApp;
98
+ ```
99
+ view_content_details playback_started → playback_progress (định kỳ) → playback_completed
100
+ ↘ playback_paused ↔ playback_resumed
101
+ buffer_started → buffer_ended
102
+ quality_changed
103
+ playback_error
127
104
  ```
128
105
 
129
- ---
130
-
131
- ## Session Lifecycle Tracking
132
-
133
- Thư viện hỗ trợ tự động track session của user:
134
-
135
- | Event | Khi nào gọi | Mô tả |
136
- | ------------------ | ------------------------- | ------------------------------ |
137
- | `session_start` | User mở app | Gọi 1 lần khi init |
138
- | `session_progress` | Định kỳ (mặc định 5 phút) | Heartbeat khi user đang active |
139
- | `session_end` | User đóng tab/browser/app | Tự động detect |
140
-
141
- ### Cách sử dụng
106
+ ### 1. View Content Details
142
107
 
143
108
  ```javascript
144
- import { useEffect } from "react";
145
- import tracking from "tracking-lib-ott";
109
+ import { trackViewContentDetails } from "tracking-lib-ott";
110
+
111
+ trackViewContentDetails(
112
+ "content_123", // contentId
113
+ "Phim ABC", // contentTitle
114
+ 0, // contentType: 0=VOD, 1=Event, 2=Channel
115
+ "channel_vtv1", // channelId (optional)
116
+ 1755766513, // eventTime (optional)
117
+ );
118
+ ```
146
119
 
147
- function MyApp({ Component, pageProps }) {
148
- useEffect(() => {
149
- // 1. Init tracking trước
150
- tracking.init({
151
- baseURL: "https://api.example.com/v1/event_batch",
152
- sessionId: "session-id", // K cần thêm vì đã trong thư viện đã tự động làm việc đó
153
- sessionSign: "session-sign",
154
- // ... other config
155
- });
120
+ ### 2. Playback Started
156
121
 
157
- // 2. Init session tracking (tự động gọi session_start)
158
- tracking.initSession({
159
- progressInterval: 5 * 60 * 1000, // 5 phút (ms)
160
- autoStart: true,
161
- debug: true,
162
- userId: "12345",
163
- });
122
+ ```javascript
123
+ import { trackPlaybackStarted } from "tracking-lib-ott";
124
+
125
+ trackPlaybackStarted({
126
+ contentId: "content_123",
127
+ contentTitle: "Phim ABC",
128
+ contentType: 0, // 0=VOD, 1=Live, 2=Channel
129
+ playbackSession: "md5_session_hash", // MD5(content_id + start_timestamp)
130
+ videoQuality: "1080p", // 360p | 480p | 720p | 1080p | 2k | 4k
131
+ startTimestamp: 1755766513,
132
+ startPosition: 0, // Live=0, VOD: 0 nếu mới, >0 nếu resume
133
+ duration: 3600, // Live=-1, VOD=số giây
134
+ // Optional
135
+ channelId: "channel_vtv1",
136
+ subContentId: "program_456",
137
+ subContentTitle: "Thời sự 19h",
138
+ });
139
+ ```
164
140
 
165
- // 3. Cleanup khi unmount
166
- return () => {
167
- tracking.cleanupSession();
168
- };
169
- }, []);
141
+ ### 3. Playback Progress (gửi định kỳ 5s/25s)
170
142
 
171
- return <Component {...pageProps} />;
172
- }
143
+ ```javascript
144
+ import { trackPlaybackProgress } from "tracking-lib-ott";
145
+
146
+ trackPlaybackProgress({
147
+ contentId: "content_123",
148
+ contentTitle: "Phim ABC",
149
+ contentType: 0,
150
+ playbackSession: "md5_session_hash",
151
+ totalWatchTime: 60, // Tổng thời gian đã xem (giây, không tính pause)
152
+ // Optional
153
+ channelId: "channel_vtv1",
154
+ subContentId: "program_456",
155
+ subContentTitle: "Thời sự 19h",
156
+ });
173
157
  ```
174
158
 
175
- ### Session Config Options
159
+ ### 4. Playback Completed
176
160
 
177
- | Option | Type | Default | Mô tả |
178
- | ------------------ | ------- | ------------- | ------------------------------------- |
179
- | `progressInterval` | number | `300000` (5m) | Khoảng thời gian gửi session_progress |
180
- | `autoStart` | boolean | `true` | Tự động gọi session_start khi init |
181
- | `debug` | boolean | `false` | Hiển thị log |
182
- | `userId` | string | `undefined` | User ID để gửi kèm session_end |
161
+ ```javascript
162
+ import { trackPlaybackCompleted } from "tracking-lib-ott";
163
+
164
+ trackPlaybackCompleted({
165
+ contentId: "content_123",
166
+ contentTitle: "Phim ABC",
167
+ contentType: 0,
168
+ playbackSession: "md5_session_hash",
169
+ totalWatchTime: 3600,
170
+ // Optional
171
+ channelId: "channel_vtv1",
172
+ subContentId: "program_456",
173
+ subContentTitle: "Thời sự 19h",
174
+ });
175
+ ```
183
176
 
184
- ### Session Events Payload
177
+ ### 5. Playback Paused / Resumed
185
178
 
186
- ```json
187
- // session_start
188
- {
189
- "events": [{
190
- "event_name": "session_start",
191
- "event_time": 1705734000000,
192
- "user_id": "12345"
179
+ ```javascript
180
+ import { trackPlaybackPaused, trackPlaybackResumed } from "tracking-lib-ott";
181
+
182
+ // Khi user pause
183
+ trackPlaybackPaused({
184
+ contentId: "content_123",
185
+ contentTitle: "Phim ABC",
186
+ contentType: 0,
187
+ playbackSession: "md5_session_hash",
188
+ positionSec: 120,
189
+ });
193
190
 
194
- }]
195
- }
191
+ // Khi user resume
192
+ trackPlaybackResumed({
193
+ contentId: "content_123",
194
+ contentTitle: "Phim ABC",
195
+ contentType: 0,
196
+ playbackSession: "md5_session_hash",
197
+ positionSec: 120,
198
+ });
199
+ ```
196
200
 
197
- // session_progress (mỗi 5 phút)
198
- {
199
- "events": [{
200
- "event_name": "session_progress",
201
- "event_time": 1705734300000,
202
- "session_duration": 300000,
203
- "user_id": "12345"
201
+ ### 6. Buffer Started / Ended
204
202
 
205
- }]
206
- }
203
+ ```javascript
204
+ import { trackBufferStarted, trackBufferEnded } from "tracking-lib-ott";
205
+
206
+ // Khi bắt đầu buffer
207
+ trackBufferStarted({
208
+ contentId: "content_123",
209
+ contentTitle: "Phim ABC",
210
+ contentType: 0,
211
+ playbackSession: "md5_session_hash",
212
+ videoQuality: "1080p",
213
+ positionSec: 120,
214
+ reason: "network_congestion", // seek_operation | network_congestion
215
+ });
207
216
 
208
- // session_end (khi đóng tab/app)
209
- {
210
- "events": [{
211
- "event_name": "session_end",
212
- "event_time": 1705735800000,
213
- "session_duration": 1800000,
214
- "user_id": "12345"
215
- }]
216
- }
217
+ // Khi kết thúc buffer
218
+ trackBufferEnded({
219
+ contentId: "content_123",
220
+ contentTitle: "Phim ABC",
221
+ contentType: 0,
222
+ playbackSession: "md5_session_hash",
223
+ videoQuality: "1080p",
224
+ positionSec: 120,
225
+ bufferDurationSec: 3, // Buffer mất 3 giây
226
+ reason: "network_congestion",
227
+ });
217
228
  ```
218
229
 
219
- ### Các API khác
230
+ ### 7. Quality Changed
220
231
 
221
232
  ```javascript
222
- import {
223
- sendSessionStart,
224
- sendSessionEnd,
225
- sendSessionProgress,
226
- isSessionStarted,
227
- getSessionDuration,
228
- updateSessionConfig,
229
- } from "tracking-lib-ott";
230
-
231
- // Gọi manual nếu cần
232
- sendSessionStart(); // Bắt đầu session
233
- sendSessionProgress(); // Gửi heartbeat
234
- sendSessionEnd(); // Kết thúc session
235
-
236
- // Kiểm tra trạng thái
237
- isSessionStarted(); // true/false
238
- getSessionDuration(); // ms đã chạy
239
-
240
- // Cập nhật config
241
- updateSessionConfig({ progressInterval: 10 * 60 * 1000 });
233
+ import { trackQualityChanged } from "tracking-lib-ott";
234
+
235
+ trackQualityChanged({
236
+ contentId: "content_123",
237
+ contentTitle: "Phim ABC",
238
+ contentType: 0,
239
+ playbackSession: "md5_session_hash",
240
+ fromQuality: "480p",
241
+ toQuality: "1080p",
242
+ positionSec: 120,
243
+ reason: "user_selected", // automatic_abr | user_selected
244
+ });
242
245
  ```
243
246
 
244
- ### chế hoạt động
245
-
246
- 1. **`session_start`**: Gọi tự động khi `initSession()` với `autoStart: true`
247
- 2. **`session_progress`**: Timer chạy định kỳ, chỉ gửi khi tab visible
248
- 3. **`session_end`**: Detect qua `beforeunload` (desktop) và `pagehide` (mobile)
247
+ ### 8. Playback Error
249
248
 
250
- > **Lưu ý**: Khi user switch tab, timer sẽ tạm dừng và resume khi user quay lại.
249
+ ```javascript
250
+ import { trackPlaybackError } from "tracking-lib-ott";
251
+
252
+ trackPlaybackError({
253
+ contentId: "content_123",
254
+ contentTitle: "Phim ABC",
255
+ contentType: 0, // 0=VOD, 1=Live
256
+ playbackSession: "md5_session_hash",
257
+ errorCode: 404,
258
+ errorMessage: "Video not found",
259
+ errorType: "network_error", // video_playback_error, network_error...
260
+ });
261
+ ```
251
262
 
252
263
  ---
253
264
 
254
- ## Session ID Cookie Management
255
-
256
- Thư viện hỗ trợ **tự động quản lý `session_id`** thông qua cookie. Nếu bạn không truyền `session_id` khi khởi tạo, thư viện sẽ tự động tạo và lưu vào cookie với thời hạn 30 phút.
257
-
258
- ### Tính năng
259
-
260
- - ✅ **Tự động tạo** `session_id` nếu không được truyền lên
261
- - ✅ **Lưu vào cookie** với thời hạn mặc định 30 phút
262
- - ✅ **Hỗ trợ group domain** (ví dụ: `.example.com`)
263
- - ✅ **Tự động gia hạn** cookie mỗi khi có event `session_start`
264
- - ✅ **Persistent** - Session ID được giữ nguyên khi refresh trang trong vòng 30 phút
265
-
266
- ### Cách sử dụng
265
+ ## Session Lifecycle Tracking
267
266
 
268
- #### 1. Auto-generate Session ID (Khuyến nghị)
267
+ | Event | Khi nào gọi |
268
+ | ------------------ | ------------------------- |
269
+ | `session_start` | User mở app |
270
+ | `session_progress` | Định kỳ (mặc định 5 phút) |
271
+ | `session_end` | User đóng tab/browser/app |
269
272
 
270
273
  ```javascript
271
274
  import tracking from "tracking-lib-ott";
272
275
 
273
- // Không cần truyền session_id - thư viện tự động tạo và lưu cookie
274
- tracking.init({
275
- baseURL: "https://api.example.com/v1/event_batch",
276
- sessionSign: "session-signature",
277
- userId: 12345,
278
- deviceId: "device-unique-id",
279
- deviceModel: "iPhone 14",
280
- deviceBrand: "Apple",
281
- ipAddress: "192.168.1.1",
276
+ // Init session tracking
277
+ tracking.initSession({
278
+ progressInterval: 5 * 60 * 1000, // 5 phút
279
+ autoStart: true,
282
280
  debug: true,
283
281
  });
284
282
 
285
- // Session ID đã được tạo tự động và lưu vào cookie: _tracking_session_id
283
+ // Cleanup khi unmount
284
+ tracking.cleanupSession();
286
285
  ```
287
286
 
288
- #### 2. Custom Cookie Configuration
289
-
290
- ```javascript
291
- tracking.init({
292
- baseURL: "https://api.example.com/v1/event_batch",
293
- sessionSign: "session-signature",
294
- userId: 12345,
295
- deviceId: "device-unique-id",
296
- deviceModel: "iPhone 14",
297
- deviceBrand: "Apple",
298
- ipAddress: "192.168.1.1",
299
-
300
- // Cấu hình cookie tùy chỉnh
301
- sessionCookieConfig: {
302
- cookieName: "my_session_id", // Tên cookie (mặc định: _tracking_session_id)
303
- expirationMinutes: 60, // Thời hạn 60 phút (mặc định: 30)
304
- domain: ".example.com", // Group domain cho tất cả subdomain
305
- path: "/", // Cookie path
306
- sameSite: "Lax", // 'Strict' | 'Lax' | 'None'
307
- },
308
-
309
- debug: true,
310
- });
311
- ```
287
+ ---
312
288
 
313
- #### 3. Kết hợp với Session Tracking
289
+ ## Tích hợp Next.js (Pages Router)
314
290
 
315
291
  ```javascript
316
292
  import { useEffect } from "react";
293
+ import { useRouter } from "next/router";
317
294
  import tracking from "tracking-lib-ott";
318
295
 
319
296
  function MyApp({ Component, pageProps }) {
297
+ const router = useRouter();
298
+
320
299
  useEffect(() => {
321
- // 1. Init tracking (session_id tự động tạo)
300
+ // 1. Init tracking
322
301
  tracking.init({
323
- baseURL: "https://api.example.com/v1/event_batch",
324
- sessionSign: "session-signature",
325
- userId: 12345,
302
+ baseURL: process.env.NEXT_PUBLIC_TRACKING_URL,
303
+ appId: "ONPlus",
304
+ packageId: "com.example.app",
305
+ sessionSign: "session-sign",
326
306
  deviceId: "device-id",
307
+ platform: "WebPC",
327
308
  deviceModel: navigator.userAgent,
328
309
  deviceBrand: "Web Browser",
329
- ipAddress: "",
330
- sessionCookieConfig: {
331
- domain: ".example.com",
332
- expirationMinutes: 30,
333
- },
310
+ events: [],
334
311
  debug: process.env.NODE_ENV === "development",
335
312
  });
336
313
 
337
- // 2. Init session tracking
338
- tracking.initSession({
339
- autoStart: true,
340
- progressInterval: 5 * 60 * 1000,
341
- sessionCookieConfig: {
342
- domain: ".example.com",
343
- expirationMinutes: 30,
344
- },
345
- });
314
+ // 2. Set user info (after login)
315
+ tracking.setUserInfo({ userId: 12345 });
316
+
317
+ // 3. Auto track page views
318
+ const cleanup = tracking.usePageViewTracking(router);
319
+
320
+ // 4. Init session tracking
321
+ tracking.initSession({ autoStart: true });
346
322
 
347
323
  return () => {
324
+ cleanup?.();
348
325
  tracking.cleanupSession();
349
326
  };
350
- }, []);
327
+ }, [router]);
351
328
 
352
329
  return <Component {...pageProps} />;
353
330
  }
354
- ```
355
-
356
- ### Cookie Configuration Options
357
-
358
- | Option | Type | Default | Mô tả |
359
- | ------------------- | --------------------------------- | ---------------------- | --------------------------------------------------------- |
360
- | `cookieName` | string | `_tracking_session_id` | Tên cookie lưu session_id |
361
- | `expirationMinutes` | number | `30` | Thời gian hết hạn cookie (phút) |
362
- | `domain` | string | `""` | Domain cho cookie (hỗ trợ group domain như `.domain.com`) |
363
- | `path` | string | `"/"` | Cookie path |
364
- | `sameSite` | `"Strict"` \| `"Lax"` \| `"None"` | `"Lax"` | SameSite attribute |
365
-
366
- ### Cơ chế hoạt động
367
331
 
368
- 1. **Lần đầu khởi tạo** (không có cookie):
369
- - Thư viện tạo `session_id` mới (format: `{timestamp}_{random}`)
370
- - Lưu vào cookie với thời hạn 30 phút
371
- - Ví dụ: `1737603823000_a8f3d9e2`
372
-
373
- 2. **Refresh trang** (trong vòng 30 phút):
374
- - Thư viện đọc `session_id` từ cookie
375
- - Sử dụng lại session_id cũ
376
- - Không tạo session mới
377
-
378
- 3. **Session Start Event**:
379
- - Mỗi khi có event `session_start`
380
- - Cookie được **gia hạn thêm 30 phút** từ thời điểm hiện tại
381
- - Ví dụ: 9:15 trigger session_start → cookie expires lúc 9:45
382
-
383
- 4. **Sau 30 phút không hoạt động**:
384
- - Cookie hết hạn và bị xóa
385
- - Lần truy cập tiếp theo sẽ tạo `session_id` mới
386
-
387
- ### Manual Cookie Management
388
-
389
- ```javascript
390
- import {
391
- generateSessionId,
392
- getCookie,
393
- setCookie,
394
- getOrCreateSessionId,
395
- renewSessionCookie,
396
- clearSessionCookie,
397
- } from "tracking-lib-ott";
398
-
399
- // Tạo session ID mới
400
- const newSessionId = generateSessionId();
401
- console.log(newSessionId); // "1737603823000_a8f3d9e2"
402
-
403
- // Lấy hoặc tạo session ID
404
- const sessionId = getOrCreateSessionId({
405
- cookieName: "my_session",
406
- expirationMinutes: 30,
407
- domain: ".example.com",
408
- });
409
-
410
- // Gia hạn cookie
411
- renewSessionCookie(sessionId, {
412
- cookieName: "my_session",
413
- expirationMinutes: 30,
414
- });
415
-
416
- // Xóa cookie
417
- clearSessionCookie({ cookieName: "my_session" });
418
-
419
- // Đọc cookie thủ công
420
- const value = getCookie("my_session");
421
- ```
422
-
423
- ### User-Provided Session ID
424
-
425
- Nếu bạn muốn tự quản lý `session_id`, vẫn có thể truyền vào như trước:
426
-
427
- ```javascript
428
- tracking.init({
429
- baseURL: "https://api.example.com/v1/event_batch",
430
- sessionId: "my-custom-session-id", // Tự cung cấp
431
- sessionSign: "session-signature",
432
- // ... other config
433
- });
434
-
435
- // Cookie sẽ KHÔNG được tạo khi bạn tự truyền session_id
332
+ export default MyApp;
436
333
  ```
437
334
 
438
335
  ---
439
336
 
440
337
  ## Custom Page Mapping
441
338
 
442
- Mặc định thư viện có sẵn mapping cho các page phổ biến. Bạn có thể tuỳ chỉnh:
443
-
444
339
  ```javascript
445
340
  tracking.init({
446
- baseURL: "...",
447
341
  // ... other config
448
-
449
342
  pageMap: {
450
- // Thêm hoặc ghi đè page mapping
343
+ // Override hoặc thêm mới
451
344
  phim: { name: "Phim", id: "movie" },
452
345
  "the-thao": { name: "Thể thao", id: "sports" },
453
- "tin-tuc": { name: "Tin tức", id: "news" },
454
346
  },
455
347
  });
456
348
  ```
457
349
 
458
- **Page mapping mặc định:**
350
+ **Default page mapping:**
459
351
 
460
352
  | URL Path | Page Name | Page ID |
461
353
  | ----------- | --------- | -------- |
@@ -474,146 +366,46 @@ tracking.init({
474
366
 
475
367
  ## API Reference
476
368
 
477
- ### `tracking.init(options)`
478
-
479
- Khởi tạo thư viện với config.
480
-
481
- | Option | Type | Required | Mô tả |
482
- | -------------- | ------- | -------- | ----------------------------- |
483
- | `baseURL` | string | ✅ | URL endpoint để gửi events |
484
- | `session_id` | string | ✅ | Session ID của user |
485
- | `session_sign` | string | ✅ | Session signature |
486
- | `user_id` | number | ✅ | User ID (-1 nếu chưa login) |
487
- | `deviceId` | string | ✅ | Device unique ID |
488
- | `deviceModel` | string | ✅ | Tên model thiết bị |
489
- | `deviceBrand` | string | ✅ | Hãng thiết bị |
490
- | `ip_address` | string | ✅ | IP address |
491
- | `debug` | boolean | ❌ | Bật/tắt debug logs |
492
- | `appName` | string | ❌ | Tên app (default: `app_name`) |
493
- | `platform` | string | ❌ | Platform (default: `Web`) |
494
- | `pageMap` | object | ❌ | Custom page mapping |
495
-
496
- ### `tracking.trackPageView(url)`
497
-
498
- Track sự kiện xem trang.
499
-
500
- ```javascript
501
- tracking.trackPageView("/detail/123?tab=info");
502
- ```
503
-
504
- ### `tracking.trackEvent(eventName, params)`
505
-
506
- Track custom event.
507
-
508
- ```javascript
509
- tracking.trackEvent("video_complete", { video_id: "123" });
510
- ```
511
-
512
- ### `tracking.sendEvent(eventData)`
513
-
514
- Gửi event trực tiếp với full payload.
515
-
516
- ```javascript
517
- await tracking.sendEvent({
518
- event_name: "my_event",
519
- ...customData,
520
- });
521
- ```
522
-
523
- ### `tracking.usePageViewTracking(router)`
524
-
525
- Auto track page views cho Next.js Pages Router.
369
+ ### TrackingConfig (Required Fields)
526
370
 
527
- ```javascript
528
- const cleanup = tracking.usePageViewTracking(router);
529
- // Gọi cleanup() khi unmount
530
- ```
371
+ | Field | Type | Giới hạn | Mô tả |
372
+ | ------------- | ------ | -------- | -------------------------------------------------- |
373
+ | `baseURL` | string | - | URL endpoint |
374
+ | `appId` | string | - | ONPlus, ONLiveTV |
375
+ | `packageId` | string | ≤ 125 | Package/Bundle ID |
376
+ | `sessionId` | string | UUID v4 | Session ID |
377
+ | `sessionSign` | string | 16..128 | MD5(append(session_id, secret_key)) |
378
+ | `deviceId` | string | ≤ 125 | Device unique ID |
379
+ | `platform` | string | - | Android, Ios, WebPC, WebMobile, SmartTV, AndroidTV |
380
+ | `deviceModel` | string | ≤ 125 | Model thiết bị |
381
+ | `deviceBrand` | string | ≤ 125 | Hãng thiết bị |
382
+ | `events` | array | - | Mảng events (không rỗng) |
531
383
 
532
- ---
384
+ ### TrackingConfig (Optional Fields)
533
385
 
534
- ## Event Payload Structure
386
+ | Field | Type | Giới hạn | Mô tả |
387
+ | ----------------- | ------- | -------- | ------------------ |
388
+ | `adId` | string | ≤ 125 | GAID/IDFA |
389
+ | `deviceOsVersion` | string | ≤ 50 | VD: "14", "17.6" |
390
+ | `sdkVersion` | string | ≤ 50 | Phiên bản SDK |
391
+ | `debug` | boolean | - | Bật/tắt debug logs |
535
392
 
536
- Khi gửi event, thư viện sẽ tự động format payload theo cấu trúc chuẩn:
393
+ > **Lưu ý**: `ip_address` `carrier_net` KHÔNG cần gửi. Server tự lấy từ header.
537
394
 
538
395
  ### Event Object Format
539
396
 
540
- Mỗi event được transform thành object với format:
541
-
542
- ```javascript
543
- // Input: sendEvent({ event_name: "video_play", video_id: "123", duration: 3600 })
544
-
545
- // Output: Event object được tạo
546
- {
547
- "event_id": "550e8400-e29b-41d4-a716-446655440000", // UUID v4 tự động sinh
548
- "event_name": "video_play", // Tách riêng từ eventData
549
- "event_params": "{\"video_id\":\"123\",\"duration\":3600}", // Các params còn lại được JSON stringify
550
- "event_time": 1705734000, // Unix timestamp (seconds)
551
- "user_id": 12345 // Từ config
552
- }
553
- ```
554
-
555
- ### Batch Request Payload
556
-
557
- Các events được gom lại và gửi theo batch:
558
-
559
- ```json
560
- {
561
- "app_name": "app_name",
562
- "app_id": "",
563
- "package_id": "domain.example.com",
564
- "platform": "Web",
565
-
566
- "session_id": "1737603823000_a8f3d9e2",
567
- "session_sign": "md5_signature",
568
- "user_id": 12345,
569
-
570
- "device_id": "device-unique-id",
571
- "device_model": "Chrome 120",
572
- "device_brand": "Web Browser",
573
- "ip_address": "192.168.1.1",
574
-
575
- "events": [
576
- {
577
- "event_id": "550e8400-e29b-41d4-a716-446655440000",
578
- "event_name": "page_view",
579
- "event_params": "{\"page_id\":\"home\",\"page_path\":\"/home\"}",
580
- "event_time": 1705734000,
581
- "user_id": 12345
582
- },
583
- {
584
- "event_id": "550e8400-e29b-41d4-a716-446655440001",
585
- "event_name": "video_play",
586
- "event_params": "{\"video_id\":\"123\"}",
587
- "event_time": 1705734005,
588
- "user_id": 12345
589
- }
590
- ]
591
- }
592
- ```
593
-
594
- ### Giải thích các trường trong Event Object
595
-
596
- | Trường | Type | Mô tả |
597
- | -------------- | ------ | -------------------------------------------- |
598
- | `event_id` | string | UUID v4 unique cho mỗi event |
599
- | `event_name` | string | Tên event (tách từ eventData) |
600
- | `event_params` | string | JSON string chứa tất cả params còn lại |
601
- | `event_time` | number | Unix timestamp (seconds) thời điểm tạo event |
602
- | `user_id` | number | User ID từ config |
397
+ | Field | Type | Bắt buộc | tả |
398
+ | -------------- | ------ | -------- | --------------------- |
399
+ | `user_id` | bigint | ✅ | -1 nếu chưa đăng nhập |
400
+ | `event_name` | string | ✅ | Tên event (≤ 125) |
401
+ | `event_time` | int | ✅ | Unix seconds |
402
+ | `event_params` | string | ❌ | JSON string (≤ 1024) |
603
403
 
604
404
  ---
605
405
 
606
- ## Debug Mode
406
+ ## Publish
607
407
 
608
- Khi bật `debug: true`, thư viện sẽ log ra console:
609
-
610
- - Config khi khởi tạo
611
- - Mỗi event được gửi đi
612
- - Lỗi nếu có
613
-
614
- ```javascript
615
- tracking.init({
616
- debug: process.env.NODE_ENV === "development",
617
- // ...
618
- });
408
+ ```bash
409
+ npm version patch
410
+ npm publish
619
411
  ```