Skip to content

Commit

Permalink
Merge pull request #573 from AppsFlyerSDK/dev/DELIVERY-67803/logAdRev…
Browse files Browse the repository at this point in the history
…enue-and-6.15.1

Updated to 6.15.1 , added logAdRevenue
  • Loading branch information
al-af authored Sep 4, 2024
2 parents 22c2175 + e6c87d9 commit fb27417
Show file tree
Hide file tree
Showing 19 changed files with 361 additions and 21 deletions.
2 changes: 2 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -65,3 +65,5 @@ demos/appsflyer-expo-app/android
demos/appsflyer-expo-app/.expo
demos/appsflyer-expo-app/node_modules
demos/appsflyer-expo-app/yarn.lock

demos/appsflyer-react-native-app/ios/AppsFlyerExample.xcodeproj/project.pbxproj
40 changes: 40 additions & 0 deletions Docs/RN_API.md
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,7 @@ The list of available methods for this plugin is described below.
- [disableAdvertisingIdentifier](#disableAdvertisingIdentifier)
- [enableTCFDataCollection](#enableTCFDataCollection)
- [setConsentData](#setConsentData)
- [logAdRevenue](#logAdRevenue)
- [Android Only APIs](#android-only-apis)
- [setCollectAndroidID](#setcollectandroidid)
- [setCollectIMEI](#setcollectimei)
Expand Down Expand Up @@ -797,6 +798,45 @@ let GDPRUser = AppsFlyerConsent.forGDPRUser(true, false);
appsFlyer.setConsentData(nonGDPRUser /**or**/ GDPRUser);
```

### logAdRevenue - Since 6.15.1
`logAdRevenue(data: AFAdRevenueData): void`

Use this method to log your ad revenue.</br>
By attributing ad revenue, app owners gain the complete view of user LTV and campaign ROI.
Ad revenue is generated by displaying ads on rewarded videos, offer walls, interstitials, and banners in an app.

#### Parameters

| Param | Type |
| -------------- | ---------------------------------------------------------- |
| **`data`** | `AFAdRevenueData` |

#### Usage Example for React Native:

```javascript
const adRevenueData = {
monetizationNetwork: 'AF-AdNetwork',
mediationNetwork: MEDIATION_NETWORK.IRONSOURCE,
currencyIso4217Code: 'USD',
revenue: 1.23,
additionalParameters: {
customParam1: 'value1',
customParam2: 'value2',
}
};

appsFlyer.logAdRevenue(adRevenueData);
```

Here's how you use `appsFlyer.logAdRevenue` within a React Native app:

1. Prepare the `adRevenueData` object as shown, including any additional parameters you wish to track along with the ad revenue event.
2. Call the `appsFlyer.logAdRevenue` method with the `adRevenueData` object.

By passing all the required fields in `AFAdRevenueData`, you help ensure accurate tracking within the AppsFlyer platform. This enables you to analyze your ad revenue alongside other user acquisition data to optimize your app's overall monetization strategy.

**Note:** The `additionalParameters` object is optional. You can add any additional data you want to log with the ad revenue event in this object. This can be useful for detailed analytics or specific event tracking later on. Make sure that the custom parameters follow the data types and structures specified by AppsFlyer in their documentation.

## Android Only APIs

### setCollectAndroidID
Expand Down
4 changes: 4 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,10 @@

## <a id="breaking-changes"> ❗❗ Breaking changes when updating to v6.x.x❗❗

- From version `6.15.1`, upgraded to targetSDKVersion 34, Java 17, and Gradle 8.7 in [AppsFlyer Android SDK v6.15.1](https://support.appsflyer.com/hc/en-us/articles/115001256006-AppsFlyer-Android-SDK-release-notes).

- From version `6.15.1`, iOS Minimum deployment target is set to 12.0.

- From version `6.3.0`, we use `xcframework` for iOS platform. Then you need to use cocoapods version >= 1.10

- From version `6.2.30`, `logCrossPromotionAndOpenStore` api will register as `af_cross_promotion` instead of `af_app_invites` in your dashboard.<br>
Expand Down
10 changes: 5 additions & 5 deletions android/build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -12,20 +12,20 @@ buildscript {
}

dependencies {
classpath 'com.android.tools.build:gradle:4.0.0'
classpath 'com.android.tools.build:gradle:7.2.2'
}
}


apply plugin: 'com.android.library'

android {
compileSdkVersion safeExtGet('compileSdkVersion', 28)
buildToolsVersion safeExtGet('buildToolsVersion', '29.0.2')
compileSdkVersion safeExtGet('compileSdkVersion', 34)
buildToolsVersion safeExtGet('buildToolsVersion', '34.0.0')

defaultConfig {
minSdkVersion safeExtGet('minSdkVersion', 16)
targetSdkVersion safeExtGet('targetSdkVersion', 28)
targetSdkVersion safeExtGet('targetSdkVersion', 34)
versionCode 1
versionName "1.0"
ndk {
Expand Down Expand Up @@ -54,5 +54,5 @@ repositories {
dependencies {
implementation "com.facebook.react:react-native:${safeExtGet('reactNativeVersion', '+')}"
implementation "com.android.installreferrer:installreferrer:${safeExtGet('installReferrerVersion', '2.1')}"
api "com.appsflyer:af-android-sdk:${safeExtGet('appsflyerVersion', '6.14.0')}"
api "com.appsflyer:af-android-sdk:${safeExtGet('appsflyerVersion', '6.15.1')}"
}
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@

public class RNAppsFlyerConstants {

final static String PLUGIN_VERSION = "6.14.3";
final static String PLUGIN_VERSION = "6.15.1";
final static String NO_DEVKEY_FOUND = "No 'devKey' found or its empty";
final static String UNKNOWN_ERROR = "AF Unknown Error";
final static String SUCCESS = "Success";
Expand Down Expand Up @@ -52,5 +52,11 @@ public class RNAppsFlyerConstants {
final static String VALIDATE_SUCCESS = "In-App Purchase Validation success";
final static String VALIDATE_FAILED = "In-App Purchase Validation failed with error: ";

final static String MONETIZATION_NETWORK = "monetizationNetwork";
final static String CURRENCY_ISO4217_CODE = "currencyIso4217Code";
final static String AF_REVENUE = "revenue";
final static String AF_MEDIATION_NETWORK = "mediationNetwork";
final static String AF_ADDITIONAL_PARAMETERS = "additionalParameters";

}

Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,7 @@
import com.facebook.react.bridge.ReactContextBaseJavaModule;
import com.facebook.react.bridge.ReactMethod;
import com.facebook.react.bridge.ReadableMap;
import com.facebook.react.bridge.ReadableType;
import com.facebook.react.bridge.ReadableArray;
import com.facebook.react.modules.core.DeviceEventManagerModule;

Expand Down Expand Up @@ -362,6 +363,59 @@ public void onError(int i, @NonNull String s) {
}
}

@ReactMethod
public void logAdRevenue(ReadableMap adRevenueDictionary) {
if (adRevenueDictionary == null || !adRevenueDictionary.keySetIterator().hasNextKey()) {
Log.d("AppsFlyer", "adRevenueData is missing, the data is mandatory to use this API.");
return;
}

String monetizationNetwork = adRevenueDictionary.getString(MONETIZATION_NETWORK);
if (monetizationNetwork == null) {
Log.d("AppsFlyer", "monetizationNetwork is missing");
return;
}

String currencyIso4217Code = adRevenueDictionary.getString(CURRENCY_ISO4217_CODE);
if (currencyIso4217Code == null) {
Log.d("AppsFlyer", "currencyIso4217Code is missing");
return;
}

if (!adRevenueDictionary.hasKey(AF_REVENUE) || adRevenueDictionary.getType(AF_REVENUE) != ReadableType.Number) {
Log.d("AppsFlyer", "revenue is missing or not a number");
return;
}
double revenue = adRevenueDictionary.getDouble(AF_REVENUE);

ReadableMap additionalParameters = null;
if (adRevenueDictionary.hasKey(AF_ADDITIONAL_PARAMETERS) && adRevenueDictionary.getType(AF_ADDITIONAL_PARAMETERS) == ReadableType.Map) {
additionalParameters = adRevenueDictionary.getMap(AF_ADDITIONAL_PARAMETERS);
}

String mediationNetworkValue = adRevenueDictionary.getString(AF_MEDIATION_NETWORK);
if (mediationNetworkValue == null || mediationNetworkValue.isEmpty()) {
Log.d("AppsFlyer", "mediationNetwork is missing");
return;
}

MediationNetwork mediationNetwork = MediationNetwork.valueOf(mediationNetworkValue.toUpperCase());
if (mediationNetwork == null) {
Log.d("AppsFlyer", "Invalid mediation network");
return;
}

AFAdRevenueData adRevenueData = new AFAdRevenueData(
monetizationNetwork,
mediationNetwork,
currencyIso4217Code,
revenue
);

// Log the ad revenue to the AppsFlyer SDK
AppsFlyerLib.getInstance().logAdRevenue(adRevenueData, RNUtil.toMap(additionalParameters));
}

@ReactMethod
public void getAppsFlyerUID(Callback callback) {
String appId = AppsFlyerLib.getInstance().getAppsFlyerUID(getReactApplicationContext());
Expand Down
1 change: 1 addition & 0 deletions demos/appsflyer-react-native-app/android/app/build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -182,6 +182,7 @@ dependencies {
implementation fileTree(dir: "libs", include: ["*.jar"])
//noinspection GradleDynamicVersion
implementation "com.facebook.react:react-native:+" // From node_modules
implementation 'org.jetbrains:annotations:16.0.2'

implementation "androidx.swiperefreshlayout:swiperefreshlayout:1.0.0"

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,12 @@
import com.facebook.soloader.SoLoader;
import java.lang.reflect.InvocationTargetException;
import java.util.List;
import android.content.BroadcastReceiver;
import android.content.Intent;
import android.content.IntentFilter;
import android.os.Build;
import org.jetbrains.annotations.Nullable;
import android.content.Context;

public class MainApplication extends Application implements ReactApplication {

Expand Down Expand Up @@ -40,6 +46,15 @@ public ReactNativeHost getReactNativeHost() {
return mReactNativeHost;
}

@Override
public Intent registerReceiver(@Nullable BroadcastReceiver receiver, IntentFilter filter) {
if (Build.VERSION.SDK_INT >= 34 && getApplicationInfo().targetSdkVersion >= 34) {
return super.registerReceiver(receiver, filter, Context.RECEIVER_EXPORTED);
} else {
return super.registerReceiver(receiver, filter);
}
}

@Override
public void onCreate() {
super.onCreate();
Expand Down
9 changes: 5 additions & 4 deletions demos/appsflyer-react-native-app/android/build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -2,18 +2,19 @@

buildscript {
ext {
buildToolsVersion = "30.0.2"
buildToolsVersion = "34.0.0"
minSdkVersion = 21
compileSdkVersion = 32
targetSdkVersion = 32
compileSdkVersion = 34
targetSdkVersion = 34
ndkVersion = "20.1.5948944"
}
repositories {
google()
mavenCentral()
}
dependencies {
classpath("com.android.tools.build:gradle:4.2.1")
//classpath("com.android.tools.build:gradle:4.2.1")
classpath("com.android.tools.build:gradle:7.1.3")
// NOTE: Do not place your application dependencies here; they belong
// in the individual module build.gradle files
}
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
#Sun Sep 01 10:19:20 IDT 2024
distributionBase=GRADLE_USER_HOME
distributionPath=wrapper/dists
distributionUrl=https\://services.gradle.org/distributions/gradle-6.9-all.zip
distributionUrl=https\://services.gradle.org/distributions/gradle-7.4-all.zip
zipStoreBase=GRADLE_USER_HOME
zipStorePath=wrapper/dists
18 changes: 17 additions & 1 deletion demos/appsflyer-react-native-app/components/AppsFlyer.js
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import appsFlyer from 'react-native-appsflyer';
import appsFlyer , {MEDIATION_NETWORK} from 'react-native-appsflyer';
import {Platform} from 'react-native';

// events
Expand Down Expand Up @@ -29,4 +29,20 @@ export function AFInit() {
// Sends in-app events to AppsFlyer servers. name is the events name ('simple event') and the values are a JSON ({info: 'fff', size: 5})
export function AFLogEvent(name, values) {
appsFlyer.logEvent(name, values, null, null);
AFLogAdRevenue();
}

export function AFLogAdRevenue(){
const adRevenueData = {
monetizationNetwork: 'AF-AdNetwork',
mediationNetwork: MEDIATION_NETWORK.IRONSOURCE,
currencyIso4217Code: 'USD',
revenue: 1.23,
additionalParameters : {
customParam1: 'value1',
customParam2: 'value2',
}
};

appsFlyer.logAdRevenue(adRevenueData);
}
29 changes: 28 additions & 1 deletion index.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -125,6 +125,33 @@ declare module "react-native-appsflyer" {
hasConsentForAdsPersonalization?: boolean;
}

//Log Ad Revenue Section
export enum MEDIATION_NETWORK {
IRONSOURCE ,
APPLOVIN_MAX ,
GOOGLE_ADMOB ,
FYBER ,
APPODEAL ,
ADMOST ,
TOPON ,
TRADPLUS,
YANDEX ,
CHARTBOOST ,
UNITY ,
TOPON_PTE ,
CUSTOM_MEDIATION ,
DIRECT_MONETIZATION_NETWORK
}

//Interface representing ad revenue information
export interface AFAdRevenueData {
monetizationNetwork: string;
mediationNetwork: MEDIATION_NETWORK;
currencyIso4217Code: string;
revenue: number;
additionalParameters?: StringMap;
}

const appsFlyer: {
onInstallConversionData(callback: (data: ConversionData) => any): () => void;
onInstallConversionFailure(callback: (data: ConversionData) => any): () => void;
Expand Down Expand Up @@ -164,7 +191,7 @@ declare module "react-native-appsflyer" {
startSdk(): void
enableTCFDataCollection(enabled: boolean): void
setConsentData(consentData: AppsFlyerConsentType): void

logAdRevenue(adRevenueData: AFAdRevenueData) : void
/**
* For iOS Only
* */
Expand Down
24 changes: 24 additions & 0 deletions index.js
Original file line number Diff line number Diff line change
Expand Up @@ -57,6 +57,30 @@ function logEvent(eventName, eventValues, success, error): Promise<string> {

appsFlyer.logEvent = logEvent;


export const MEDIATION_NETWORK = Object.freeze({
IRONSOURCE : "ironsource",
APPLOVIN_MAX : "applovinmax",
GOOGLE_ADMOB : "googleadmob",
FYBER : "fyber",
APPODEAL : "appodeal",
ADMOST : "Admost",
TOPON : "Topon",
TRADPLUS : "Tradplus",
YANDEX : "Yandex",
CHARTBOOST : "chartboost",
UNITY : "Unity",
TOPON_PTE : "toponpte",
CUSTOM_MEDIATION : "customMediation",
DIRECT_MONETIZATION_NETWORK : "directMonetizationNetwork"
});

function logAdRevenue(adRevenueData) {
RNAppsFlyer.logAdRevenue(adRevenueData);
}

appsFlyer.logAdRevenue = logAdRevenue

/**
* Manually record the location of the user
*
Expand Down
Loading

0 comments on commit fb27417

Please sign in to comment.