Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 2 additions & 2 deletions example/ios/Podfile.lock
Original file line number Diff line number Diff line change
Expand Up @@ -286,7 +286,7 @@ PODS:
- React
- RNGestureHandler (2.3.0):
- React-Core
- segment-analytics-react-native (2.1.11):
- segment-analytics-react-native (2.1.12):
- React-Core
- sovran-react-native
- segment-analytics-react-native-plugin-idfa (0.2.1):
Expand Down Expand Up @@ -459,7 +459,7 @@ SPEC CHECKSUMS:
RNCAsyncStorage: b49b4e38a1548d03b74b30e558a1d18465b94be7
RNCMaskedView: 0e1bc4bfa8365eba5fbbb71e07fbdc0555249489
RNGestureHandler: 77d59828d40838c9fabb76a12d2d0a80c006906f
segment-analytics-react-native: b251b9e7277a8cbf0a8379d9bca155f0aa1d5d4a
segment-analytics-react-native: 5287504fa5aa60e64dbb497bee5c7eb6f94e5e49
segment-analytics-react-native-plugin-idfa: 80e5d610f537156833eabea12a1804523355de95
sovran-react-native: ef02f663b489ac5e63ea7b80cd8426bf82992263
Yoga: 90dcd029e45d8a7c1ff059e8b3c6612ff409061a
Expand Down
2 changes: 1 addition & 1 deletion packages/plugins/plugin-adjust/src/AdjustPlugin.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@ export class AdjustPlugin extends DestinationPlugin {
key = 'Adjust';

private settings: SegmentAdjustSettings | null = null;
private hasRegisteredCallback: Boolean = false;
private hasRegisteredCallback: boolean = false;

update(settings: SegmentAPISettings, _: UpdateType) {
const adjustSettings = settings.integrations[
Expand Down
95 changes: 85 additions & 10 deletions packages/plugins/plugin-appsflyer/src/AppsflyerPlugin.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -3,27 +3,65 @@ import {
IdentifyEventType,
PluginType,
TrackEventType,
UpdateType,
SegmentAPISettings,
} from '@segment/analytics-react-native';
import appsFlyer, { InitSDKOptions } from 'react-native-appsflyer';
import type { SegmentAppsflyerSettings } from './types';
import appsFlyer from 'react-native-appsflyer';
import identify from './methods/identify';
import track from './methods/track';

export class AppsflyerPlugin extends DestinationPlugin {
type = PluginType.destination;
key = 'Appsflyer';
key = 'AppsFlyer';

constructor(opts: InitSDKOptions) {
super();
private settings: SegmentAppsflyerSettings | null = null;
private hasRegisteredInstallCallback: boolean = false;
private hasRegisteredDeepLinkCallback: boolean = false;
private hasInitialized: boolean = false;

const defaultOpts = {
isDebug: true,
update(settings: SegmentAPISettings, _: UpdateType) {
let defaultOpts = {
isDebug: false,
timeToWaitForATTUserAuthorization: 60,
onInstallConversionDataListener: true,
};

appsFlyer.initSdk({
...defaultOpts,
...opts,
});
const appsflyerSettings = settings.integrations[
this.key
] as SegmentAppsflyerSettings;

if (appsflyerSettings === undefined) {
return;
}
const clientConfig = this.analytics?.getConfig();

this.settings = appsflyerSettings;

if (
this.settings.trackAttributionData &&
!this.hasRegisteredInstallCallback
) {
this.registerConversionCallback();
this.hasRegisteredInstallCallback = true;
}

if (
clientConfig?.trackDeepLinks === true &&
!this.hasRegisteredDeepLinkCallback
) {
this.registerDeepLinkCallback();
this.hasRegisteredDeepLinkCallback = true;
}
if (!this.hasInitialized) {
appsFlyer.initSdk({
devKey: this.settings.appsFlyerDevKey,
appId: this.settings.appleAppID,
onDeepLinkListener: clientConfig?.trackDeepLinks === true,
...defaultOpts,
});
this.hasInitialized = true;
}
}

identify(event: IdentifyEventType) {
Expand All @@ -35,4 +73,41 @@ export class AppsflyerPlugin extends DestinationPlugin {
track(event);
return event;
}

registerConversionCallback = () => {
appsFlyer.onInstallConversionData((res) => {
const { af_status, media_source, campaign, is_first_launch } = res?.data;
const properties = {
provider: this.key,
campaign: {
source: media_source,
name: campaign,
},
};

if (is_first_launch === 'true') {
if (af_status === 'Non-organic') {
this.analytics?.track('Install Attributed', properties);
} else {
this.analytics?.track('Organic Install', { provider: 'AppsFlyer' });
}
}
});
};

registerDeepLinkCallback = () => {
appsFlyer.onAppOpenAttribution((res) => {
if (res?.status === 'success') {
const { campaign, media_source } = res.data;
const properties = {
provider: this.key,
campaign: {
name: campaign,
source: media_source,
},
};
this.analytics?.track('Deep Link Opened', properties);
}
});
};
}
9 changes: 9 additions & 0 deletions packages/plugins/plugin-appsflyer/src/types.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
export type SegmentAppsflyerSettings = {
appleAppID?: string;
appsFlyerDevKey: string;
httpFallback: boolean;
rokuAppID?: string;
trackAttributionData: boolean;
type: string;
versionSettings: { [key: string]: string[] };
};