diff --git a/CHANGELOG.md b/CHANGELOG.md new file mode 100644 index 0000000..49b1a9e --- /dev/null +++ b/CHANGELOG.md @@ -0,0 +1,17 @@ +# Changelog + +All notable changes to this project will be documented in this file. See [standard-version](https://github.com/conventional-changelog/standard-version) for commit guidelines. + +## [2.3.0](https://github.com/rudderlabs/rudder-integration-appsflyer-android/compare/v0.1.1...v2.3.0) (2023-05-02) + + +### Features + +* add ci/cd ([#10](https://github.com/rudderlabs/rudder-integration-appsflyer-android/issues/10)) ([c2fe02f](https://github.com/rudderlabs/rudder-integration-appsflyer-android/commit/c2fe02fabcce06d2872768cbdb102a7f7fb31984)) +* updated to the latest version of appsflyer android sdk 6.9.4 ([dd36221](https://github.com/rudderlabs/rudder-integration-appsflyer-android/commit/dd36221eabb8e278eaa276b15b74186f40895745)) +* upgraded to the latest version of appsflyer sdk and added support for new events ([f5259f0](https://github.com/rudderlabs/rudder-integration-appsflyer-android/commit/f5259f0f17618ba9ea51ef1499240736d69d64ae)) + + +### Bug Fixes + +* fixed issue with event name mapping ([b3c7c4f](https://github.com/rudderlabs/rudder-integration-appsflyer-android/commit/b3c7c4f679252f7fff5aea9e73969b30867e2618)) diff --git a/appsflyer/build.gradle b/appsflyer/build.gradle index 09c0aa5..7980993 100644 --- a/appsflyer/build.gradle +++ b/appsflyer/build.gradle @@ -25,11 +25,12 @@ android { dependencies { implementation fileTree(dir: 'libs', include: ['*.jar']) + // rudder core sdk - implementation 'com.rudderstack.android.sdk:core:[1.8.0,)' + compileOnly 'com.rudderstack.android.sdk:core:[1.12, 2.0)' // appsflyer dependencies - implementation 'com.appsflyer:af-android-sdk:6.9.4' + implementation 'com.appsflyer:af-android-sdk:[6.10.1, 7.0)' implementation 'com.android.installreferrer:installreferrer:2.2' } diff --git a/appsflyer/src/main/java/com/rudderstack/android/integrations/appsflyer/AppsFlyerIntegrationFactory.java b/appsflyer/src/main/java/com/rudderstack/android/integrations/appsflyer/AppsFlyerIntegrationFactory.java index 3bd1c76..d17f9c0 100644 --- a/appsflyer/src/main/java/com/rudderstack/android/integrations/appsflyer/AppsFlyerIntegrationFactory.java +++ b/appsflyer/src/main/java/com/rudderstack/android/integrations/appsflyer/AppsFlyerIntegrationFactory.java @@ -19,6 +19,7 @@ import org.json.JSONObject; import java.util.ArrayList; +import java.util.Arrays; import java.util.Collection; import java.util.HashMap; import java.util.List; @@ -27,8 +28,13 @@ public class AppsFlyerIntegrationFactory extends RudderIntegration { private static final String APPSFLYER_KEY = "AppsFlyer"; private static final String FIRST_PURCHASE = "first_purchase"; + public static final String CREATIVE = "creative"; private Boolean isNewScreenEnabled = false; + static final List TRACK_RESERVED_KEYWORDS = Arrays.asList(ECommerceParamNames.QUERY, ECommerceParamNames.PRICE, ECommerceParamNames.PRODUCT_ID, ECommerceParamNames.CATEGORY, + ECommerceParamNames.CURRENCY, ECommerceParamNames.PRODUCTS, ECommerceParamNames.QUANTITY, ECommerceParamNames.TOTAL, + ECommerceParamNames.REVENUE, ECommerceParamNames.ORDER_ID, ECommerceParamNames.SHARE_MESSAGE, CREATIVE, ECommerceParamNames.RATING); + public static RudderIntegration.Factory FACTORY = new Factory() { @Override public RudderIntegration create(Object settings, RudderClient client, RudderConfig config) { @@ -52,7 +58,7 @@ private AppsFlyerIntegrationFactory(Object config, RudderConfig rudderConfig) { private void processEvents(RudderMessage message) { String eventType = message.getType(); - String afEventName; + String afEventName = null; Map afEventProps = new HashMap<>(); if (eventType != null) { switch (eventType) { @@ -64,7 +70,7 @@ private void processEvents(RudderMessage message) { switch (eventName) { case ECommerceEvents.PRODUCTS_SEARCHED: if (property.containsKey(ECommerceParamNames.QUERY)) { - afEventProps.put(AFInAppEventParameterName.SEARCH_STRING, property.get("query")); + afEventProps.put(AFInAppEventParameterName.SEARCH_STRING, property.get(ECommerceParamNames.QUERY)); } afEventName = AFInAppEventType.SEARCH; break; @@ -100,7 +106,7 @@ private void processEvents(RudderMessage message) { afEventProps.put(AFInAppEventParameterName.CONTENT_LIST, products.toArray()); } } - afEventName = "af_list_view"; + afEventName = AFInAppEventType.LIST_VIEW; break; case ECommerceEvents.PRODUCT_ADDED_TO_WISH_LIST: if (property.containsKey(ECommerceParamNames.PRICE)) @@ -141,7 +147,7 @@ private void processEvents(RudderMessage message) { afEventName = AFInAppEventType.PURCHASE; break; case FIRST_PURCHASE: - makeOrderCompletedEvent(property,afEventProps); + makeOrderCompletedEvent(property, afEventProps); afEventName = FIRST_PURCHASE; break; case ECommerceEvents.PRODUCT_REMOVED: @@ -151,12 +157,43 @@ private void processEvents(RudderMessage message) { afEventProps.put(AFInAppEventParameterName.CONTENT_TYPE, property.get(ECommerceParamNames.CATEGORY)); afEventName = "remove_from_cart"; break; + case ECommerceEvents.PROMOTION_VIEWED: + if (property.containsKey(CREATIVE)) + afEventProps.put(AFInAppEventParameterName.AD_REVENUE_AD_TYPE, property.get(CREATIVE)); + if (property.containsKey(ECommerceParamNames.CURRENCY)) + afEventProps.put(AFInAppEventParameterName.CURRENCY, property.get(ECommerceParamNames.CURRENCY)); + afEventName = AFInAppEventType.AD_VIEW; + break; + case ECommerceEvents.PROMOTION_CLICKED: + if (property.containsKey(CREATIVE)) + afEventProps.put(AFInAppEventParameterName.AD_REVENUE_AD_TYPE, property.get(CREATIVE)); + if (property.containsKey(ECommerceParamNames.CURRENCY)) + afEventProps.put(AFInAppEventParameterName.CURRENCY, property.get(ECommerceParamNames.CURRENCY)); + afEventName = AFInAppEventType.AD_CLICK; + break; + case ECommerceEvents.PAYMENT_INFO_ENTERED: + afEventName = AFInAppEventType.ADD_PAYMENT_INFO; + break; + case ECommerceEvents.PRODUCT_SHARED: + case ECommerceEvents.CART_SHARED: + if (property.containsKey(ECommerceParamNames.SHARE_MESSAGE)) + afEventProps.put(AFInAppEventParameterName.DESCRIPTION, property.get(ECommerceParamNames.SHARE_MESSAGE)); + afEventName = AFInAppEventType.SHARE; + break; + case ECommerceEvents.PRODUCT_REVIEWED: + if (property.containsKey(ECommerceParamNames.PRODUCT_ID)) + afEventProps.put(AFInAppEventParameterName.CONTENT_ID, property.get(ECommerceParamNames.PRODUCT_ID)); + if (property.containsKey(ECommerceParamNames.RATING)) + afEventProps.put(AFInAppEventParameterName.RATING_VALUE, property.get(ECommerceParamNames.RATING)); + afEventName = AFInAppEventType.RATE; + break; default: afEventName = eventName.toLowerCase().replace(" ", "_"); } } else { afEventName = eventName.toLowerCase().replace(" ", "_"); } + attachAllCustomProperties(afEventProps, property); AppsFlyerLib.getInstance().logEvent(RudderClient.getApplication(), afEventName, afEventProps); } break; @@ -191,6 +228,19 @@ private void processEvents(RudderMessage message) { } } + private void attachAllCustomProperties(Map afEventProps, Map properties) { + if (properties == null || properties.size() == 0) { + return; + } + for (String key : properties.keySet()) { + Object value = properties.get(key); + if (TRACK_RESERVED_KEYWORDS.contains(key) || TextUtils.isEmpty(key)) { + continue; + } + afEventProps.put(key, value); + } + } + private void makeOrderCompletedEvent(Map eventProperties, Map afEventProps) { if (eventProperties.containsKey(ECommerceParamNames.TOTAL)) afEventProps.put(AFInAppEventParameterName.PRICE, eventProperties.get(ECommerceParamNames.TOTAL)); diff --git a/gradle.properties b/gradle.properties index 8695bab..1906614 100644 --- a/gradle.properties +++ b/gradle.properties @@ -1,14 +1,14 @@ -VERSION_NAME=2.2.0 +VERSION_NAME=2.3.0 android.enableJetifier=true -org.gradle.jvmargs=-Xmx1536m android.useAndroidX=true +org.gradle.jvmargs=-Xmx1536m POM_NAME=Rudder-Integration-AppsFlyer-Android POM_DESCRIPTION=RudderStack\'s Native SDK Integration support for AppsFlyer. POM_LICENCE_URL=http://opensource.org/licenses/MIT POM_DEVELOPER_NAME=Rudderstack, Inc. kotlin.code.style=official -VERSION_CODE=1 +VERSION_CODE=2 POM_LICENCE_DIST=repo GROUP=com.rudderstack.android.integration POM_DEVELOPER_ID=Rudderstack @@ -16,4 +16,4 @@ POM_LICENCE_NAME=The MIT License (MIT) POM_URL=https://github.com/rudderlabs/rudder-integration-appsflyer-android POM_SCM_URL=https://github.com/rudderlabs/rudder-integration-appsflyer-android/tree/master POM_SCM_CONNECTION=scm:git:git://github.com/rudderlabs/rudder-integration-appsflyer-android.git -POM_SCM_DEV_CONNECTION=scm:git:git://github.com:rudderlabs/rudder-integration-appsflyer-android.git +POM_SCM_DEV_CONNECTION=scm:git:git://github.com:rudderlabs/rudder-integration-appsflyer-android.git \ No newline at end of file diff --git a/package.json b/package.json index 7c67dcb..90913d1 100644 --- a/package.json +++ b/package.json @@ -1 +1,6 @@ -{"version":"2.2.0","dependencies":{"properties-reader":"^2.2.0"}} \ No newline at end of file +{ + "version": "2.3.0", + "dependencies": { + "properties-reader": "^2.2.0" + } +} diff --git a/sample-kotlin/.gitignore b/sample-kotlin/.gitignore index 796b96d..4f1e170 100644 --- a/sample-kotlin/.gitignore +++ b/sample-kotlin/.gitignore @@ -1 +1,2 @@ /build +local.properties \ No newline at end of file diff --git a/sample-kotlin/build.gradle b/sample-kotlin/build.gradle index 9db11ff..aed2bfb 100644 --- a/sample-kotlin/build.gradle +++ b/sample-kotlin/build.gradle @@ -12,15 +12,24 @@ apply plugin: 'com.android.application' apply plugin: 'kotlin-android' apply plugin: 'kotlin-android-extensions' +Properties properties = new Properties() +File localPropertiesFile = new File(project.projectDir, "local.properties") +if (localPropertiesFile.exists()) { + properties.load(localPropertiesFile.newDataInputStream()) +} + android { compileSdkVersion 33 defaultConfig { - applicationId "com.rudderstack.test.android" + applicationId "com.desu.venkat.android" minSdkVersion 19 targetSdkVersion 33 versionCode 1 versionName "1.0" testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner" + buildConfigField("String", "DATA_PLANE_URL", properties.getProperty('dataplaneUrl', '\"https://hosted.rudderlabs.com\"')) + buildConfigField("String", "CONTROL_PLANE_URL", properties.getProperty('controlplaneUrl', '\"https://api.rudderstack.com\"')) + buildConfigField("String", "WRITE_KEY", properties.getProperty('writeKey', '\"\"')) } buildTypes { release { @@ -43,7 +52,7 @@ dependencies { implementation 'com.rudderstack.android.sdk:core:1.+' implementation project(':appsflyer') - implementation 'com.appsflyer:af-android-sdk:6.2.0' + implementation 'com.appsflyer:af-android-sdk:6.10.2' implementation 'com.android.installreferrer:installreferrer:2.2' implementation 'com.google.code.gson:gson:2.8.6' diff --git a/sample-kotlin/src/main/java/com/rudderlabs/android/sample/kotlin/MainActivity.kt b/sample-kotlin/src/main/java/com/rudderlabs/android/sample/kotlin/MainActivity.kt index e09a237..032f42a 100644 --- a/sample-kotlin/src/main/java/com/rudderlabs/android/sample/kotlin/MainActivity.kt +++ b/sample-kotlin/src/main/java/com/rudderlabs/android/sample/kotlin/MainActivity.kt @@ -170,5 +170,44 @@ class MainActivity : AppCompatActivity() { productSharedEvent.event(), productSharedEvent.properties() ) + + + val cartSharedEvent = CartSharedEvent() + .withCart(cart) + .withSocialChannel("facebook") + .withShareMessage("some message") + .withRecipient("friend@gmail.com") + MainApplication.rudderClient.track( + cartSharedEvent.event(), + cartSharedEvent.properties() + ); + + val promotionViewedEvent = PromotionViewedEvent() + .withPromotion( + ECommercePromotion( + "firstPromotion", + "mail", + "launch", + "head" + ) + ); + MainApplication.rudderClient.track( + promotionViewedEvent.event(), + promotionViewedEvent.properties() + ) + + val promotionClickedEvent = PromotionClickedEvent() + .withPromotion( + ECommercePromotion( + "firstPromotion", + "mail", + "launch", + "head" + ) + ) + MainApplication.rudderClient.track( + promotionClickedEvent.event(), + promotionClickedEvent.properties() + ) } } diff --git a/sample-kotlin/src/main/java/com/rudderlabs/android/sample/kotlin/MainApplication.kt b/sample-kotlin/src/main/java/com/rudderlabs/android/sample/kotlin/MainApplication.kt index 4b7efb8..c6668f9 100644 --- a/sample-kotlin/src/main/java/com/rudderlabs/android/sample/kotlin/MainApplication.kt +++ b/sample-kotlin/src/main/java/com/rudderlabs/android/sample/kotlin/MainApplication.kt @@ -25,9 +25,9 @@ class MainApplication : Application() { AppsFlyerLib.getInstance().start(this); rudderClient = RudderClient.getInstance( this, - WRITE_KEY, + BuildConfig.WRITE_KEY, RudderConfig.Builder() - .withDataPlaneUrl(DATA_PLANE_URL) + .withDataPlaneUrl(BuildConfig.DATA_PLANE_URL) .withFactory(AppsFlyerIntegrationFactory.FACTORY) .withLogLevel(RudderLogger.RudderLogLevel.DEBUG) .build()