@datalyr/react-native 1.7.5 → 1.7.6
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/package.json +1 -1
- package/src/datalyr-sdk-expo.ts +86 -0
package/package.json
CHANGED
package/src/datalyr-sdk-expo.ts
CHANGED
|
@@ -206,6 +206,11 @@ export class DatalyrSDKExpo {
|
|
|
206
206
|
}
|
|
207
207
|
|
|
208
208
|
if (attributionManager.isInstall()) {
|
|
209
|
+
// iOS: Attempt deferred web-to-app attribution via IP matching before tracking install
|
|
210
|
+
if (Platform.OS === 'ios') {
|
|
211
|
+
await this.fetchDeferredWebAttribution();
|
|
212
|
+
}
|
|
213
|
+
|
|
209
214
|
const installData = await attributionManager.trackInstall();
|
|
210
215
|
await this.track('app_install', {
|
|
211
216
|
platform: Platform.OS,
|
|
@@ -376,6 +381,87 @@ export class DatalyrSDKExpo {
|
|
|
376
381
|
}
|
|
377
382
|
}
|
|
378
383
|
|
|
384
|
+
/**
|
|
385
|
+
* Fetch deferred web attribution on first app install.
|
|
386
|
+
* Uses IP-based matching to recover attribution data (fbclid, utm_*, etc.)
|
|
387
|
+
* from a prelander web visit. Called automatically during initialize()
|
|
388
|
+
* when a fresh install is detected on iOS.
|
|
389
|
+
*/
|
|
390
|
+
private async fetchDeferredWebAttribution(): Promise<void> {
|
|
391
|
+
if (!this.state.config?.apiKey) {
|
|
392
|
+
debugLog('API key not available for deferred attribution fetch');
|
|
393
|
+
return;
|
|
394
|
+
}
|
|
395
|
+
|
|
396
|
+
try {
|
|
397
|
+
debugLog('Fetching deferred web attribution via IP matching...');
|
|
398
|
+
|
|
399
|
+
const controller = new AbortController();
|
|
400
|
+
const timeout = setTimeout(() => controller.abort(), 10000);
|
|
401
|
+
|
|
402
|
+
const response = await fetch('https://api.datalyr.com/attribution/deferred-lookup', {
|
|
403
|
+
method: 'POST',
|
|
404
|
+
headers: {
|
|
405
|
+
'Content-Type': 'application/json',
|
|
406
|
+
'X-Datalyr-API-Key': this.state.config.apiKey!,
|
|
407
|
+
},
|
|
408
|
+
body: JSON.stringify({ platform: Platform.OS }),
|
|
409
|
+
signal: controller.signal,
|
|
410
|
+
});
|
|
411
|
+
|
|
412
|
+
clearTimeout(timeout);
|
|
413
|
+
|
|
414
|
+
if (!response.ok) {
|
|
415
|
+
debugLog('Deferred attribution lookup failed:', response.status);
|
|
416
|
+
return;
|
|
417
|
+
}
|
|
418
|
+
|
|
419
|
+
const result = await response.json() as { found: boolean; attribution?: any };
|
|
420
|
+
|
|
421
|
+
if (!result.found || !result.attribution) {
|
|
422
|
+
debugLog('No deferred web attribution found for this IP');
|
|
423
|
+
return;
|
|
424
|
+
}
|
|
425
|
+
|
|
426
|
+
const webAttribution = result.attribution;
|
|
427
|
+
debugLog('Deferred web attribution found:', {
|
|
428
|
+
visitor_id: webAttribution.visitor_id,
|
|
429
|
+
has_fbclid: !!webAttribution.fbclid,
|
|
430
|
+
has_gclid: !!webAttribution.gclid,
|
|
431
|
+
utm_source: webAttribution.utm_source,
|
|
432
|
+
});
|
|
433
|
+
|
|
434
|
+
// Merge web attribution into current session
|
|
435
|
+
attributionManager.mergeWebAttribution(webAttribution);
|
|
436
|
+
|
|
437
|
+
// Track match event for analytics
|
|
438
|
+
await this.track('$web_attribution_matched', {
|
|
439
|
+
web_visitor_id: webAttribution.visitor_id,
|
|
440
|
+
web_user_id: webAttribution.user_id,
|
|
441
|
+
fbclid: webAttribution.fbclid,
|
|
442
|
+
gclid: webAttribution.gclid,
|
|
443
|
+
ttclid: webAttribution.ttclid,
|
|
444
|
+
gbraid: webAttribution.gbraid,
|
|
445
|
+
wbraid: webAttribution.wbraid,
|
|
446
|
+
fbp: webAttribution.fbp,
|
|
447
|
+
fbc: webAttribution.fbc,
|
|
448
|
+
utm_source: webAttribution.utm_source,
|
|
449
|
+
utm_medium: webAttribution.utm_medium,
|
|
450
|
+
utm_campaign: webAttribution.utm_campaign,
|
|
451
|
+
utm_content: webAttribution.utm_content,
|
|
452
|
+
utm_term: webAttribution.utm_term,
|
|
453
|
+
web_timestamp: webAttribution.timestamp,
|
|
454
|
+
match_method: 'ip',
|
|
455
|
+
});
|
|
456
|
+
|
|
457
|
+
debugLog('Successfully merged deferred web attribution');
|
|
458
|
+
|
|
459
|
+
} catch (error) {
|
|
460
|
+
errorLog('Error fetching deferred web attribution:', error as Error);
|
|
461
|
+
// Non-blocking - email-based fallback will catch this on identify()
|
|
462
|
+
}
|
|
463
|
+
}
|
|
464
|
+
|
|
379
465
|
async alias(newUserId: string, previousId?: string): Promise<void> {
|
|
380
466
|
try {
|
|
381
467
|
if (!newUserId || typeof newUserId !== 'string') {
|