Handling Attribution & Deep Linking Callbacks | AppsFlyer
37Shares

Chapter 6

Handling Attribution & Deep Linking Callbacks (With Examples!)

The easiest way to put some of this knowledge into practice is to demonstrate how to handle attribution and deep linking using examples.

 

Customer Case #1: Handling Standard Attribution & Routing

In this example, it is assumed that you already have the SDK setup and are properly following all steps to successfully test a deep link. If you are not able to, check out the Testing & QA sections of this guide which elaborately lay out exactly the process to follow on how to QA deep links, as well as some of the common pitfalls. We also provide succinct checklists to follow with your QA team. In this case, assuming you have setup your SDK and now you’re trying to understand how to deep link the user. AppsFlyer provides two different functions for receiving install data in the apps:

                                                            Android: onInstallConversionDataLoaded

                                                            iOS: onConversionDataReceived

The returned conversion data from these functions consists of all the parameters on the original attribution link and some additional server parameters created at the time of click or install. Since the conversion data is reliant on the attribution link, it means that different sources and attribution links may produce different conversion data parameters.

Additionally, there are 3 possible outcomes depending on the type of install:

  1. Non-Organic Installs: Returns the original attribution data of the install (see the examples below).
  2. Organic Install (or re-install): Returns “organic install”
  3. Re-attribution: Returns the re-attribution conversion details.

Example In Action

Below is an example callback you might receive if you called onConversionDataReceived on iOS and received a proper callback. The example is demonstrated with the shopping app Jet, who uses AppsFlyer to deep link from paid ads.

  1. ▿ 0 : 2 elements
  2. – key : click_time
  3. – value : 2018-08-14 02:37:30.798
  4. ▿ 1 : 2 elements
  5. – key : orig_cost
  6. – value : 0.0
  7. ▿ 2 : 2 elements
  8. – key : cost_cents_USD
  9. – value : 0
  10. ▿ 3 : 2 elements
  11. – key : is_first_launch
  12. – value : 0
  13. ▿ 4 : 2 elements
  14. – key : campaign
  15. – value : Test
  16. ▿ 5 : 2 elements
  17. – key : af_click_lookback
  18. – value : 7d
  19. ▿ 6 : 2 elements
  20. – key : af_dp
  21. – value : jet://product/Carbona-Washing-Machine-Cleaner-3-Count/d1909b8fb76240d480df7c983452a913
  22. ▿ 7 : 2 elements
  23. – key : idfa
  24. – value : 00000-0000-0000-0000-0000000000000
  25. ▿ 8 : 2 elements
  26. – key : media_source
  27. – value : Email
  28. ▿ 9 : 2 elements
  29. – key : install_time
  30. – value : 2018-08-14 02:38:40.012
  31. ▿ 10 : 2 elements
  32. – key : af_status

A few things should stand out immediately and it should be clear that you can use this key value structure in the callback of this function to parse information and use it to route the user, and call custom events or experiences. For example, the af_dp value, which stands for AppsFlyer deep link, can be leveraged to immediately route the user to this URI. Similarly, the is_first_launch value can be used to determine whether this is the first time the user launched the app after install, or whether the user already opened the app in the past.

A unique aspect of AppsFlyer is that it has another method for both iOS and Android – onAppOpenAttribution to receive attribution data every time the app opens. The below flow diagram outlines exactly how you could use these two different functions in combination to receive install data when an install occurs, and to receive open data when it does not. From there, you could parse the different keys that you’d like to use for deep linking such as af_dp, af_web_dp, af_ios_url, or af_android_url. A full list of link parameters that would be included in a URL can be found here.

 

Deep linking routing flowReference

This brings us to an important nuance: depending on the SDK and the 3rd Party Attribution Service, you may have different ways of receiving data. AppsFlyer has two distinct methods as illustrated by this chart. Others might have more or less.

The process by which you parse data from the callback and route the user, however, should not change!

Customer Case #2: AppsFlyer & More with a CDP (mParticle)

 

In the case below, we will examine how to handle multiple deep link responses via a Customer Data Platform – in this example, mParticle.

The key to this use case is to first, make sure you understand the response keys from each vendor, then to make sure you prioritize who to handle from a deep linking perspective. Last, but not least, we’ll examine how you can log this attribution callback data to a custom event so that you can trigger a push notification, pop up promotion or other campaigns using your AppsFlyer data!

Example In Action

This app has integrations with two other vendors that provide callbacks to the app. mParticle, a customer data platform that excels in web and mobile data handling, pipes all attribution and deep linking callback data to  a single method.

This single mParticle API wraps both of AppsFlyers callbacks – as well as the callbacks of all other attribution providers –  while the respective AppsFlyer Kit exposes constants to inform you of which callback has been fired.

On both platforms, the iOS/Android kit will register a delegate/callback with the AppsFlyer SDK on initialization and for the lifetime of the app’s process, and will call your completion handler block (iOS), or AttributionListener (Android), whenever there is a new conversion data available.

 

The keys returned in these results will match the result of the AppsFlyer SDK, documented here:

AppsFlyer Callback Response: https://support.appsflyer.com/hc/en-us/articles/207032096-Accessing-AppsFlyer-Attribution-Conversion-Data-from-the-SDK-iOS-Deferred-Deep Linking-

  1. (lldb) po linkInfo
  2. ▿ 1 element
  3. ▿ 0 : 2 elements
  4. ▿ key : AnyHashable(“mParticle-AppsFlyer App Open Result”)
  5. – value : “mParticle-AppsFlyer App Open Result”
  6. ▿ value : 1 element
  7. ▿ 0 : 2 elements
  8. – key : link
  9. – value : https://jet.bttn.io/product/Carbona-Washing-Machine-Cleaner-3-Count/d1909b8fb76240d480df7c983452a913/?btn_ref=fakesrctoken-1111111111111111Shop
    (lldb) po linkInfo
  10. ▿ 1 element
  11. ▿ 0 : 2 elements
  12. ▿ key : AnyHashable(“mParticle-AppsFlyer Attribution Result”)
  13. – value : “mParticle-AppsFlyer Attribution Result”
  14. ▿ value : 11 elements
  15. ▿ 0 : 2 elements
  16. – key : click_time
  17. – value : 2018-08-14 02:37:30.798
  18. ▿ 1 : 2 elements
  19. – key : orig_cost
  20. – value : 0.0
  21. ▿ 2 : 2 elements
  22. – key : cost_cents_USD
  23. – value : 0
  24. ▿ 3 : 2 elements
  25. – key : is_first_launch
  26. – value : 0
  27. ▿ 4 : 2 elements
  28. – key : campaign
  29. – value : Test
  30. ▿ 5 : 2 elements
  31. – key : af_click_lookback
  32. – value : 7d
  33. ▿ 6 : 2 elements
  34. – key : af_dp
  35. – value : jet://product/Carbona-Washing-Machine-Cleaner-3-Count/d1909b8fb76240d480df7c983452a913
  36. ▿ 7 : 2 elements
  37. – key : idfa
  38. – value : 0000000-0000-0000-0000-00000000000
  39. ▿ 8 : 2 elements
  40. – key : media_source
  41. – value : Email
  42. ▿ 9 : 2 elements
  43. – key : install_time
  44. – value : 2018-08-14 02:38:40.012
  45. ▿ 10 : 2 elements
  46. – key : af_status

In this case, we are receiving callback data from the single mParticle deep link API. Just as in the case of handling the AppsFlyer SDK response directly, you should consider which one of these responses you want to handle and how you want to handle it. Here is a framework for structuring your link logic.

  1. If you are receiving callback data from multiple vendors, who takes precedence? Most marketers prioritize the response from a paid-relevant, MMP qualified vendor like AppsFlyer.
  2. Remember to check both install and open responses from AppsFlyer.
  3. If the response is “Organic” you might choose to check the other vendors, especially if that vendor doesn’t have a direct integration with AppsFlyer.

In addition to thinking through your attribution and deep linking logic, you should also log a custom event with the flattened keys and values from this client side attribution event. Below are samples of how to do this directly with AppsFlyer as well as with a CDP like mParticle.

 

AppsFlyer

iOS

– (void) trackEvent:(NSString *)eventName withValues:(NSDictionary*)values

The eventName could be as simple as “Attribution” or “Attribution Data” and the values should be all or some of the values from the callback response listed above.

Android

public static void trackEvent(Context context, String eventName, Map eventValues)

The eventName could be as simple as “Attribution” or “Attribution Data” and the eventValues should be all or some of the values from the callback response listed above.

Documentation:

https://support.appsflyer.com/hc/en-us/articles/115005544169-AppsFlyer-Rich-In-App-Events-Android-and-iOS#Introduction

mParticle

iOS

MPEvent *event = [[MPEvent alloc] initWithName:@”Attribution Data”
                                         type:MPEventTypeTransaction];
event.info = @{@”key”:@”value”};
[[MParticle sharedInstance] logEvent:event];

Android

Map<String, String> eventInfo = new HashMap<String, String>();
eventInfo.put(“key”, “value”);
MPEvent event = new MPEvent.Builder(“Attribution Data”, EventType.Navigation)
   .info(eventInfo)
   .build();
MParticle.getInstance().logEvent(event);

Documentation:

iOS: https://docs.mparticle.com/developers/sdk/ios/event-tracking/#capture-a-custom-event

Android: https://docs.mparticle.com/developers/sdk/android/event-tracking/#capture-a-custom-event

About the Authors