@datalyr/react-native 1.4.9 → 1.6.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.
Files changed (38) hide show
  1. package/CHANGELOG.md +39 -0
  2. package/README.md +17 -127
  3. package/android/build.gradle +0 -7
  4. package/android/src/main/java/com/datalyr/reactnative/DatalyrNativeModule.java +2 -380
  5. package/android/src/main/java/com/datalyr/reactnative/DatalyrPackage.java +1 -1
  6. package/datalyr-react-native.podspec +3 -7
  7. package/expo-module.config.json +4 -1
  8. package/ios/DatalyrNativeModule.swift +0 -266
  9. package/lib/datalyr-sdk.d.ts +8 -4
  10. package/lib/datalyr-sdk.js +83 -143
  11. package/lib/http-client.js +2 -2
  12. package/lib/index.d.ts +1 -1
  13. package/lib/index.js +1 -1
  14. package/lib/integrations/index.d.ts +3 -4
  15. package/lib/integrations/index.js +3 -4
  16. package/lib/native/DatalyrNativeBridge.d.ts +6 -22
  17. package/lib/native/DatalyrNativeBridge.js +6 -147
  18. package/lib/native/index.d.ts +1 -1
  19. package/lib/native/index.js +1 -1
  20. package/lib/types.d.ts +1 -19
  21. package/package.json +3 -5
  22. package/src/datalyr-sdk-expo.ts +6 -141
  23. package/src/datalyr-sdk.ts +96 -173
  24. package/src/http-client.ts +2 -2
  25. package/src/index.ts +1 -1
  26. package/src/integrations/index.ts +3 -4
  27. package/src/native/DatalyrNativeBridge.ts +6 -241
  28. package/src/native/index.ts +0 -2
  29. package/src/types.ts +2 -25
  30. package/src/utils-expo.ts +2 -2
  31. package/ios/DatalyrObjCExceptionCatcher.h +0 -14
  32. package/ios/DatalyrObjCExceptionCatcher.m +0 -30
  33. package/lib/integrations/meta-integration.d.ts +0 -77
  34. package/lib/integrations/meta-integration.js +0 -219
  35. package/lib/integrations/tiktok-integration.d.ts +0 -83
  36. package/lib/integrations/tiktok-integration.js +0 -360
  37. package/src/integrations/meta-integration.ts +0 -239
  38. package/src/integrations/tiktok-integration.ts +0 -363
@@ -1,6 +1,5 @@
1
1
  package com.datalyr.reactnative;
2
2
 
3
- import android.os.Bundle;
4
3
  import android.util.Log;
5
4
 
6
5
  import com.facebook.react.bridge.Arguments;
@@ -8,44 +7,21 @@ import com.facebook.react.bridge.Promise;
8
7
  import com.facebook.react.bridge.ReactApplicationContext;
9
8
  import com.facebook.react.bridge.ReactContextBaseJavaModule;
10
9
  import com.facebook.react.bridge.ReactMethod;
11
- import com.facebook.react.bridge.ReadableMap;
12
- import com.facebook.react.bridge.ReadableMapKeySetIterator;
13
10
  import com.facebook.react.bridge.WritableMap;
14
11
 
15
- // Meta (Facebook) SDK imports
16
- import com.facebook.FacebookSdk;
17
- import com.facebook.appevents.AppEventsLogger;
18
- import com.facebook.appevents.AppEventsConstants;
19
- import com.facebook.appevents.UserDataStore;
20
- import com.facebook.bolts.AppLinks;
21
- import android.net.Uri;
22
-
23
- // TikTok SDK imports
24
- import com.tiktok.TikTokBusinessSdk;
25
- import com.tiktok.TikTokBusinessSdk.TTConfig;
26
- import com.tiktok.appevents.TikTokAppEvent;
27
- import com.tiktok.appevents.TikTokAppEventLogger;
28
-
29
12
  import com.google.android.gms.ads.identifier.AdvertisingIdClient;
30
13
  import com.google.android.gms.common.GooglePlayServicesNotAvailableException;
31
14
 
32
- import java.math.BigDecimal;
33
- import java.util.Currency;
34
- import java.util.HashMap;
35
- import java.util.Map;
36
-
37
15
  /**
38
16
  * Datalyr Native Module for Android
39
- * Provides Meta (Facebook) and TikTok SDK integrations for React Native
17
+ * Provides advertiser info (GAID) for React Native.
18
+ * Conversion event routing to ad platforms is handled server-side via postback.
40
19
  */
41
20
  public class DatalyrNativeModule extends ReactContextBaseJavaModule {
42
21
  private static final String TAG = "DatalyrNative";
43
22
  private static final String MODULE_NAME = "DatalyrNative";
44
23
 
45
24
  private final ReactApplicationContext reactContext;
46
- private AppEventsLogger metaLogger;
47
- private boolean metaInitialized = false;
48
- private boolean tiktokInitialized = false;
49
25
 
50
26
  public DatalyrNativeModule(ReactApplicationContext context) {
51
27
  super(context);
@@ -57,328 +33,6 @@ public class DatalyrNativeModule extends ReactContextBaseJavaModule {
57
33
  return MODULE_NAME;
58
34
  }
59
35
 
60
- // ============================================================================
61
- // Meta (Facebook) SDK Methods
62
- // ============================================================================
63
-
64
- @ReactMethod
65
- public void initializeMetaSDK(String appId, String clientToken, boolean advertiserTrackingEnabled, Promise promise) {
66
- try {
67
- // Initialize Facebook SDK
68
- FacebookSdk.setApplicationId(appId);
69
- if (clientToken != null && !clientToken.isEmpty()) {
70
- FacebookSdk.setClientToken(clientToken);
71
- }
72
- FacebookSdk.setAdvertiserIDCollectionEnabled(advertiserTrackingEnabled);
73
- FacebookSdk.setAutoLogAppEventsEnabled(true);
74
- FacebookSdk.sdkInitialize(reactContext.getApplicationContext());
75
-
76
- // Create logger instance
77
- metaLogger = AppEventsLogger.newLogger(reactContext.getApplicationContext());
78
- metaInitialized = true;
79
-
80
- Log.d(TAG, "Meta SDK initialized with App ID: " + appId);
81
- promise.resolve(true);
82
- } catch (Exception e) {
83
- Log.e(TAG, "Failed to initialize Meta SDK", e);
84
- promise.reject("meta_init_error", "Failed to initialize Meta SDK: " + e.getMessage());
85
- }
86
- }
87
-
88
- @ReactMethod
89
- public void fetchDeferredAppLink(Promise promise) {
90
- if (!metaInitialized) {
91
- promise.resolve(null);
92
- return;
93
- }
94
-
95
- try {
96
- AppLinks.getTargetUrlFromInboundIntent(reactContext.getApplicationContext(), reactContext.getCurrentActivity().getIntent())
97
- .continueWith(task -> {
98
- if (task.getError() != null) {
99
- Log.d(TAG, "Deferred app link error: " + task.getError().getMessage());
100
- promise.resolve(null);
101
- return null;
102
- }
103
-
104
- Uri targetUrl = task.getResult();
105
- if (targetUrl != null) {
106
- promise.resolve(targetUrl.toString());
107
- } else {
108
- promise.resolve(null);
109
- }
110
- return null;
111
- });
112
- } catch (Exception e) {
113
- Log.d(TAG, "Deferred app link not available");
114
- promise.resolve(null);
115
- }
116
- }
117
-
118
- @ReactMethod
119
- public void logMetaEvent(String eventName, Double valueToSum, ReadableMap parameters, Promise promise) {
120
- if (!metaInitialized || metaLogger == null) {
121
- promise.resolve(false);
122
- return;
123
- }
124
-
125
- try {
126
- Bundle params = readableMapToBundle(parameters);
127
-
128
- if (valueToSum != null) {
129
- metaLogger.logEvent(eventName, valueToSum, params);
130
- } else if (params.isEmpty()) {
131
- metaLogger.logEvent(eventName);
132
- } else {
133
- metaLogger.logEvent(eventName, params);
134
- }
135
-
136
- Log.d(TAG, "Meta event logged: " + eventName);
137
- promise.resolve(true);
138
- } catch (Exception e) {
139
- Log.e(TAG, "Failed to log Meta event", e);
140
- promise.reject("meta_event_error", "Failed to log Meta event: " + e.getMessage());
141
- }
142
- }
143
-
144
- @ReactMethod
145
- public void logMetaPurchase(double amount, String currency, ReadableMap parameters, Promise promise) {
146
- if (!metaInitialized || metaLogger == null) {
147
- promise.resolve(false);
148
- return;
149
- }
150
-
151
- try {
152
- Bundle params = readableMapToBundle(parameters);
153
- BigDecimal purchaseAmount = BigDecimal.valueOf(amount);
154
- Currency currencyObj = Currency.getInstance(currency);
155
-
156
- metaLogger.logPurchase(purchaseAmount, currencyObj, params);
157
-
158
- Log.d(TAG, "Meta purchase logged: " + amount + " " + currency);
159
- promise.resolve(true);
160
- } catch (Exception e) {
161
- Log.e(TAG, "Failed to log Meta purchase", e);
162
- promise.reject("meta_purchase_error", "Failed to log Meta purchase: " + e.getMessage());
163
- }
164
- }
165
-
166
- @ReactMethod
167
- public void setMetaUserData(ReadableMap userData, Promise promise) {
168
- if (!metaInitialized) {
169
- promise.resolve(false);
170
- return;
171
- }
172
-
173
- try {
174
- // Set user data for Advanced Matching
175
- Bundle userDataBundle = new Bundle();
176
-
177
- if (userData.hasKey("email")) {
178
- userDataBundle.putString("em", userData.getString("email"));
179
- }
180
- if (userData.hasKey("firstName")) {
181
- userDataBundle.putString("fn", userData.getString("firstName"));
182
- }
183
- if (userData.hasKey("lastName")) {
184
- userDataBundle.putString("ln", userData.getString("lastName"));
185
- }
186
- if (userData.hasKey("phone")) {
187
- userDataBundle.putString("ph", userData.getString("phone"));
188
- }
189
- if (userData.hasKey("dateOfBirth")) {
190
- userDataBundle.putString("db", userData.getString("dateOfBirth"));
191
- }
192
- if (userData.hasKey("gender")) {
193
- userDataBundle.putString("ge", userData.getString("gender"));
194
- }
195
- if (userData.hasKey("city")) {
196
- userDataBundle.putString("ct", userData.getString("city"));
197
- }
198
- if (userData.hasKey("state")) {
199
- userDataBundle.putString("st", userData.getString("state"));
200
- }
201
- if (userData.hasKey("zip")) {
202
- userDataBundle.putString("zp", userData.getString("zip"));
203
- }
204
- if (userData.hasKey("country")) {
205
- userDataBundle.putString("country", userData.getString("country"));
206
- }
207
-
208
- AppEventsLogger.setUserData(
209
- userData.hasKey("email") ? userData.getString("email") : null,
210
- userData.hasKey("firstName") ? userData.getString("firstName") : null,
211
- userData.hasKey("lastName") ? userData.getString("lastName") : null,
212
- userData.hasKey("phone") ? userData.getString("phone") : null,
213
- userData.hasKey("dateOfBirth") ? userData.getString("dateOfBirth") : null,
214
- userData.hasKey("gender") ? userData.getString("gender") : null,
215
- userData.hasKey("city") ? userData.getString("city") : null,
216
- userData.hasKey("state") ? userData.getString("state") : null,
217
- userData.hasKey("zip") ? userData.getString("zip") : null,
218
- userData.hasKey("country") ? userData.getString("country") : null
219
- );
220
-
221
- Log.d(TAG, "Meta user data set for Advanced Matching");
222
- promise.resolve(true);
223
- } catch (Exception e) {
224
- Log.e(TAG, "Failed to set Meta user data", e);
225
- promise.reject("meta_userdata_error", "Failed to set Meta user data: " + e.getMessage());
226
- }
227
- }
228
-
229
- @ReactMethod
230
- public void clearMetaUserData(Promise promise) {
231
- if (!metaInitialized) {
232
- promise.resolve(false);
233
- return;
234
- }
235
-
236
- try {
237
- AppEventsLogger.clearUserData();
238
- Log.d(TAG, "Meta user data cleared");
239
- promise.resolve(true);
240
- } catch (Exception e) {
241
- Log.e(TAG, "Failed to clear Meta user data", e);
242
- promise.reject("meta_clear_error", "Failed to clear Meta user data: " + e.getMessage());
243
- }
244
- }
245
-
246
- @ReactMethod
247
- public void updateMetaTrackingAuthorization(boolean enabled, Promise promise) {
248
- try {
249
- FacebookSdk.setAdvertiserIDCollectionEnabled(enabled);
250
- Log.d(TAG, "Meta tracking authorization updated: " + enabled);
251
- promise.resolve(true);
252
- } catch (Exception e) {
253
- Log.e(TAG, "Failed to update Meta tracking authorization", e);
254
- promise.reject("meta_tracking_error", "Failed to update Meta tracking: " + e.getMessage());
255
- }
256
- }
257
-
258
- // ============================================================================
259
- // TikTok SDK Methods
260
- // ============================================================================
261
-
262
- @ReactMethod
263
- public void initializeTikTokSDK(String appId, String tiktokAppId, String accessToken, boolean debug, Promise promise) {
264
- try {
265
- TTConfig config = new TTConfig(reactContext.getApplicationContext())
266
- .setAppId(appId)
267
- .setTTAppId(tiktokAppId);
268
-
269
- if (accessToken != null && !accessToken.isEmpty()) {
270
- config.setAccessToken(accessToken);
271
- }
272
-
273
- if (debug) {
274
- config.openDebugMode();
275
- }
276
-
277
- TikTokBusinessSdk.initializeSdk(config);
278
- tiktokInitialized = true;
279
-
280
- Log.d(TAG, "TikTok SDK initialized with App ID: " + tiktokAppId);
281
- promise.resolve(true);
282
- } catch (Exception e) {
283
- Log.e(TAG, "Failed to initialize TikTok SDK", e);
284
- promise.reject("tiktok_init_error", "Failed to initialize TikTok SDK: " + e.getMessage());
285
- }
286
- }
287
-
288
- @ReactMethod
289
- public void trackTikTokEvent(String eventName, String eventId, ReadableMap properties, Promise promise) {
290
- if (!tiktokInitialized) {
291
- promise.resolve(false);
292
- return;
293
- }
294
-
295
- try {
296
- TikTokAppEvent event;
297
- if (eventId != null && !eventId.isEmpty()) {
298
- event = new TikTokAppEvent(eventName).setEventId(eventId);
299
- } else {
300
- event = new TikTokAppEvent(eventName);
301
- }
302
-
303
- // Add properties to the event
304
- if (properties != null) {
305
- ReadableMapKeySetIterator iterator = properties.keySetIterator();
306
- while (iterator.hasNextKey()) {
307
- String key = iterator.nextKey();
308
- switch (properties.getType(key)) {
309
- case String:
310
- event.addProperty(key, properties.getString(key));
311
- break;
312
- case Number:
313
- event.addProperty(key, properties.getDouble(key));
314
- break;
315
- case Boolean:
316
- event.addProperty(key, properties.getBoolean(key));
317
- break;
318
- default:
319
- break;
320
- }
321
- }
322
- }
323
-
324
- TikTokBusinessSdk.trackTTEvent(event);
325
-
326
- Log.d(TAG, "TikTok event logged: " + eventName);
327
- promise.resolve(true);
328
- } catch (Exception e) {
329
- Log.e(TAG, "Failed to log TikTok event", e);
330
- promise.reject("tiktok_event_error", "Failed to log TikTok event: " + e.getMessage());
331
- }
332
- }
333
-
334
- @ReactMethod
335
- public void identifyTikTokUser(String externalId, String externalUserName, String phoneNumber, String email, Promise promise) {
336
- if (!tiktokInitialized) {
337
- promise.resolve(false);
338
- return;
339
- }
340
-
341
- try {
342
- TikTokBusinessSdk.identify(
343
- externalId != null && !externalId.isEmpty() ? externalId : null,
344
- externalUserName != null && !externalUserName.isEmpty() ? externalUserName : null,
345
- phoneNumber != null && !phoneNumber.isEmpty() ? phoneNumber : null,
346
- email != null && !email.isEmpty() ? email : null
347
- );
348
-
349
- Log.d(TAG, "TikTok user identified");
350
- promise.resolve(true);
351
- } catch (Exception e) {
352
- Log.e(TAG, "Failed to identify TikTok user", e);
353
- promise.reject("tiktok_identify_error", "Failed to identify TikTok user: " + e.getMessage());
354
- }
355
- }
356
-
357
- @ReactMethod
358
- public void logoutTikTok(Promise promise) {
359
- if (!tiktokInitialized) {
360
- promise.resolve(false);
361
- return;
362
- }
363
-
364
- try {
365
- TikTokBusinessSdk.logout();
366
- Log.d(TAG, "TikTok user logged out");
367
- promise.resolve(true);
368
- } catch (Exception e) {
369
- Log.e(TAG, "Failed to logout TikTok user", e);
370
- promise.reject("tiktok_logout_error", "Failed to logout TikTok user: " + e.getMessage());
371
- }
372
- }
373
-
374
- @ReactMethod
375
- public void updateTikTokTrackingAuthorization(boolean enabled, Promise promise) {
376
- // TikTok SDK handles this automatically on Android
377
- // No explicit method needed
378
- Log.d(TAG, "TikTok tracking authorization update requested: " + enabled);
379
- promise.resolve(true);
380
- }
381
-
382
36
  // ============================================================================
383
37
  // SDK Availability
384
38
  // ============================================================================
@@ -386,8 +40,6 @@ public class DatalyrNativeModule extends ReactContextBaseJavaModule {
386
40
  @ReactMethod
387
41
  public void getSDKAvailability(Promise promise) {
388
42
  WritableMap result = Arguments.createMap();
389
- result.putBoolean("meta", true);
390
- result.putBoolean("tiktok", true);
391
43
  result.putBoolean("playInstallReferrer", true);
392
44
  // Apple Search Ads is iOS only
393
45
  result.putBoolean("appleSearchAds", false);
@@ -434,34 +86,4 @@ public class DatalyrNativeModule extends ReactContextBaseJavaModule {
434
86
  }
435
87
  }).start();
436
88
  }
437
-
438
- // ============================================================================
439
- // Helper Methods
440
- // ============================================================================
441
-
442
- private Bundle readableMapToBundle(ReadableMap map) {
443
- Bundle bundle = new Bundle();
444
- if (map == null) {
445
- return bundle;
446
- }
447
-
448
- ReadableMapKeySetIterator iterator = map.keySetIterator();
449
- while (iterator.hasNextKey()) {
450
- String key = iterator.nextKey();
451
- switch (map.getType(key)) {
452
- case String:
453
- bundle.putString(key, map.getString(key));
454
- break;
455
- case Number:
456
- bundle.putDouble(key, map.getDouble(key));
457
- break;
458
- case Boolean:
459
- bundle.putBoolean(key, map.getBoolean(key));
460
- break;
461
- default:
462
- break;
463
- }
464
- }
465
- return bundle;
466
- }
467
89
  }
@@ -11,7 +11,7 @@ import java.util.List;
11
11
 
12
12
  /**
13
13
  * React Native Package for Datalyr SDK
14
- * Registers all native modules (Meta, TikTok, Play Install Referrer)
14
+ * Registers native modules (Datalyr, Play Install Referrer)
15
15
  */
16
16
  public class DatalyrPackage implements ReactPackage {
17
17
 
@@ -7,9 +7,9 @@ Pod::Spec.new do |s|
7
7
  s.version = package['version']
8
8
  s.summary = package['description']
9
9
  s.description = <<-DESC
10
- Datalyr SDK for React Native with bundled Meta (Facebook) and TikTok SDKs.
11
- Provides deferred deep linking, event forwarding, and advanced attribution
12
- without requiring users to install additional packages.
10
+ Datalyr SDK for React Native with server-side attribution tracking.
11
+ Provides event capture, Apple Search Ads attribution, and Play Install
12
+ Referrer support. Conversion routing handled server-side via postback.
13
13
  DESC
14
14
  s.homepage = package['homepage']
15
15
  s.license = package['license']
@@ -20,12 +20,8 @@ Pod::Spec.new do |s|
20
20
  s.swift_version = "5.0"
21
21
 
22
22
  s.dependency "ExpoModulesCore"
23
- s.dependency "FBSDKCoreKit", "~> 18.0"
24
- s.dependency "TikTokBusinessSDK", "1.6.0"
25
23
 
26
- # Disable bitcode (required for TikTok SDK)
27
24
  s.pod_target_xcconfig = {
28
- 'ENABLE_BITCODE' => 'NO',
29
25
  'DEFINES_MODULE' => 'YES'
30
26
  }
31
27
  end
@@ -1,6 +1,9 @@
1
1
  {
2
- "platforms": ["ios"],
2
+ "platforms": ["ios", "android"],
3
3
  "ios": {
4
4
  "modules": ["DatalyrNativeModule", "DatalyrSKAdNetworkModule"]
5
+ },
6
+ "android": {
7
+ "modules": ["com.datalyr.reactnative.DatalyrPackage"]
5
8
  }
6
9
  }