@bytem/bytem-tracker-app 0.0.7 → 0.0.9
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 +78 -34
- package/dist/src/BytemTracker.d.ts +81 -0
- package/dist/src/BytemTracker.js +107 -7
- package/dist/src/types.d.ts +25 -0
- package/dist/src/types.js +3 -0
- package/dist/test/BytemTracker.test.js +13 -3
- package/package.json +7 -7
package/README.md
CHANGED
|
@@ -2,16 +2,12 @@
|
|
|
2
2
|
|
|
3
3
|
This is the official Bytem Tracker SDK for React Native applications.
|
|
4
4
|
|
|
5
|
-
## Documentation
|
|
6
|
-
|
|
7
|
-
- [Usage Guide](docs/USAGE.md): Detailed instructions on initialization, event tracking, and API usage.
|
|
8
|
-
|
|
9
5
|
## Installation
|
|
10
6
|
|
|
11
7
|
Install the package and its peer dependencies using Yarn:
|
|
12
8
|
|
|
13
9
|
```bash
|
|
14
|
-
yarn add @bytem/bytem-tracker-app
|
|
10
|
+
yarn add @bytem/bytem-tracker-app
|
|
15
11
|
```
|
|
16
12
|
|
|
17
13
|
### iOS Setup
|
|
@@ -20,47 +16,95 @@ Don't forget to install pods for iOS:
|
|
|
20
16
|
cd ios && pod install
|
|
21
17
|
```
|
|
22
18
|
|
|
23
|
-
##
|
|
19
|
+
## Usage
|
|
24
20
|
|
|
25
|
-
|
|
21
|
+
### Initialization
|
|
22
|
+
Initialize the tracker in your app entry point (e.g., `App.tsx` or `index.js`). Note that `init` is asynchronous.
|
|
26
23
|
|
|
27
|
-
|
|
24
|
+
```typescript
|
|
25
|
+
import React, { useEffect } from 'react';
|
|
26
|
+
import BytemTracker from '@bytem/bytem-tracker-app';
|
|
28
27
|
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
28
|
+
const App = () => {
|
|
29
|
+
useEffect(() => {
|
|
30
|
+
const initTracker = async () => {
|
|
31
|
+
await BytemTracker.init({
|
|
32
|
+
appId: 'your-app-id',
|
|
33
|
+
endpoint: 'https://api.bytem.com/track',
|
|
34
|
+
debug: __DEV__, // Enable debug logs in development
|
|
35
|
+
});
|
|
36
|
+
};
|
|
32
37
|
|
|
33
|
-
|
|
38
|
+
initTracker();
|
|
39
|
+
}, []);
|
|
34
40
|
|
|
35
|
-
|
|
36
|
-
|
|
41
|
+
return <YourApp />;
|
|
42
|
+
};
|
|
37
43
|
```
|
|
38
44
|
|
|
39
|
-
###
|
|
45
|
+
### Tracking Events
|
|
40
46
|
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
```
|
|
47
|
+
#### Identify User
|
|
48
|
+
Track user identification when a user logs in or updates their profile.
|
|
44
49
|
|
|
45
|
-
|
|
50
|
+
```typescript
|
|
51
|
+
// Signature: trackUser(userId: string, traits?: object)
|
|
52
|
+
await BytemTracker.trackUser('user_12345', {
|
|
53
|
+
email: 'user@example.com',
|
|
54
|
+
age: 25,
|
|
55
|
+
membership: 'gold'
|
|
56
|
+
});
|
|
57
|
+
```
|
|
46
58
|
|
|
47
|
-
|
|
59
|
+
#### View Product
|
|
60
|
+
Track when a user views a product details page.
|
|
61
|
+
|
|
62
|
+
```typescript
|
|
63
|
+
await BytemTracker.trackViewProduct({
|
|
64
|
+
productId: 'prod_001',
|
|
65
|
+
name: 'Awesome Gadget',
|
|
66
|
+
price: 99.99,
|
|
67
|
+
currency: 'USD',
|
|
68
|
+
category: 'Electronics'
|
|
69
|
+
});
|
|
70
|
+
```
|
|
48
71
|
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
72
|
+
#### Checkout Order
|
|
73
|
+
Track when a user initiates checkout.
|
|
74
|
+
|
|
75
|
+
```typescript
|
|
76
|
+
await BytemTracker.trackCheckOutOrder({
|
|
77
|
+
orderId: 'order_abc123',
|
|
78
|
+
total: 150.00,
|
|
79
|
+
currency: 'USD',
|
|
80
|
+
products: [
|
|
81
|
+
{ productId: 'prod_001', price: 99.99, quantity: 1 },
|
|
82
|
+
{ productId: 'prod_002', price: 50.01, quantity: 1 }
|
|
83
|
+
]
|
|
84
|
+
});
|
|
85
|
+
```
|
|
52
86
|
|
|
53
|
-
|
|
54
|
-
|
|
87
|
+
#### Pay Order
|
|
88
|
+
Track when a user completes a payment.
|
|
89
|
+
|
|
90
|
+
```typescript
|
|
91
|
+
await BytemTracker.trackPayOrder({
|
|
92
|
+
orderId: 'order_abc123',
|
|
93
|
+
total: 150.00,
|
|
94
|
+
currency: 'USD',
|
|
95
|
+
products: [
|
|
96
|
+
{ productId: 'prod_001', price: 99.99, quantity: 1 },
|
|
97
|
+
{ productId: 'prod_002', price: 50.01, quantity: 1 }
|
|
98
|
+
]
|
|
99
|
+
});
|
|
100
|
+
```
|
|
55
101
|
|
|
56
|
-
|
|
57
|
-
npm run release:major
|
|
102
|
+
## Platform Compatibility
|
|
58
103
|
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
104
|
+
This SDK is designed for **React Native** and supports:
|
|
105
|
+
- iOS
|
|
106
|
+
- Android
|
|
62
107
|
|
|
63
|
-
|
|
64
|
-
-
|
|
65
|
-
- `
|
|
66
|
-
- Configure auth via user-level `~/.npmrc`. Do not commit tokens in the repo.
|
|
108
|
+
It relies on:
|
|
109
|
+
- `@react-native-async-storage/async-storage`: For persisting session and visitor IDs.
|
|
110
|
+
- `react-native-device-info`: For capturing device metrics (model, OS version, etc.).
|
|
@@ -23,16 +23,72 @@ declare class BytemTracker {
|
|
|
23
23
|
private lastViewStoredDuration;
|
|
24
24
|
private constructor();
|
|
25
25
|
static getInstance(): BytemTracker;
|
|
26
|
+
/**
|
|
27
|
+
* Initializes the BytemTracker SDK with the provided configuration.
|
|
28
|
+
* This method must be called before any other tracking methods.
|
|
29
|
+
*
|
|
30
|
+
* @param config - The configuration object for the tracker.
|
|
31
|
+
* @returns A promise that resolves when initialization is complete.
|
|
32
|
+
*/
|
|
26
33
|
init(config: TrackerConfig): Promise<void>;
|
|
27
34
|
private ensureInitialized;
|
|
35
|
+
/**
|
|
36
|
+
* Begins a new user session.
|
|
37
|
+
* Handles session cookie logic to prevent excessive session starts if one is already active.
|
|
38
|
+
*
|
|
39
|
+
* @param force - If true, forces a new session start request even if the session cookie is valid.
|
|
40
|
+
*/
|
|
28
41
|
beginSession(force?: boolean): Promise<void>;
|
|
42
|
+
/**
|
|
43
|
+
* Reports session duration to the server.
|
|
44
|
+
* Usually called internally or when app state changes.
|
|
45
|
+
*
|
|
46
|
+
* @param sec - The duration in seconds to report.
|
|
47
|
+
*/
|
|
29
48
|
sessionDuration(sec: number): Promise<void>;
|
|
49
|
+
/**
|
|
50
|
+
* Ends the current user session.
|
|
51
|
+
*
|
|
52
|
+
* @param sec - Optional duration of the session in seconds. If not provided, it's calculated from the last beat.
|
|
53
|
+
* @param force - If true, forces the end session request even if using session cookies.
|
|
54
|
+
*/
|
|
30
55
|
endSession(sec?: number, force?: boolean): Promise<void>;
|
|
56
|
+
/**
|
|
57
|
+
* Manually tracks or extends a session.
|
|
58
|
+
* If a session is active, it reports duration. If not, it begins a new session.
|
|
59
|
+
*/
|
|
31
60
|
trackSessions(): Promise<void>;
|
|
61
|
+
/**
|
|
62
|
+
* Resumes time tracking for session duration.
|
|
63
|
+
*/
|
|
32
64
|
startTime(): void;
|
|
65
|
+
/**
|
|
66
|
+
* Pauses time tracking for session duration.
|
|
67
|
+
*/
|
|
33
68
|
stopTime(): void;
|
|
69
|
+
/**
|
|
70
|
+
* Tracks a custom event.
|
|
71
|
+
*
|
|
72
|
+
* @param eventKey - The unique key/name for the event.
|
|
73
|
+
* @param segmentation - Optional key-value pairs to attach to the event.
|
|
74
|
+
* @param count - The number of times this event occurred (default: 1).
|
|
75
|
+
* @param sum - Optional numeric value associated with the event (e.g., purchase amount).
|
|
76
|
+
* @param duration - Optional duration associated with the event.
|
|
77
|
+
*/
|
|
34
78
|
trackEvent(eventKey: string, segmentation?: Record<string, any>, count?: number, sum?: number, duration?: number): Promise<void>;
|
|
79
|
+
/**
|
|
80
|
+
* Tracks a page view.
|
|
81
|
+
* Automatically handles reporting the duration of the previous page view.
|
|
82
|
+
*
|
|
83
|
+
* @param current - The name or path of the current page.
|
|
84
|
+
* @param referrer - Optional name or path of the previous page.
|
|
85
|
+
*/
|
|
35
86
|
trackPageview(current: string, referrer?: string): Promise<void>;
|
|
87
|
+
/**
|
|
88
|
+
* Tracks a click on a product/goods item.
|
|
89
|
+
*
|
|
90
|
+
* @param params - The parameters for the goods click event.
|
|
91
|
+
*/
|
|
36
92
|
trackGoodsClick(params: {
|
|
37
93
|
gid?: string;
|
|
38
94
|
skuid?: string;
|
|
@@ -48,9 +104,34 @@ declare class BytemTracker {
|
|
|
48
104
|
private buildBaseRequestParams;
|
|
49
105
|
private extendSession;
|
|
50
106
|
private sendRequest;
|
|
107
|
+
/**
|
|
108
|
+
* Tracks a product view event.
|
|
109
|
+
* Maps the product details to a 'view_product' event.
|
|
110
|
+
*
|
|
111
|
+
* @param product - The product object to track.
|
|
112
|
+
*/
|
|
51
113
|
trackViewProduct(product: Product): Promise<void>;
|
|
114
|
+
/**
|
|
115
|
+
* Tracks a checkout order event.
|
|
116
|
+
* Automatically splits product lists into parallel arrays (gids, prices, quantities)
|
|
117
|
+
* to match the backend requirement.
|
|
118
|
+
*
|
|
119
|
+
* @param order - The order object containing products to checkout.
|
|
120
|
+
*/
|
|
52
121
|
trackCheckOutOrder(order: Order): Promise<void>;
|
|
122
|
+
/**
|
|
123
|
+
* Tracks a payment order event.
|
|
124
|
+
* Maps product list to a 'goods' array structure expected by the backend.
|
|
125
|
+
*
|
|
126
|
+
* @param order - The order object that was paid for.
|
|
127
|
+
*/
|
|
53
128
|
trackPayOrder(order: Order): Promise<void>;
|
|
129
|
+
/**
|
|
130
|
+
* Tracks user details/profile updates.
|
|
131
|
+
*
|
|
132
|
+
* @param userId - The unique identifier for the user.
|
|
133
|
+
* @param traits - Additional user properties (email, name, custom fields).
|
|
134
|
+
*/
|
|
54
135
|
trackUser(userId: string, traits?: UserTraits): Promise<void>;
|
|
55
136
|
private sendUserDetails;
|
|
56
137
|
}
|
package/dist/src/BytemTracker.js
CHANGED
|
@@ -35,6 +35,13 @@ class BytemTracker {
|
|
|
35
35
|
}
|
|
36
36
|
return BytemTracker.instance;
|
|
37
37
|
}
|
|
38
|
+
/**
|
|
39
|
+
* Initializes the BytemTracker SDK with the provided configuration.
|
|
40
|
+
* This method must be called before any other tracking methods.
|
|
41
|
+
*
|
|
42
|
+
* @param config - The configuration object for the tracker.
|
|
43
|
+
* @returns A promise that resolves when initialization is complete.
|
|
44
|
+
*/
|
|
38
45
|
async init(config) {
|
|
39
46
|
if (this.isInitialized) {
|
|
40
47
|
console.warn('[BytemTracker] Already initialized');
|
|
@@ -49,7 +56,10 @@ class BytemTracker {
|
|
|
49
56
|
if (config.path) {
|
|
50
57
|
this.apiPath = config.path.startsWith('/') ? config.path : '/' + config.path;
|
|
51
58
|
}
|
|
52
|
-
// Initialize Visitor ID
|
|
59
|
+
// Initialize Visitor ID logic:
|
|
60
|
+
// 1. If provided in config, use it.
|
|
61
|
+
// 2. If not, try to retrieve from storage.
|
|
62
|
+
// 3. If not in storage, generate a new UUID.
|
|
53
63
|
if (config.visitorId) {
|
|
54
64
|
this.visitorId = config.visitorId;
|
|
55
65
|
await (0, storage_1.setItem)(storage_1.StorageKeys.VISITOR_ID, this.visitorId);
|
|
@@ -69,7 +79,9 @@ class BytemTracker {
|
|
|
69
79
|
console.log(`[BytemTracker] Restored visitor ID: ${this.visitorId}`);
|
|
70
80
|
}
|
|
71
81
|
}
|
|
72
|
-
// Initialize Device ID type
|
|
82
|
+
// Initialize Device ID type logic:
|
|
83
|
+
// 0: Developer supplied
|
|
84
|
+
// 1: SDK generated (default)
|
|
73
85
|
if (config.deviceId) {
|
|
74
86
|
this.deviceIdType = 0; // Developer set
|
|
75
87
|
await (0, storage_1.setItem)(storage_1.StorageKeys.DEVICE_ID, config.deviceId);
|
|
@@ -88,7 +100,7 @@ class BytemTracker {
|
|
|
88
100
|
if (this.appScheme)
|
|
89
101
|
console.log(` app_scheme: ${this.appScheme}`);
|
|
90
102
|
}
|
|
91
|
-
//
|
|
103
|
+
// Attempt to begin a session automatically on init
|
|
92
104
|
try {
|
|
93
105
|
await this.beginSession();
|
|
94
106
|
}
|
|
@@ -104,6 +116,12 @@ class BytemTracker {
|
|
|
104
116
|
throw new Error('[BytemTracker] Not initialized. Call await init() first.');
|
|
105
117
|
}
|
|
106
118
|
}
|
|
119
|
+
/**
|
|
120
|
+
* Begins a new user session.
|
|
121
|
+
* Handles session cookie logic to prevent excessive session starts if one is already active.
|
|
122
|
+
*
|
|
123
|
+
* @param force - If true, forces a new session start request even if the session cookie is valid.
|
|
124
|
+
*/
|
|
107
125
|
async beginSession(force = false) {
|
|
108
126
|
this.ensureInitialized();
|
|
109
127
|
if (this.sessionStarted) {
|
|
@@ -114,7 +132,7 @@ class BytemTracker {
|
|
|
114
132
|
try {
|
|
115
133
|
this.sessionStarted = true;
|
|
116
134
|
this.lastBeat = Date.now();
|
|
117
|
-
// Check session cookie
|
|
135
|
+
// Check session cookie to avoid duplicate session starts
|
|
118
136
|
const sessionKey = `${this.appKey}/cly_session`;
|
|
119
137
|
const expireTimestampStr = await (0, storage_1.getItem)(sessionKey);
|
|
120
138
|
const expireTimestamp = expireTimestampStr ? parseInt(expireTimestampStr, 10) : null;
|
|
@@ -126,7 +144,7 @@ class BytemTracker {
|
|
|
126
144
|
if (!shouldSendRequest) {
|
|
127
145
|
if (this.debug)
|
|
128
146
|
console.log('[BytemTracker] Session cookie still valid, skipping begin_session request');
|
|
129
|
-
//
|
|
147
|
+
// Extend the cookie validity
|
|
130
148
|
await (0, storage_1.setItem)(sessionKey, (currentTimestamp + this.sessionCookieTimeout * 60 * 1000).toString());
|
|
131
149
|
return;
|
|
132
150
|
}
|
|
@@ -144,6 +162,12 @@ class BytemTracker {
|
|
|
144
162
|
console.error('[BytemTracker] Error in beginSession:', e);
|
|
145
163
|
}
|
|
146
164
|
}
|
|
165
|
+
/**
|
|
166
|
+
* Reports session duration to the server.
|
|
167
|
+
* Usually called internally or when app state changes.
|
|
168
|
+
*
|
|
169
|
+
* @param sec - The duration in seconds to report.
|
|
170
|
+
*/
|
|
147
171
|
async sessionDuration(sec) {
|
|
148
172
|
this.ensureInitialized();
|
|
149
173
|
if (!this.sessionStarted) {
|
|
@@ -158,6 +182,12 @@ class BytemTracker {
|
|
|
158
182
|
this.lastBeat = Date.now();
|
|
159
183
|
await this.extendSession();
|
|
160
184
|
}
|
|
185
|
+
/**
|
|
186
|
+
* Ends the current user session.
|
|
187
|
+
*
|
|
188
|
+
* @param sec - Optional duration of the session in seconds. If not provided, it's calculated from the last beat.
|
|
189
|
+
* @param force - If true, forces the end session request even if using session cookies.
|
|
190
|
+
*/
|
|
161
191
|
async endSession(sec, force = false) {
|
|
162
192
|
this.ensureInitialized();
|
|
163
193
|
if (!this.sessionStarted) {
|
|
@@ -181,6 +211,10 @@ class BytemTracker {
|
|
|
181
211
|
await this.sendRequest(this.apiPath, body, 'End Session');
|
|
182
212
|
this.sessionStarted = false;
|
|
183
213
|
}
|
|
214
|
+
/**
|
|
215
|
+
* Manually tracks or extends a session.
|
|
216
|
+
* If a session is active, it reports duration. If not, it begins a new session.
|
|
217
|
+
*/
|
|
184
218
|
async trackSessions() {
|
|
185
219
|
this.ensureInitialized();
|
|
186
220
|
if (this.debug)
|
|
@@ -200,6 +234,9 @@ class BytemTracker {
|
|
|
200
234
|
if (this.debug)
|
|
201
235
|
console.log('[BytemTracker] Session tracking started');
|
|
202
236
|
}
|
|
237
|
+
/**
|
|
238
|
+
* Resumes time tracking for session duration.
|
|
239
|
+
*/
|
|
203
240
|
startTime() {
|
|
204
241
|
if (!this.trackTime) {
|
|
205
242
|
this.trackTime = true;
|
|
@@ -223,6 +260,9 @@ class BytemTracker {
|
|
|
223
260
|
this.extendSession();
|
|
224
261
|
}
|
|
225
262
|
}
|
|
263
|
+
/**
|
|
264
|
+
* Pauses time tracking for session duration.
|
|
265
|
+
*/
|
|
226
266
|
stopTime() {
|
|
227
267
|
if (this.trackTime) {
|
|
228
268
|
this.trackTime = false;
|
|
@@ -237,6 +277,15 @@ class BytemTracker {
|
|
|
237
277
|
console.log('[BytemTracker] Time tracking stopped');
|
|
238
278
|
}
|
|
239
279
|
}
|
|
280
|
+
/**
|
|
281
|
+
* Tracks a custom event.
|
|
282
|
+
*
|
|
283
|
+
* @param eventKey - The unique key/name for the event.
|
|
284
|
+
* @param segmentation - Optional key-value pairs to attach to the event.
|
|
285
|
+
* @param count - The number of times this event occurred (default: 1).
|
|
286
|
+
* @param sum - Optional numeric value associated with the event (e.g., purchase amount).
|
|
287
|
+
* @param duration - Optional duration associated with the event.
|
|
288
|
+
*/
|
|
240
289
|
async trackEvent(eventKey, segmentation, count = 1, sum, duration) {
|
|
241
290
|
this.ensureInitialized();
|
|
242
291
|
const deviceId = await this.getRealDeviceId();
|
|
@@ -257,6 +306,13 @@ class BytemTracker {
|
|
|
257
306
|
body['events'] = JSON.stringify([event]);
|
|
258
307
|
await this.sendRequest(this.apiPath, body, 'Event');
|
|
259
308
|
}
|
|
309
|
+
/**
|
|
310
|
+
* Tracks a page view.
|
|
311
|
+
* Automatically handles reporting the duration of the previous page view.
|
|
312
|
+
*
|
|
313
|
+
* @param current - The name or path of the current page.
|
|
314
|
+
* @param referrer - Optional name or path of the previous page.
|
|
315
|
+
*/
|
|
260
316
|
async trackPageview(current, referrer) {
|
|
261
317
|
await this.reportViewDuration();
|
|
262
318
|
const segmentation = {
|
|
@@ -279,6 +335,11 @@ class BytemTracker {
|
|
|
279
335
|
}
|
|
280
336
|
await this.trackEvent(types_1.BytemEventKeys.view, segmentation, 1, undefined, duration);
|
|
281
337
|
}
|
|
338
|
+
/**
|
|
339
|
+
* Tracks a click on a product/goods item.
|
|
340
|
+
*
|
|
341
|
+
* @param params - The parameters for the goods click event.
|
|
342
|
+
*/
|
|
282
343
|
async trackGoodsClick(params) {
|
|
283
344
|
this.ensureInitialized();
|
|
284
345
|
const segmentation = {
|
|
@@ -423,6 +484,12 @@ class BytemTracker {
|
|
|
423
484
|
}
|
|
424
485
|
}
|
|
425
486
|
// Wrappers for Business methods to maintain compatibility or you can refactor them too
|
|
487
|
+
/**
|
|
488
|
+
* Tracks a product view event.
|
|
489
|
+
* Maps the product details to a 'view_product' event.
|
|
490
|
+
*
|
|
491
|
+
* @param product - The product object to track.
|
|
492
|
+
*/
|
|
426
493
|
async trackViewProduct(product) {
|
|
427
494
|
// Map Product to segmentation
|
|
428
495
|
const segmentation = {
|
|
@@ -435,25 +502,58 @@ class BytemTracker {
|
|
|
435
502
|
// In Dart, trackViewProduct sends "view_product" event.
|
|
436
503
|
await this.trackEvent('view_product', segmentation);
|
|
437
504
|
}
|
|
505
|
+
/**
|
|
506
|
+
* Tracks a checkout order event.
|
|
507
|
+
* Automatically splits product lists into parallel arrays (gids, prices, quantities)
|
|
508
|
+
* to match the backend requirement.
|
|
509
|
+
*
|
|
510
|
+
* @param order - The order object containing products to checkout.
|
|
511
|
+
*/
|
|
438
512
|
async trackCheckOutOrder(order) {
|
|
439
513
|
// Map Order to segmentation
|
|
440
514
|
const segmentation = {
|
|
441
515
|
order_id: order.orderId,
|
|
442
516
|
total: order.total,
|
|
443
517
|
currency: order.currency,
|
|
444
|
-
// products need to be handled. Dart sends lists of gids, etc.
|
|
445
|
-
// This is a simplification. Ideally we replicate trackCheckOutOrder logic fully.
|
|
446
518
|
};
|
|
519
|
+
if (order.products && order.products.length > 0) {
|
|
520
|
+
segmentation.gids = order.products.map(p => p.productId);
|
|
521
|
+
segmentation.prices = order.products.map(p => p.price);
|
|
522
|
+
segmentation.quantity = order.products.map(p => p.quantity || 1);
|
|
523
|
+
// Optional: skuids if available in Product type, currently not in interface but good to handle if extended
|
|
524
|
+
// segmentation.skuids = ...
|
|
525
|
+
}
|
|
447
526
|
await this.trackEvent('check_out_order', segmentation);
|
|
448
527
|
}
|
|
528
|
+
/**
|
|
529
|
+
* Tracks a payment order event.
|
|
530
|
+
* Maps product list to a 'goods' array structure expected by the backend.
|
|
531
|
+
*
|
|
532
|
+
* @param order - The order object that was paid for.
|
|
533
|
+
*/
|
|
449
534
|
async trackPayOrder(order) {
|
|
450
535
|
const segmentation = {
|
|
451
536
|
order_id: order.orderId,
|
|
452
537
|
total: order.total,
|
|
453
538
|
currency: order.currency,
|
|
454
539
|
};
|
|
540
|
+
if (order.products && order.products.length > 0) {
|
|
541
|
+
// Dart maps this to a list of maps called "goods"
|
|
542
|
+
segmentation.goods = order.products.map(p => ({
|
|
543
|
+
gid: p.productId,
|
|
544
|
+
name: p.name,
|
|
545
|
+
price: p.price,
|
|
546
|
+
quantity: p.quantity || 1,
|
|
547
|
+
}));
|
|
548
|
+
}
|
|
455
549
|
await this.trackEvent('pay_order', segmentation);
|
|
456
550
|
}
|
|
551
|
+
/**
|
|
552
|
+
* Tracks user details/profile updates.
|
|
553
|
+
*
|
|
554
|
+
* @param userId - The unique identifier for the user.
|
|
555
|
+
* @param traits - Additional user properties (email, name, custom fields).
|
|
556
|
+
*/
|
|
457
557
|
async trackUser(userId, traits) {
|
|
458
558
|
// Map to user_details
|
|
459
559
|
// This is a special request in Dart: "user_details" param
|
package/dist/src/types.d.ts
CHANGED
|
@@ -1,12 +1,25 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Configuration for initializing the BytemTracker.
|
|
3
|
+
*/
|
|
1
4
|
export interface TrackerConfig {
|
|
5
|
+
/** The unique application ID provided by Bytem. */
|
|
2
6
|
appId: string;
|
|
7
|
+
/** Custom endpoint URL for tracking requests. */
|
|
3
8
|
endpoint?: string;
|
|
9
|
+
/** Custom path for the API endpoint (default: '/i'). */
|
|
4
10
|
path?: string;
|
|
11
|
+
/** Enable debug logging for development. */
|
|
5
12
|
debug?: boolean;
|
|
13
|
+
/** Optional: Manually set a visitor ID. */
|
|
6
14
|
visitorId?: string;
|
|
15
|
+
/** Optional: Manually set a device ID. */
|
|
7
16
|
deviceId?: string;
|
|
17
|
+
/** Optional: App scheme for domain field in tracking. */
|
|
8
18
|
appScheme?: string;
|
|
9
19
|
}
|
|
20
|
+
/**
|
|
21
|
+
* Predefined event keys used internally by the SDK.
|
|
22
|
+
*/
|
|
10
23
|
export declare const BytemEventKeys: {
|
|
11
24
|
nps: string;
|
|
12
25
|
survey: string;
|
|
@@ -16,6 +29,9 @@ export declare const BytemEventKeys: {
|
|
|
16
29
|
pushAction: string;
|
|
17
30
|
action: string;
|
|
18
31
|
};
|
|
32
|
+
/**
|
|
33
|
+
* Structure containing device information collected by the SDK.
|
|
34
|
+
*/
|
|
19
35
|
export interface DeviceInfo {
|
|
20
36
|
platform: string;
|
|
21
37
|
os: string;
|
|
@@ -44,9 +60,15 @@ export interface BaseParams {
|
|
|
44
60
|
screen_height: number;
|
|
45
61
|
user_agent: string;
|
|
46
62
|
}
|
|
63
|
+
/**
|
|
64
|
+
* Arbitrary key-value pairs for user properties.
|
|
65
|
+
*/
|
|
47
66
|
export interface UserTraits {
|
|
48
67
|
[key: string]: any;
|
|
49
68
|
}
|
|
69
|
+
/**
|
|
70
|
+
* Represents a product in the system.
|
|
71
|
+
*/
|
|
50
72
|
export interface Product {
|
|
51
73
|
productId: string;
|
|
52
74
|
name?: string;
|
|
@@ -55,6 +77,9 @@ export interface Product {
|
|
|
55
77
|
category?: string;
|
|
56
78
|
quantity?: number;
|
|
57
79
|
}
|
|
80
|
+
/**
|
|
81
|
+
* Represents an order (checkout or payment).
|
|
82
|
+
*/
|
|
58
83
|
export interface Order {
|
|
59
84
|
orderId: string;
|
|
60
85
|
total: number;
|
package/dist/src/types.js
CHANGED
|
@@ -223,7 +223,10 @@ describe('BytemTracker SDK', () => {
|
|
|
223
223
|
expect(events[0].segmentation).toMatchObject({
|
|
224
224
|
order_id: 'order_123',
|
|
225
225
|
total: 99.99,
|
|
226
|
-
currency: 'USD'
|
|
226
|
+
currency: 'USD',
|
|
227
|
+
gids: ['prod_1', 'prod_2'],
|
|
228
|
+
prices: [50, 49.99],
|
|
229
|
+
quantity: [1, 1]
|
|
227
230
|
});
|
|
228
231
|
});
|
|
229
232
|
it('should track pay order', async () => {
|
|
@@ -231,7 +234,10 @@ describe('BytemTracker SDK', () => {
|
|
|
231
234
|
orderId: 'order_123',
|
|
232
235
|
total: 99.99,
|
|
233
236
|
currency: 'USD',
|
|
234
|
-
products: [
|
|
237
|
+
products: [
|
|
238
|
+
{ productId: 'prod_1', name: 'Product 1', price: 50, quantity: 1 },
|
|
239
|
+
{ productId: 'prod_2', name: 'Product 2', price: 49.99, quantity: 2 }
|
|
240
|
+
]
|
|
235
241
|
};
|
|
236
242
|
await BytemTracker_1.default.trackPayOrder(order);
|
|
237
243
|
const calls = global.fetch.mock.calls;
|
|
@@ -241,7 +247,11 @@ describe('BytemTracker SDK', () => {
|
|
|
241
247
|
expect(events[0].segmentation).toMatchObject({
|
|
242
248
|
order_id: 'order_123',
|
|
243
249
|
total: 99.99,
|
|
244
|
-
currency: 'USD'
|
|
250
|
+
currency: 'USD',
|
|
251
|
+
goods: [
|
|
252
|
+
{ gid: 'prod_1', name: 'Product 1', price: 50, quantity: 1 },
|
|
253
|
+
{ gid: 'prod_2', name: 'Product 2', price: 49.99, quantity: 2 }
|
|
254
|
+
]
|
|
245
255
|
});
|
|
246
256
|
});
|
|
247
257
|
});
|
package/package.json
CHANGED
|
@@ -1,9 +1,9 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@bytem/bytem-tracker-app",
|
|
3
|
-
"version": "0.0.
|
|
3
|
+
"version": "0.0.9",
|
|
4
4
|
"description": "Bytem Tracker SDK for React Native",
|
|
5
|
-
"main": "dist/index.js",
|
|
6
|
-
"types": "dist/index.d.ts",
|
|
5
|
+
"main": "dist/src/index.js",
|
|
6
|
+
"types": "dist/src/index.d.ts",
|
|
7
7
|
"files": [
|
|
8
8
|
"dist"
|
|
9
9
|
],
|
|
@@ -25,13 +25,13 @@
|
|
|
25
25
|
"author": "Barry",
|
|
26
26
|
"license": "ISC",
|
|
27
27
|
"peerDependencies": {
|
|
28
|
-
"@react-native-async-storage/async-storage": "^1.0.0",
|
|
29
28
|
"react": ">=16.8.0",
|
|
30
|
-
"react-native": ">=0.60.0"
|
|
31
|
-
"react-native-device-info": "^10.0.0"
|
|
29
|
+
"react-native": ">=0.60.0"
|
|
32
30
|
},
|
|
33
31
|
"dependencies": {
|
|
34
|
-
"uuid": "^9.0.0"
|
|
32
|
+
"uuid": "^9.0.0",
|
|
33
|
+
"@react-native-async-storage/async-storage": "^1.19.0",
|
|
34
|
+
"react-native-device-info": "^10.8.0"
|
|
35
35
|
},
|
|
36
36
|
"devDependencies": {
|
|
37
37
|
"@react-native-async-storage/async-storage": "^1.19.0",
|