一、简介
AppsFlyer 可以帮助客户直接在客户端 SDK 层级实时访问用户的归因数据。从而实现,在用户在首次打开App时,能够将用户重定向至指定页面或展示指定内容。这种功能场景通常被称为“延迟”深度链接:
该功能在 Web端很常见,但在移动应用生态系统中要实现这一点则颇为挑战。当然,AppsFlyer在不同设备平台都可以轻松为您提供相应的解决方案。
延迟深度链接用于新增用户。要为现有用户提供深度链接,您的应用必须支持URI方案、APP Links(Android)或Universal Links(iOS)。
延迟深度链接可以深度链接新用户,并在他们安装应用后为其展示自定义内容。这不同于常规的深度链接,在常规深度链接中,应用必须已经安装在用户设备上。
要用OneLink实现延迟深度链接,开发人员需要有访问AppsFlyer控制面板的权限。
延迟深度链接的设置与深度链接相同。唯一的区别是,您需要在应用中实现其他逻辑,以便在用户安装和启动应用后将他们深度链接到自定义内容。
示例
试想一个用户在搜索“纽约酒店”后点击了 HotelTonight 的 Google Adwords 广告。该用户首先被转至 Google Play/App-Store 去下载应用,然后在首次打开应用时,用户会直接看到纽约的酒店页面。通过获取 AppsFlyer 提供的归因数据,应用会收到准确的营销活动以及关键字,推动用户转化/安装。
除了增强用户体验以及提高转化率以外,此功能还可以实现基于场景的复杂营销活动,比如为安装和使用应用的用户提供优惠/奖励。例如,用安装应用即可获得50美金订购券广告系列取代点击安装的广告系列。这种营销活动不仅可以提高点击至安装的转化率,还可以提高付费用户的转化率。这些营销活动可以将投资回报提高 2-5 倍!
AppsFlyer的SDK负责启用从应用内部访问归因数据。在首次打开应用时,获取 AppsFlyer SDK 提供的归因数据可能需要几秒钟。之后每次打开应用,这个过程是即时的,因为归因数据已经存储在设备上。
注意
- 根据 Facebook 的隐私政策,只有接受 Facebook 的服务条款之后,AppsFlyer(或任何其他第三方移动监测合作伙伴)才可以提供来自Facebook安装的用户层级归因数据。更多信息, 请点击此处。如果您选择不接受服务条款,Facebook Mobile Ads 的安装会被归类为 ‘Organic’,您也无法收到 Facebook 安装的用户级数据。 获取归因数据以执行延迟深度链接适用于安装后首次打开应用的用户。若要为已经安装应用的用户执行深度链接,请参阅此处。
- 转化数据不是用于在后端存储用户原始数据的理想API。 点击此处了解最适合您的数据接口。
二、SDK 集成
onConversionDataSuccess
会包含 激活的归因数据. 您可以使用该函数执行:
- 延迟深度链接: 首次进入app的新用户,跳转至指定页面
- 在用户使用app的整个周期内针对不同的事件获取激活归因数据
示例
用户在Facebook上看到一双小红鞋的广告后很喜欢,决定 下载并激活您的应用 。在这个场景下,如果想将用户在首次打开app时,直接定向到app中的小红鞋商品页面,请使用onConversionDataSuccess
要访问 AppsFlyer 从 Android SDK 中获取的转化数据,执行 ConversionDataListener:
注意: 从SDK 5.0版本开始,获取归因转化数据的方法名称更改为 onConversionDataSuccess
。如果使用的SDK版本低于5.0.0,该方法的名称为onInstallConversionDataLoaded
。我们建议您升级到SDK 5.0.0。要了解更多信息,请点击这里 。
public interface AppsFlyerConversionListener { void onConversionDataSuccess(Map<String,String> conversionData); void onConversionDataFail(String errorMessage); }
代码示例
以下分别是用于 Android 和 iOS 的代码示例。
JAVA 代码
@Override public void onCreate(){ super.onCreate(); /** Set Up Conversion Listener to get attribution data **/ AppsFlyerConversionListener conversionListener = new AppsFlyerConversionListener() { /* Returns the attribution data. Note - the same conversion data is returned every time per install */ @Override public void onConversionDataSuccess(Map<String, String> conversionData) { for (String attrName : conversionData.keySet()) { Log.d("LOG_TAG", "attribute: " + attrName + " = " + conversionData.get(attrName)); } setInstallData(conversionData); } @Override public void onConversionDataFail(String errorMessage) { Log.d("LOG_TAG", "error getting conversion data: " + errorMessage); } /* Called only when a Deep Link is opened */ @Override public void onAppOpenAttribution(Map<String, String> conversionData) { for (String attrName : conversionData.keySet()) { Log.d("LOG_TAG", "attribute: " + attrName + " = " + conversionData.get(attrName)); } } @Override public void onAttributionFailure(String errorMessage) { Log.d("LOG_TAG", "error onAttributionFailure : " + errorMessage); } }; /* This API enables AppsFlyer to detect installations, sessions, and updates. */ AppsFlyerLib.getInstance().init(AF_DEV_KEY, conversionListener, getApplicationContext()); AppsFlyerLib.getInstance().startTracking(this);} 如果不需要转化数据,只需在 init方法中传递 null : AppsFlyerLib.getInstance().init(AF_DEV_KEY, null, this);
IOS 代码
AppDelegate.h #import "AppsFlyerTracker.h" @interface AppDelegate : UIResponder<UIApplicationDelegate, AppsFlyerTrackerDelegate> { ... } AppDelegate.m - (BOOL)application:(UIApplication ?*)application didFinishLaunchingWithOptions:(NSDictionary*?)launchOptions { [AppsFlyerTracker sharedTracker].appsFlyerDevKey = @"[MY_DEV_KEY]"; [AppsFlyerTracker sharedTracker].appleAppID = @"123456789"; // Load conversion and deep link data [AppsFlyerTracker sharedTracker].delegate = self; return YES; } -(void)applicationDidBecomeActive:(UIApplication *)application { [[AppsFlyerTracker sharedTracker] trackAppLaunch]; } -(void)onConversionDataSuccess:(NSDictionary*) installData { id status = [installData objectForKey:@"af_status"]; if([status isEqualToString:@"Non-organic"]) { id sourceID = [installData objectForKey:@"media_source"]; id campaign = [installData objectForKey:@"campaign"]; NSLog(@"This is a none organic install. Media source: %@ Campaign: %@",sourceID,campaign); } else if([status isEqualToString:@"Organic"]) { NSLog(@"This is an organic install."); } } -(void)onConversionDataFail:(NSError *) error { NSLog(@"%@",error); }
首次启动
应用首次启动时,归因数据会从 AppsFlyer 的服务器实时发送到新激活的app。然后,SDK 会将该数据保存到应用的缓存中(Shared Preference 或 userDefault)。
针对后续的app启动,AppsFlyer 的 SDK 会直接从缓存中读取归因数据,而不会再向 AppsFlyer 服务器发起请求。因此,无论是否首次打开,归因数据始终返回相同的值。
为了帮助开发者仅在首次启动时才使用转化数据,AppsFlyer 在转化数据响应中添加了 is_first_launch
参数。is_first_launch
在应用首次启动时为 true (Objective-C中为 YES ),之后为 false (Objective-C中为 NO )。该参数在 Android(SDK 4.8.4 及更高版本)和 iOS SDK(SDK 4.8.2 及更高版本)中均可使用。
三、返回结果
归因返回结果中的参数
返回的转化数据包含原始归因链接中的所有参数以及在点击或安装时创建的其他一些服务器参数。
由于转化数据依赖于归因链接,因而不同的来源和归因链接可能产生不同的转化数据参数。
每次app启动时,都会调用以下函数: onConversionDataSuccess
。
注意: 从SDK 5.0版本开始,获取归因转化数据的方法名称更改为 onConversionDataSuccess
。如果您使用的SDK版本低于5.0.0,则该方法的名称在Android中为onInstallConversionDataLoaded
,在iOS中为onConversionDataReceived
。我们建议您升级到SDK 5.0.0。要了解更多信息,请点击这里 。
视转化类型而定,可能有 3 种结果:
- 非自然激活
返回最初的归因数据(见以下示例)。 - 自然激活
(或re-install)返回“organic install” - 再归因(reattribution)
返回再归因的归因数据。
参数说明
参数名称 | 说明 | 示例值 | 媒体渠道 |
af_status | 归因类型有效值:自然非自然 | 非自然 | 全部 |
af_message | 任意文本 | 自然激活/错误消息 | 全部 |
media_source | 媒体渠道名称。这是 AF 归因链接的“pid’”参数 | inmobi_inttapjoy_intFacebook 注意代理商带来的激活,媒体渠道信息默认被隐藏,值为“null”。 | 全部 |
campaign | 广告系列名称(AppsFlyer 归因链接的 ‘C’ 参数或 Facebook 的广告系列名称) | Ad1/camp123 | 全部 |
clickid | 点击 ID 或交易 ID | 123456/xsfd234 | 全部 |
af_siteid | 子渠道 ID(通常用于优化) | 子渠道1 | 全部 |
af_sub1 | 额外参数 | 一些参数 | 全部 |
af_sub2 | 额外参数 | 全部 | |
af_sub3 | 额外参数 | 全部 | |
af_sub4 | 额外参数 | 全部 | |
af_sub5 | 额外参数 | 全部 | |
af_keywords | 在搜索广告系列中用于搜索的关键字。例如:Google Search 广告系列 | 全部 | |
click_time | 点击日期&时间(毫秒) (UTC) | 2014-01-08 00:07:53.233 UTC | 全部 |
install_time | 归因转换日期&时间(毫秒)(UTC) | 2014-01-08 00:12:51.701 UTC | 全部 |
agency | 代理或 PMD带来的激活 | nanigans | 全部 |
is_first_launch | 首次启动时为 True,之后为 False | true | 全部 |
is_fb | 标记表明此安装归因于 Facebook。值:true/false | true | |
ad_id | Facebook 的唯一广告标识号码 | 6012740800279 | |
campaign_id | 广告系列活动ID | 6012700005123 | 全部 |
广告集 | Facebook 的广告组名称 | US - 18+ | |
adset_id | Facebook 广告组 ID | 6099800005123 | |
orig_cost | 安装的成本(可以是任何货币) | 1.5 | 全部 |
cost_cents_USD | 货币换算后,以美分表示的成本值 | 150(美分) | 全部 |
retargeting_conversion_type | 再营销转化类型 | 再归因(re-attribution) / 再互动(re-engagement) | 全部 |
对于归因链接集成(非自归因平台),归因链接中出现的所有URL参数都会在GCD中返回。
四、示例
1、常规 AppsFlyer 归因链接激活示例
ANDROID 平台
http://app.appsflyer.com/com.greatapp?pid=network_int&c=network_TH&af_ad=ad_name&af_sub1=102619 &af_sub2=network_TH_G001_Android&af_dp=app%3A%2F%2Fhome&af_prt=expertagency &af_siteid=1777215&af_sub_siteid=1702&freehand-param=somevalue&tag={TAGID} &clickid={CLICKID}&af_click_lookback=1d
返回结果如下:
{ "media_source":"network_int", "campaign":"network_TH", "adset":null, "clickid":"fb7f51d42-2621-93bd-e9a1b24f1acfab7b76e5104706104f4d6*******", "adgroup":null, "campaign_id":null, "af_cost_currency":"USD", "af_status":"Non-organic", "af_sub_siteid":"1702", "agency":"expertagency", "af_sub3":null, "af_cost_model":"CPI", "af_siteid":"1777215", "af_ad" = "ad_name", "af_dp":"app://home", "adset_id":null, "click_time":"2017-07-19 08:30:31.890", "cost_cents_USD":"150", "iscache":true, "is_first_launch":true, "af_cpi":null, "af_sub1":"102619", "af_cost_value":"1.5", "af_click_lookback":"1d", "af_sub4":null, "site_id":"1777215", "adgroup_id":null, "tag":"8d55089f-31b6-407b-9266-*********", "orig_cost":"1.5", "af_prt":"expertagency", "af_sub5":null, "install_time":"2017-07-19 08:30:35.461", "af_sub2":"network_TH_G001_Android", "freehand-param":"somevalue" }
IOS 平台
http://app.appsflyer.com/id123456789?pid=network_int&c=network_KR&af_ad=ad_name&af_sub1=CD48704_ &af_sub2=network_KR_G001_iOS&af_dp=app%3A%2F%2Fhome&af_prt=expertagency& af_siteid=1777236&af_sub_siteid=1702&freehand-param=somevalue&tag={TAGID} &clickid={CLICKID}&af_click_lookback=1d { "media_source":"network_int", "campaign":"network_KR", "adset":null, "adgroup":null, "campaign_id":null, "af_cost_currency":"USD", "af_status":"Non-organic", "agency":"expertagency", "af_sub3":null, "af_cost_model":"CPI", "af_siteid":"1777236", "af_ad" = "ad_name", "af_dp":"app://home", "adset_id":null, "click_time":"2017-07-18 14:48:42.896", "cost_cents_USD":"0", "iscache":true, "is_first_launch":1, "af_cpi":null, "af_sub1":"CD48704_", "af_click_lookback":"1d", "af_sub4":null, "site_id":"1777236", "adgroup_id":null, "tag":"43fafd60-76ad-4a8f-9d1d-************", "orig_cost":"0.0", "af_prt":"expertagency", "af_sub5":null, "install_time":"2017-07-18 15:09:06.014", "af_sub2":"network_KR_G001_iOS", "clickID":"3gggBgAw2Bvxa8gR56ZA8Y3qjUy2gPkFgP6rA96s4e*******", "freehand-param":"somevalue" }
2、Facebook 激活示例
在 Facebook 广告系列中定义的深度链接参数在 Facebook 以外不可用。这包括af_dp参数,该参数中含有应用的scheme路径。因此,要执行延迟深度链接,必须针对 Facebook 广告系列采用其他逻辑。将 Facebook 数据用于 getConversionData
响应,例如,广告系列、Adset、Adgroup 等,有计划地对用户进行重定向。
来自Facebook 的激活客户端返回结果如下:
Android 平台
{ "adset":"T:DAT-Desktop_O:All_L:AR-AE_A:All_R:1-30 Day", "adgroup":"T:DAT-Desktop_O:All_L:AR-AE_A:All_R:1-30 Day", "campaign_id":"6068535534218", "af_status":"Non-organic", "agency":null, "af_sub3":null, "af_siteid":null, "adset_id":"6073532011618", "is_fb":true, "is_first_launch":true, "click_time":"2017-07-18 12:55:05", "iscache":false, "ad_id":"6074245540018", "af_sub1":null, "campaign":"T:DAT_L:AR-AE", "is_paid":true, "af_sub4":null, "adgroup_id":"6073532011418", "is_mobile_data_terms_signed":true, "af_channel":"Facebook", "af_sub5":null, "media_source":"Facebook Ads", "install_time":"2017-07-19 08:06:56.189", "af_sub2":null }
IOS 平台
{ "media_source":"Facebook Ads", "campaign":"T:App Install_A:ALL", "adset":"T:App Install_M:iOS_O:ALL_L:DE-DE_A:ALL", "adgroup":"T:App Install_M:iOS_O:ALL_L:DE-DE_A:ALL_Banne", "campaign_id":"6074766693717", "af_status":"Non-organic", "agency":null, "af_sub3":null, "af_siteid":null, "adset_id":"6074767207317", "is_fb":true, "is_first_launch":true, "click_time":"2017-07-17 16:23:18", "iscache":false, "ad_id":"6078076656717", "af_sub1":null, "is_paid":true, "af_sub4":null, "adgroup_id":"6074821181517", "is_mobile_data_terms_signed":true, "af_channel":"Facebook", "af_sub5":null, "install_time":"2017-07-18 15:10:50.190", "af_sub2":null }