@clix-so/react-native-sdk 1.0.0 → 1.1.0
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/lib/module/core/Clix.js +40 -95
- package/lib/module/core/Clix.js.map +1 -1
- package/lib/module/core/ClixInitCoordinator.js +3 -14
- package/lib/module/core/ClixInitCoordinator.js.map +1 -1
- package/lib/module/core/ClixNotification.js +25 -28
- package/lib/module/core/ClixNotification.js.map +1 -1
- package/lib/module/models/ClixDevice.js +0 -6
- package/lib/module/models/ClixDevice.js.map +1 -1
- package/lib/module/models/ClixPushNotificationPayload.js +0 -19
- package/lib/module/models/ClixPushNotificationPayload.js.map +1 -1
- package/lib/module/services/ClixAPIClient.js +50 -99
- package/lib/module/services/ClixAPIClient.js.map +1 -1
- package/lib/module/services/DeviceAPIService.js +37 -45
- package/lib/module/services/DeviceAPIService.js.map +1 -1
- package/lib/module/services/DeviceService.js +97 -116
- package/lib/module/services/DeviceService.js.map +1 -1
- package/lib/module/services/EventAPIService.js +3 -5
- package/lib/module/services/EventAPIService.js.map +1 -1
- package/lib/module/services/EventService.js +13 -20
- package/lib/module/services/EventService.js.map +1 -1
- package/lib/module/services/NotificationService.js +252 -402
- package/lib/module/services/NotificationService.js.map +1 -1
- package/lib/module/services/TokenService.js +3 -59
- package/lib/module/services/TokenService.js.map +1 -1
- package/lib/module/utils/http/HTTPClient.js +101 -0
- package/lib/module/utils/http/HTTPClient.js.map +1 -0
- package/lib/module/utils/http/HTTPMethod.js +10 -0
- package/lib/module/utils/http/HTTPMethod.js.map +1 -0
- package/lib/module/utils/http/HTTPRequest.js +4 -0
- package/lib/module/utils/http/HTTPRequest.js.map +1 -0
- package/lib/module/utils/http/HTTPResponse.js +2 -0
- package/lib/module/utils/http/HTTPResponse.js.map +1 -0
- package/lib/module/utils/types.js +2 -0
- package/lib/module/utils/types.js.map +1 -0
- package/lib/typescript/src/core/Clix.d.ts +13 -15
- package/lib/typescript/src/core/Clix.d.ts.map +1 -1
- package/lib/typescript/src/core/ClixConfig.d.ts +3 -3
- package/lib/typescript/src/core/ClixConfig.d.ts.map +1 -1
- package/lib/typescript/src/core/ClixInitCoordinator.d.ts +0 -3
- package/lib/typescript/src/core/ClixInitCoordinator.d.ts.map +1 -1
- package/lib/typescript/src/core/ClixNotification.d.ts +6 -5
- package/lib/typescript/src/core/ClixNotification.d.ts.map +1 -1
- package/lib/typescript/src/models/ClixDevice.d.ts +0 -2
- package/lib/typescript/src/models/ClixDevice.d.ts.map +1 -1
- package/lib/typescript/src/models/ClixPushNotificationPayload.d.ts +8 -21
- package/lib/typescript/src/models/ClixPushNotificationPayload.d.ts.map +1 -1
- package/lib/typescript/src/services/ClixAPIClient.d.ts +6 -22
- package/lib/typescript/src/services/ClixAPIClient.d.ts.map +1 -1
- package/lib/typescript/src/services/DeviceAPIService.d.ts +1 -1
- package/lib/typescript/src/services/DeviceAPIService.d.ts.map +1 -1
- package/lib/typescript/src/services/DeviceService.d.ts +10 -5
- package/lib/typescript/src/services/DeviceService.d.ts.map +1 -1
- package/lib/typescript/src/services/EventAPIService.d.ts.map +1 -1
- package/lib/typescript/src/services/EventService.d.ts +1 -0
- package/lib/typescript/src/services/EventService.d.ts.map +1 -1
- package/lib/typescript/src/services/NotificationService.d.ts +50 -57
- package/lib/typescript/src/services/NotificationService.d.ts.map +1 -1
- package/lib/typescript/src/services/TokenService.d.ts +1 -7
- package/lib/typescript/src/services/TokenService.d.ts.map +1 -1
- package/lib/typescript/src/utils/http/HTTPClient.d.ts +15 -0
- package/lib/typescript/src/utils/http/HTTPClient.d.ts.map +1 -0
- package/lib/typescript/src/utils/http/HTTPMethod.d.ts +7 -0
- package/lib/typescript/src/utils/http/HTTPMethod.d.ts.map +1 -0
- package/lib/typescript/src/utils/http/HTTPRequest.d.ts +9 -0
- package/lib/typescript/src/utils/http/HTTPRequest.d.ts.map +1 -0
- package/lib/typescript/src/utils/http/HTTPResponse.d.ts +6 -0
- package/lib/typescript/src/utils/http/HTTPResponse.d.ts.map +1 -0
- package/lib/typescript/src/utils/types.d.ts +5 -0
- package/lib/typescript/src/utils/types.d.ts.map +1 -0
- package/package.json +1 -1
- package/src/core/Clix.ts +62 -115
- package/src/core/ClixConfig.ts +3 -3
- package/src/core/ClixInitCoordinator.ts +5 -17
- package/src/core/ClixNotification.ts +36 -37
- package/src/models/ClixDevice.ts +17 -25
- package/src/models/ClixPushNotificationPayload.ts +8 -37
- package/src/services/ClixAPIClient.ts +84 -144
- package/src/services/DeviceAPIService.ts +39 -47
- package/src/services/DeviceService.ts +122 -156
- package/src/services/EventAPIService.ts +3 -5
- package/src/services/EventService.ts +26 -33
- package/src/services/NotificationService.ts +318 -533
- package/src/services/TokenService.ts +4 -71
- package/src/utils/http/HTTPClient.ts +141 -0
- package/src/utils/http/HTTPMethod.ts +6 -0
- package/src/utils/http/HTTPRequest.ts +9 -0
- package/src/utils/http/HTTPResponse.ts +5 -0
- package/src/utils/types.ts +7 -0
|
@@ -6,39 +6,37 @@ import { ClixAPIClient } from './ClixAPIClient';
|
|
|
6
6
|
export class DeviceAPIService {
|
|
7
7
|
constructor(private readonly apiClient: ClixAPIClient) {}
|
|
8
8
|
|
|
9
|
-
async
|
|
9
|
+
async upsertDevice(device: ClixDevice): Promise<void> {
|
|
10
10
|
try {
|
|
11
11
|
ClixLogger.debug(`Upserting device: ${device.id}`);
|
|
12
12
|
|
|
13
13
|
const response = await this.apiClient.post('/devices', {
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
],
|
|
36
|
-
},
|
|
14
|
+
devices: [
|
|
15
|
+
{
|
|
16
|
+
id: device.id,
|
|
17
|
+
platform: device.platform,
|
|
18
|
+
model: device.model,
|
|
19
|
+
manufacturer: device.manufacturer,
|
|
20
|
+
os_name: device.osName,
|
|
21
|
+
os_version: device.osVersion,
|
|
22
|
+
locale_region: device.localeRegion,
|
|
23
|
+
locale_language: device.localeLanguage,
|
|
24
|
+
timezone: device.timezone,
|
|
25
|
+
app_name: device.appName,
|
|
26
|
+
app_version: device.appVersion,
|
|
27
|
+
sdk_type: device.sdkType,
|
|
28
|
+
sdk_version: device.sdkVersion,
|
|
29
|
+
ad_id: device.adId,
|
|
30
|
+
is_push_permission_granted: device.isPushPermissionGranted,
|
|
31
|
+
push_token: device.pushToken,
|
|
32
|
+
push_token_type: device.pushTokenType,
|
|
33
|
+
},
|
|
34
|
+
],
|
|
37
35
|
});
|
|
38
36
|
|
|
39
|
-
if (response.
|
|
37
|
+
if (response.statusCode < 200 || response.statusCode >= 300) {
|
|
40
38
|
throw new Error(
|
|
41
|
-
`HTTP ${response.
|
|
39
|
+
`HTTP ${response.statusCode}: ${JSON.stringify(response.data)}`
|
|
42
40
|
);
|
|
43
41
|
}
|
|
44
42
|
|
|
@@ -59,15 +57,13 @@ export class DeviceAPIService {
|
|
|
59
57
|
const response = await this.apiClient.post(
|
|
60
58
|
`/devices/${deviceId}/user/project-user-id`,
|
|
61
59
|
{
|
|
62
|
-
|
|
63
|
-
project_user_id: projectUserId,
|
|
64
|
-
},
|
|
60
|
+
project_user_id: projectUserId,
|
|
65
61
|
}
|
|
66
62
|
);
|
|
67
63
|
|
|
68
|
-
if (response.
|
|
64
|
+
if (response.statusCode < 200 || response.statusCode >= 300) {
|
|
69
65
|
throw new Error(
|
|
70
|
-
`HTTP ${response.
|
|
66
|
+
`HTTP ${response.statusCode}: ${JSON.stringify(response.data)}`
|
|
71
67
|
);
|
|
72
68
|
}
|
|
73
69
|
|
|
@@ -91,9 +87,9 @@ export class DeviceAPIService {
|
|
|
91
87
|
`/devices/${deviceId}/user/project-user-id`
|
|
92
88
|
);
|
|
93
89
|
|
|
94
|
-
if (response.
|
|
90
|
+
if (response.statusCode < 200 || response.statusCode >= 300) {
|
|
95
91
|
throw new Error(
|
|
96
|
-
`HTTP ${response.
|
|
92
|
+
`HTTP ${response.statusCode}: ${JSON.stringify(response.data)}`
|
|
97
93
|
);
|
|
98
94
|
}
|
|
99
95
|
|
|
@@ -121,19 +117,17 @@ export class DeviceAPIService {
|
|
|
121
117
|
const response = await this.apiClient.post(
|
|
122
118
|
`/devices/${deviceId}/user/properties`,
|
|
123
119
|
{
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
})),
|
|
130
|
-
},
|
|
120
|
+
properties: properties.map((p) => ({
|
|
121
|
+
name: p.name,
|
|
122
|
+
value_string: p.valueString,
|
|
123
|
+
type: p.type,
|
|
124
|
+
})),
|
|
131
125
|
}
|
|
132
126
|
);
|
|
133
127
|
|
|
134
|
-
if (response.
|
|
128
|
+
if (response.statusCode < 200 || response.statusCode >= 300) {
|
|
135
129
|
throw new Error(
|
|
136
|
-
`HTTP ${response.
|
|
130
|
+
`HTTP ${response.statusCode}: ${JSON.stringify(response.data)}`
|
|
137
131
|
);
|
|
138
132
|
}
|
|
139
133
|
|
|
@@ -161,15 +155,13 @@ export class DeviceAPIService {
|
|
|
161
155
|
const response = await this.apiClient.delete(
|
|
162
156
|
`/devices/${deviceId}/user/properties`,
|
|
163
157
|
{
|
|
164
|
-
|
|
165
|
-
property_names: propertyNames.join(','),
|
|
166
|
-
},
|
|
158
|
+
property_names: propertyNames.join(','),
|
|
167
159
|
}
|
|
168
160
|
);
|
|
169
161
|
|
|
170
|
-
if (response.
|
|
162
|
+
if (response.statusCode < 200 || response.statusCode >= 300) {
|
|
171
163
|
throw new Error(
|
|
172
|
-
`HTTP ${response.
|
|
164
|
+
`HTTP ${response.statusCode}: ${JSON.stringify(response.data)}`
|
|
173
165
|
);
|
|
174
166
|
}
|
|
175
167
|
|
|
@@ -1,18 +1,17 @@
|
|
|
1
1
|
import messaging from '@react-native-firebase/messaging';
|
|
2
|
-
import { Platform } from 'react-native';
|
|
3
2
|
import DeviceInfo from 'react-native-device-info';
|
|
4
3
|
import { ClixVersion } from '../core/ClixVersion';
|
|
5
4
|
import { ClixDevice } from '../models/ClixDevice';
|
|
6
5
|
import { ClixUserProperty } from '../models/ClixUserProperty';
|
|
7
|
-
import { ClixError } from '../utils/ClixError';
|
|
8
6
|
import { ClixLogger } from '../utils/logging/ClixLogger';
|
|
9
7
|
import { UUID } from '../utils/UUID';
|
|
10
8
|
import { DeviceAPIService } from './DeviceAPIService';
|
|
11
9
|
import { StorageService } from './StorageService';
|
|
12
|
-
import { TokenService } from './TokenService';
|
|
10
|
+
import type { TokenService } from './TokenService';
|
|
13
11
|
|
|
14
12
|
export class DeviceService {
|
|
15
|
-
private
|
|
13
|
+
private deviceIdKey = 'clix_device_id';
|
|
14
|
+
private currentDevice?: ClixDevice;
|
|
16
15
|
|
|
17
16
|
constructor(
|
|
18
17
|
private readonly storageService: StorageService,
|
|
@@ -20,135 +19,140 @@ export class DeviceService {
|
|
|
20
19
|
private readonly deviceAPIService: DeviceAPIService
|
|
21
20
|
) {}
|
|
22
21
|
|
|
22
|
+
async initialize(): Promise<void> {
|
|
23
|
+
this.currentDevice = await this.createDevice();
|
|
24
|
+
await this.deviceAPIService.upsertDevice(this.currentDevice);
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
private generateDeviceId(): string {
|
|
28
|
+
return UUID.generate();
|
|
29
|
+
}
|
|
30
|
+
|
|
23
31
|
getCurrentDeviceId(): string {
|
|
24
|
-
const existingId = this.storageService.get<string>(
|
|
25
|
-
DeviceService.DEVICE_ID_KEY
|
|
26
|
-
);
|
|
32
|
+
const existingId = this.storageService.get<string>(this.deviceIdKey);
|
|
27
33
|
if (existingId) {
|
|
28
34
|
return existingId;
|
|
29
35
|
}
|
|
30
36
|
|
|
31
|
-
const
|
|
32
|
-
this.storageService.set(
|
|
33
|
-
return newId;
|
|
34
|
-
}
|
|
37
|
+
const newDeviceId = this.generateDeviceId();
|
|
38
|
+
this.storageService.set(this.deviceIdKey, newDeviceId);
|
|
35
39
|
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
const deviceId = this.getCurrentDeviceId();
|
|
39
|
-
await this.deviceAPIService.setProjectUserId(deviceId, projectUserId);
|
|
40
|
-
ClixLogger.debug(`Project user ID set: ${projectUserId}`);
|
|
41
|
-
} catch (error) {
|
|
42
|
-
ClixLogger.error('Failed to set project user ID', error);
|
|
43
|
-
throw ClixError.unknownError({
|
|
44
|
-
reason: `Failed to set project user ID: ${error}`,
|
|
45
|
-
cause: error,
|
|
46
|
-
});
|
|
47
|
-
}
|
|
40
|
+
ClixLogger.debug(`Generated new device ID: ${newDeviceId}`);
|
|
41
|
+
return newDeviceId;
|
|
48
42
|
}
|
|
49
43
|
|
|
50
|
-
async
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
44
|
+
async createDevice(): Promise<ClixDevice> {
|
|
45
|
+
const deviceId = this.getCurrentDeviceId();
|
|
46
|
+
const platform = DeviceInfo.getSystemName();
|
|
47
|
+
const osName = DeviceInfo.getSystemName();
|
|
48
|
+
const osVersion = DeviceInfo.getSystemVersion();
|
|
49
|
+
const manufacturer = await DeviceInfo.getManufacturer();
|
|
50
|
+
const model = DeviceInfo.getModel();
|
|
51
|
+
const appName = DeviceInfo.getApplicationName();
|
|
52
|
+
const appVersion = DeviceInfo.getVersion();
|
|
53
|
+
const timezone = Intl.DateTimeFormat().resolvedOptions().timeZone;
|
|
54
|
+
const locale = Intl.DateTimeFormat().resolvedOptions().locale || 'en-US';
|
|
55
|
+
const localeLanguage = locale.split('-')[0] || 'en';
|
|
56
|
+
const localeRegion = locale.split('-')[1] || 'US';
|
|
57
|
+
const adId: string | undefined = undefined; // TODO: Implement Ad ID
|
|
58
|
+
const isPushPermissionGranted = await this.getPushPermissionStatus();
|
|
59
|
+
const sdkType = 'react-native';
|
|
60
|
+
const sdkVersion = await ClixVersion.getVersion();
|
|
61
|
+
const pushToken = await this.getPushToken();
|
|
62
|
+
const pushTokenType = pushToken ? 'FCM' : undefined;
|
|
63
|
+
|
|
64
|
+
const device = new ClixDevice({
|
|
65
|
+
id: deviceId,
|
|
66
|
+
platform,
|
|
67
|
+
model,
|
|
68
|
+
manufacturer,
|
|
69
|
+
osName,
|
|
70
|
+
osVersion,
|
|
71
|
+
localeRegion,
|
|
72
|
+
localeLanguage,
|
|
73
|
+
timezone,
|
|
74
|
+
appName,
|
|
75
|
+
appVersion,
|
|
76
|
+
sdkType,
|
|
77
|
+
sdkVersion,
|
|
78
|
+
adId,
|
|
79
|
+
isPushPermissionGranted,
|
|
80
|
+
pushToken,
|
|
81
|
+
pushTokenType,
|
|
82
|
+
});
|
|
83
|
+
|
|
84
|
+
return device;
|
|
62
85
|
}
|
|
63
86
|
|
|
64
|
-
async
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
ClixUserProperty.of(key, value)
|
|
68
|
-
);
|
|
87
|
+
async upsertDevice(device: ClixDevice): Promise<void> {
|
|
88
|
+
return this.deviceAPIService.upsertDevice(device);
|
|
89
|
+
}
|
|
69
90
|
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
91
|
+
async updatePushToken(
|
|
92
|
+
pushToken: string,
|
|
93
|
+
pushTokenType: string
|
|
94
|
+
): Promise<void> {
|
|
95
|
+
if (!this.currentDevice) {
|
|
96
|
+
ClixLogger.warn('Device not initialized yet, cannot update push token');
|
|
97
|
+
return;
|
|
98
|
+
}
|
|
75
99
|
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
ClixLogger.
|
|
81
|
-
|
|
82
|
-
reason: `Failed to update user properties: ${error}`,
|
|
83
|
-
cause: error,
|
|
84
|
-
});
|
|
100
|
+
if (
|
|
101
|
+
this.currentDevice.pushToken === pushToken &&
|
|
102
|
+
this.currentDevice.pushTokenType === pushTokenType
|
|
103
|
+
) {
|
|
104
|
+
ClixLogger.debug('Push token and type are unchanged, skipping update');
|
|
105
|
+
return;
|
|
85
106
|
}
|
|
107
|
+
|
|
108
|
+
const newDevice = this.currentDevice.copyWith({ pushToken, pushTokenType });
|
|
109
|
+
this.currentDevice = newDevice;
|
|
110
|
+
|
|
111
|
+
return this.deviceAPIService.upsertDevice(newDevice);
|
|
86
112
|
}
|
|
87
113
|
|
|
88
|
-
async
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
114
|
+
async updatePushPermission(isGranted: boolean): Promise<void> {
|
|
115
|
+
if (!this.currentDevice) {
|
|
116
|
+
ClixLogger.warn(
|
|
117
|
+
'Device not initialized yet, cannot update push permission status'
|
|
118
|
+
);
|
|
119
|
+
return;
|
|
120
|
+
}
|
|
92
121
|
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
throw ClixError.unknownError({
|
|
97
|
-
reason: `Failed to remove user properties: ${error}`,
|
|
98
|
-
cause: error,
|
|
99
|
-
});
|
|
122
|
+
if (this.currentDevice.isPushPermissionGranted === isGranted) {
|
|
123
|
+
ClixLogger.debug('Push permission status is unchanged, skipping update');
|
|
124
|
+
return;
|
|
100
125
|
}
|
|
101
|
-
}
|
|
102
126
|
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
127
|
+
const newDevice = this.currentDevice.copyWith({
|
|
128
|
+
isPushPermissionGranted: isGranted,
|
|
129
|
+
});
|
|
130
|
+
this.currentDevice = newDevice;
|
|
106
131
|
|
|
107
|
-
|
|
108
|
-
|
|
132
|
+
return this.deviceAPIService.upsertDevice(newDevice);
|
|
133
|
+
}
|
|
109
134
|
|
|
110
|
-
|
|
135
|
+
async setProjectUserId(projectUserId: string): Promise<void> {
|
|
136
|
+
const deviceId = this.getCurrentDeviceId();
|
|
137
|
+
return this.deviceAPIService.setProjectUserId(deviceId, projectUserId);
|
|
138
|
+
}
|
|
111
139
|
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
// Don't throw for token upsert failures during initialization
|
|
117
|
-
// This allows the SDK to continue initializing even if token registration fails
|
|
118
|
-
if (
|
|
119
|
-
error instanceof Error &&
|
|
120
|
-
error.message.includes('crypto.getRandomValues')
|
|
121
|
-
) {
|
|
122
|
-
ClixLogger.warn(
|
|
123
|
-
'Token upsert failed due to crypto polyfill issue, will retry later'
|
|
124
|
-
);
|
|
125
|
-
return;
|
|
126
|
-
}
|
|
127
|
-
|
|
128
|
-
throw ClixError.unknownError({
|
|
129
|
-
reason: `Failed to upsert token: ${error}`,
|
|
130
|
-
cause: error,
|
|
131
|
-
});
|
|
132
|
-
}
|
|
140
|
+
async removeProjectUserId(): Promise<void> {
|
|
141
|
+
const deviceId = this.getCurrentDeviceId();
|
|
142
|
+
return this.deviceAPIService.removeProjectUserId(deviceId);
|
|
133
143
|
}
|
|
134
144
|
|
|
135
|
-
async
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
145
|
+
async updateUserProperties(properties: Record<string, any>): Promise<void> {
|
|
146
|
+
const deviceId = this.getCurrentDeviceId();
|
|
147
|
+
const userProperties = Object.entries(properties).map(([key, value]) =>
|
|
148
|
+
ClixUserProperty.of(key, value)
|
|
149
|
+
);
|
|
150
|
+
return this.deviceAPIService.upsertUserProperties(deviceId, userProperties);
|
|
151
|
+
}
|
|
140
152
|
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
);
|
|
145
|
-
} catch (error) {
|
|
146
|
-
ClixLogger.error('Failed to upsert push permission status', error);
|
|
147
|
-
throw ClixError.unknownError({
|
|
148
|
-
reason: `Failed to upsert push permission status: ${error}`,
|
|
149
|
-
cause: error,
|
|
150
|
-
});
|
|
151
|
-
}
|
|
153
|
+
async removeUserProperties(names: string[]): Promise<void> {
|
|
154
|
+
const deviceId = this.getCurrentDeviceId();
|
|
155
|
+
return this.deviceAPIService.removeUserProperties(deviceId, names);
|
|
152
156
|
}
|
|
153
157
|
|
|
154
158
|
private async getPushPermissionStatus(): Promise<boolean> {
|
|
@@ -158,9 +162,6 @@ export class DeviceService {
|
|
|
158
162
|
authStatus === messaging.AuthorizationStatus.AUTHORIZED ||
|
|
159
163
|
authStatus === messaging.AuthorizationStatus.PROVISIONAL;
|
|
160
164
|
|
|
161
|
-
ClixLogger.debug(
|
|
162
|
-
`Push permission status: ${isGranted ? 'granted' : 'denied'}`
|
|
163
|
-
);
|
|
164
165
|
return isGranted;
|
|
165
166
|
} catch (error) {
|
|
166
167
|
ClixLogger.warn(
|
|
@@ -171,49 +172,14 @@ export class DeviceService {
|
|
|
171
172
|
}
|
|
172
173
|
}
|
|
173
174
|
|
|
174
|
-
async
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
const model = DeviceInfo.getModel();
|
|
184
|
-
const appName = DeviceInfo.getApplicationName();
|
|
185
|
-
const appVersion = DeviceInfo.getVersion();
|
|
186
|
-
const timezone = Intl.DateTimeFormat().resolvedOptions().timeZone;
|
|
187
|
-
const locale = Intl.DateTimeFormat().resolvedOptions().locale || 'en-US';
|
|
188
|
-
const localeLanguage = locale.split('-')[0] || 'en';
|
|
189
|
-
const localeRegion = locale.split('-')[1] || 'US';
|
|
190
|
-
let adId: string | undefined;
|
|
191
|
-
const pushPermissionGranted =
|
|
192
|
-
isPushPermissionGranted ?? (await this.getPushPermissionStatus());
|
|
193
|
-
const sdkVersion = await ClixVersion.getVersion();
|
|
194
|
-
|
|
195
|
-
return new ClixDevice({
|
|
196
|
-
id: deviceId,
|
|
197
|
-
platform,
|
|
198
|
-
model,
|
|
199
|
-
manufacturer,
|
|
200
|
-
osName,
|
|
201
|
-
osVersion,
|
|
202
|
-
localeRegion,
|
|
203
|
-
localeLanguage,
|
|
204
|
-
timezone,
|
|
205
|
-
appName,
|
|
206
|
-
appVersion,
|
|
207
|
-
sdkType: 'react-native',
|
|
208
|
-
sdkVersion,
|
|
209
|
-
adId,
|
|
210
|
-
isPushPermissionGranted: pushPermissionGranted,
|
|
211
|
-
pushToken: token,
|
|
212
|
-
pushTokenType: token
|
|
213
|
-
? Platform.OS === 'ios'
|
|
214
|
-
? 'APNS'
|
|
215
|
-
: 'FCM'
|
|
216
|
-
: undefined,
|
|
217
|
-
});
|
|
175
|
+
private async getPushToken(): Promise<string | undefined> {
|
|
176
|
+
try {
|
|
177
|
+
const token = await messaging().getToken();
|
|
178
|
+
this.tokenService.saveToken(token);
|
|
179
|
+
return token;
|
|
180
|
+
} catch (error) {
|
|
181
|
+
ClixLogger.warn('Failed to get push token', error);
|
|
182
|
+
return undefined;
|
|
183
|
+
}
|
|
218
184
|
}
|
|
219
185
|
}
|
|
@@ -27,14 +27,12 @@ export class EventAPIService {
|
|
|
27
27
|
};
|
|
28
28
|
|
|
29
29
|
const response = await this.apiClient.post('/events', {
|
|
30
|
-
|
|
31
|
-
events: [eventRequestBody],
|
|
32
|
-
},
|
|
30
|
+
events: [eventRequestBody],
|
|
33
31
|
});
|
|
34
32
|
|
|
35
|
-
if (response.
|
|
33
|
+
if (response.statusCode < 200 || response.statusCode >= 300) {
|
|
36
34
|
throw new Error(
|
|
37
|
-
`HTTP ${response.
|
|
35
|
+
`HTTP ${response.statusCode}: ${JSON.stringify(response.data)}`
|
|
38
36
|
);
|
|
39
37
|
}
|
|
40
38
|
|
|
@@ -1,5 +1,4 @@
|
|
|
1
1
|
import { ClixDateFormatter } from '../utils/ClixDateFormatter';
|
|
2
|
-
import { ClixLogger } from '../utils/logging/ClixLogger';
|
|
3
2
|
import { DeviceService } from './DeviceService';
|
|
4
3
|
import { EventAPIService } from './EventAPIService';
|
|
5
4
|
|
|
@@ -9,6 +8,23 @@ export class EventService {
|
|
|
9
8
|
private readonly deviceService: DeviceService
|
|
10
9
|
) {}
|
|
11
10
|
|
|
11
|
+
private serializeProperties(
|
|
12
|
+
properties: Record<string, any> = {}
|
|
13
|
+
): Record<string, any> {
|
|
14
|
+
const cleanProperties: Record<string, any> = {};
|
|
15
|
+
|
|
16
|
+
Object.entries(properties).forEach(([key, value]) => {
|
|
17
|
+
if (value instanceof Date) {
|
|
18
|
+
cleanProperties[key] = ClixDateFormatter.format(value);
|
|
19
|
+
return;
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
cleanProperties[key] = value;
|
|
23
|
+
});
|
|
24
|
+
|
|
25
|
+
return cleanProperties;
|
|
26
|
+
}
|
|
27
|
+
|
|
12
28
|
async trackEvent(
|
|
13
29
|
name: string,
|
|
14
30
|
properties?: Record<string, any>,
|
|
@@ -16,38 +32,15 @@ export class EventService {
|
|
|
16
32
|
userJourneyId?: string,
|
|
17
33
|
userJourneyNodeId?: string
|
|
18
34
|
): Promise<void> {
|
|
19
|
-
|
|
20
|
-
ClixLogger.debug(`Tracking event: ${name}`);
|
|
21
|
-
|
|
22
|
-
const deviceId = this.deviceService.getCurrentDeviceId();
|
|
23
|
-
|
|
24
|
-
const cleanProperties: Record<string, any> = {};
|
|
25
|
-
if (properties) {
|
|
26
|
-
Object.entries(properties).forEach(([key, value]) => {
|
|
27
|
-
if (value instanceof Date) {
|
|
28
|
-
cleanProperties[key] = ClixDateFormatter.format(value);
|
|
29
|
-
return;
|
|
30
|
-
}
|
|
31
|
-
|
|
32
|
-
cleanProperties[key] = value;
|
|
33
|
-
});
|
|
34
|
-
}
|
|
35
|
-
|
|
36
|
-
await this.eventAPIService.trackEvent(
|
|
37
|
-
deviceId,
|
|
38
|
-
name,
|
|
39
|
-
cleanProperties,
|
|
40
|
-
messageId,
|
|
41
|
-
userJourneyId,
|
|
42
|
-
userJourneyNodeId
|
|
43
|
-
);
|
|
35
|
+
const deviceId = this.deviceService.getCurrentDeviceId();
|
|
44
36
|
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
37
|
+
await this.eventAPIService.trackEvent(
|
|
38
|
+
deviceId,
|
|
39
|
+
name,
|
|
40
|
+
this.serializeProperties(properties),
|
|
41
|
+
messageId,
|
|
42
|
+
userJourneyId,
|
|
43
|
+
userJourneyNodeId
|
|
44
|
+
);
|
|
52
45
|
}
|
|
53
46
|
}
|