概要:通过Web SDK将AppsFlyer对接到您的网站,记录和衡量访问、事件、转化以及收入。
Web SDK用户与对接指南
- Web SDK JavaScript标签:
- PBA(People-Based Attribution,基于用户的归因)解决方案的一部分,用于分析跨平台的用户路径。
- 可将网站上的访问和行为上报至AppsFlyer平台。
- 是一个无需编程的网站插件模块,与访客的操作系统和浏览器无关。
- 大小:40-60KB。
- 建议在移动应用中部署AppsFlyer移动SDK,并在网站端部署Web SDK,从而对用户行为进行统一记录与映射。
- 发生在网站之外的事件,可通过Web S2S event API(Web S2S)进行记录。
选择代码片段
选择与您的集成类型和安全要求相匹配的片段。有两个选项可供选择:
重要提示!
如果您正在从标准Web SDK过渡到高级SDK验证,请用新的片段替换现有的片段。请勿在现有片段上添加新的片段。
标准Web SDK
使用此片段来部署标准Web SDK集成。将其粘贴在您希望加载SDK的所有页面的标签的顶部附近。
没有智能横幅
<script>
// Queue — buffers AF() calls until the SDK is ready
window.AppsFlyerSdkObject = "AF";
window.AF = window.AF || function() {
(window.AF.q = window.AF.q || []).push([Date.now()].concat(Array.prototype.slice.call(arguments)));
};
window.AF.id = window.AF.id || { pba: { webAppId: "WEB_DEV_KEY" } };
window.AF.plugins = {};
// Inject SDK
var o = document.createElement("script"),
p = document.getElementsByTagName("script")[0];
o.async = 1;
o.src = "https://websdk.appsflyersdk.com?" + "st=pba&af_id=WEB_DEV_KEY";
p.parentNode.insertBefore(o, p);
</script>(智能横幅助力)
<script>
// Queue — buffers AF() calls until the SDK is ready
window.AppsFlyerSdkObject = "AF";
window.AF = window.AF || function() {
(window.AF.q = window.AF.q || []).push([Date.now()].concat(Array.prototype.slice.call(arguments)));
};
window.AF.id = window.AF.id || { pba: { webAppId: "WEB_DEV_KEY" }, banners: { key: "YOUR_BANNER_KEY" } };
window.AF.plugins = {};
// Inject SDK
var o = document.createElement("script"),
p = document.getElementsByTagName("script")[0];
o.async = 1;
o.src = "https://websdk.appsflyersdk.com?" + "st=pba,banners&af_id=WEB_DEV_KEY";
p.parentNode.insertBefore(o, p);
AF('banners', 'showBanner');
</script>高级SDK验证
高级SDK验证为Web SDK增加供应链保护。它确保在用户浏览器中运行的代码与AppsFlyer发布的代码完全相同。SDK源代码本身与标准集成相同;只有交付和验证机制不同。
高级SDK验证:
- 为CDN攻击、DNS劫持和中间人攻击增加额外的安全层。
- 大约增加250毫秒的SDK加载时间。
高级SDK验证是可选的。标准集成仍然完全支持,并且是第三方分析像素的市场标准。高级SDK验证提供了超出标准的额外保护层。
如果您的网站使用nonce强制实施内容安全策略(CSP),请参见内容安全策略(CSP)中的管理隐私部分,以获取此代码片段的nonce扩展变体。
没有智能横幅
<script>
// Queue — buffers AF() calls until the SDK is ready
window.AppsFlyerSdkObject = "AF";
window.AF = window.AF || function() {
(window.AF.q = window.AF.q || []).push([Date.now()].concat(Array.prototype.slice.call(arguments)));
};
window.AF.id = window.AF.id || { pba: { webAppId: "WEB_DEV_KEY" } };
window.AF.plugins = {};
// Manifest loader config
window.AF_LOADER_CONFIG = {
baseUrl: "https://websdk.appsflyersdk.com",
plugins: ["pba"]
};
// Inject manifest loader
var loaderScript = document.createElement("script");
loaderScript.src = "https://websdk.appsflyersdk.com/manifestLoader.v1.js";
loaderScript.integrity = "sha384-Uncl2YwvjFpFz0PwEfl3bL/0JsOQcDFEpwXHzcN0MBavn9vvFEx5pZxADTq8h+CV";
loaderScript.crossOrigin = "anonymous";
loaderScript.async = true;
document.head.appendChild(loaderScript);
</script>(智能横幅助力)
<script>
// Queue — buffers AF() calls until the SDK is ready
window.AppsFlyerSdkObject = "AF";
window.AF = window.AF || function() {
(window.AF.q = window.AF.q || []).push([Date.now()].concat(Array.prototype.slice.call(arguments)));
};
window.AF.id = window.AF.id || { pba: { webAppId: "WEB_DEV_KEY" }, banners: { key: "YOUR_BANNER_KEY" } };
window.AF.plugins = {};
// Manifest loader config
window.AF_LOADER_CONFIG = {
baseUrl: "https://websdk.appsflyersdk.com",
plugins: ["banners", "pba"]
};
// Inject manifest loader
var loaderScript = document.createElement("script");
loaderScript.src = "https://websdk.appsflyersdk.com/manifestLoader.v1.js";
loaderScript.integrity = "sha384-Uncl2YwvjFpFz0PwEfl3bL/0JsOQcDFEpwXHzcN0MBavn9vvFEx5pZxADTq8h+CV";
loaderScript.crossOrigin = "anonymous";
loaderScript.async = true;
document.head.appendChild(loaderScript);
</script>在网站中对接Web SDK
安装与对接
注意事项与操作要求
| 对接检查清单 |
|---|
| 为确保事件被完整记录和正常访问,请务必在网站的所有页面中安装Web SDK。 |
| 将您在上面选择的代码片段放置在页面范围内尽可能早地加载。最好位于head标签顶部位置,以确保尽早加载。 |
|
如通过Google Tag Manager(GTM)对接:
|
| 在设置Web SDK时,可选择使用或不使用智能横幅。请遵循后文中的相关说明。 |
|
对接必备条件
使用测试工具验证对接是否成功。 |
前期准备 :
- 请与市场营销人员确认已创建品牌套件。
- 如需更多说明,请参见PBA上手指南。
- 注意事项:如您已经在使用独立的智能横幅Web SDK,请先将其移除,统一替换为Web SDK,以便同时支持Smart Banners和PBA;请勿为PBA添加单独的Web SDK。
具体方法如下:
- 获取Web SDK的网页开发者密钥。 注意:此密钥与移动应用使用的密钥不同。
-
如需获取网页开发者密钥:
- 从AppsFlyer后台的顶部菜单栏中选我的应用
- 点击查看品牌套件。
- 复制所需的Web Dev Key(WEB_DEV_KEY)。
-
如需获取网页开发者密钥:
- 如需使用智能横幅,请获取智能横幅密钥。
-
操作方法如下:
- 从AppsFlyer后台的侧边栏中选择互动> 网页到应用>智能横幅。
- 复制所需的智能横幅密钥。
-
操作方法如下:
- 确认您已获得在网站的head标签中添加脚本的权限。
- 如果使用Google Tag Manager(GTM),请确保GTM已完成与网站的对接。
您可以通过以下任意方式对接Web SDK:
嵌入JavaScript代码片段
请使用以下方法之一对接Web SDK。
如需在不使用智能横幅的情况下安装Web SDK:
- 请在网站所有页面中重复以下操作:
- 在下面的代码片段中,将
WEB_DEV_KEY替换为准备阶段获取的WEB_DEV_KEY。 - 将您在上面选择的代码片段粘贴到您网站的head标签中。位置尽量靠前。
如需在使用智能横幅的情况下安装Web SDK:
- 在您网站的所有页面上重复以下程序。
- 在您选择的代码片段中,使用先决条件中指定的键替换
WEB_DEV_KEY和YOUR_BANNER_KEY。 - 将此代码片段粘贴到网站的head标签中。位置尽量靠前。
要使用Google Tag Manager (GTM)实现Web SDK:
- 进入Google Tag Manager。
-
为AppsFlyer Web SDK创建一个新标签。
- 选择自定义HTML标签类型。
- 给标签起一个有意义的名称。
- 根据是否使用智能横幅,执行以下步骤:
- 点击保存。
- 根据是否使用智能横幅,执行以下步骤:
- 在Adobe Experience Cloud后台创建一个Property(即标签)。
- 将Web SDK添加到Adobe Launch标签
- 将Adobe Launch标签添加到网站
- 发布Adobe Launch环境
在Adobe Experience Cloud后台创建一个Property(即标签)。
- 进入Adobe Experience Cloud > Launch。
- 点击Adobe Experience Cloud Launch下的Go to Launch。
- 点击New Property。
- 命名属性。
- 选择Platform下的Web。
- 输入您的网站域名。
- 点击保存。
将Web SDK添加到Adobe Launch标签
- 在My web property页面中,选择Rules选项卡。
- 为该规则命名。推荐使用,加载Web SDK。
- 在If部分,点击Events下的+Add。
- 在Event Type下选择Core - DOM Ready。
- 点击Keep Changes。
- 在Then部分,点击Actions下的+Add。
- 在Action Type下,进入Custom Code。
- 选择JavaScript > Open Editor,将不带<script>标签的Web SDK代码片段粘贴到编辑器中。
- 点击Keep Changes,关闭代码编辑器。
- 点击保存。
将Adobe Launch标签添加到网站
发布Adobe Launch环境
- 从My web property进入Publishing选项卡。
- 在Development部分下点击Add New Library。
- 为该Library命名并选择一个环境。
- 在Resource Changes下,点击Add a Resource。
- 点击Rules > Load Web Banners > Latest > Select & Create a New Revision。
- 点击保存。
- 在Development部分下执行以下操作:
- 点击新创建的library旁边的操作菜单(以3个点表示),并选择Build for Development。
- 再次点击操作菜单,并选择Submit for Approval。
- 在Submitted部分下执行以下操作:
- 点击操作菜单并选择Build for Staging。
- 再次点击操作菜单并选择Approve for Publishing。
- 在已批准部分:
- 点击操作菜单并选择Build & Publish to Production。
- 至此,该流程操作完毕。
在移动设备上加网站载时,横幅中会显示当前启用的素材。如需在特定页面或根据用户操作显示横幅,请参见Adobe Launch规则。
确保SDK正常运行
安装完成后,需要验证访客浏览器是否能够成功调用AppsFlyer Web SDK,并确保数据消息已正常发送。您可以通过检查浏览器开发者工具中的网络请求来完成此操作。
验证SDK加载和运行的步骤如下:
- 打开网站。
-
打开浏览器开发者工具。
- 转到(A)广告平台选项卡。
- 刷新页面。
- 按(B)wa.appsflyer筛选。
- 选择(C)events消息。
- 在 Headers(D)中确认以下信息:
- Request URL为wa.appsflyer.com/events。
- site_id 查询参数=
WEB_DEV_KEY。 - (E) status code is 200.
- 验证site_id的值是否与品牌套件设置中的WEB_DEV_KEY一致:
- 在AppsFlyer后台的侧边栏中选择设置> 品牌套件。
- 点击网页开发者密钥复制密钥。
- 将密钥粘贴到任意位置(例如新浏览器标签页或记事本)以查看。
- 验证site_id和
WEB_DEV_KEY是否匹配。
- 确保SDK仅加载一次。多次加载可能会导致SDK无法正常运行。
事件发送的启用与停用
Web SDK会将访客事件数据发送至AppsFlyer。您可以根据需要开启、关闭或控制事件发送。
注意事项:
- SDK初始状态设置:确定SDK是在页面加载时立即发送事件,还是等待明确的命令后再发送。该设置包含在网页代码片段中。
-
显式控制:可随时手动启用或停止事件发送。例如,如果您设置了数据授权横幅(如Cookie授权弹窗),可以在横幅的控制逻辑中嵌入命令,来启动或停止事件发送。显式控制的优先级高于SDK初始设置,且第一方Cookie具有以下特征:
- Cookie设置在网站域名下。
- Cookie过期时间由Web SDK或浏览器决定;到期后,SDK会恢复至初始设置。
-
SDK设置的Cookie不会影响浏览器自身的Cookie规则。
SDK初始状态设置
| 配置 | 代码片段 |
|---|---|
| [默认] 发送事件 |
对Web SDK代码片段进行以下更改。 如有需要,请添加measurementStatus参数: 设置measurementStatus=true
|
|
不发送事件
|
对Web SDK代码片段进行以下更改。如有必要,添加 measurementStatus 参数: 设置measurementStatus=false |
显式控制
| 操作 | 命令 |
|---|---|
| 开始发送事件(opt-in) | window.AF_SDK.PLUGINS.PBA.enableMeasurement() |
| 停止发送事件(opt-out) | window.AF_SDK.PLUGINS.PBA.disableMeasurement() |
实施内容安全策略 (CSP)
如果您的网站需要严格的安全或数据隐私协议,请使用以下机制配置Web SDK如何与您的环境和数据交互。
内容安全策略(CSP)
如果您的网站要求JavaScript通过CSP进行安全保护,Web SDK支持两种方法,具体取决于您的CSP配置。
-
使用self将
https://websdk.appsflyersdk.com添加到您的script-src允许列表中。这适用于标准Web SDK和高级SDK验证。 -
使用nonce:如果您的策略使用
script-src 'nonce-...',您可以使用高级SDK验证的nonce扩展变体。这将nonce转发到验证过程所需的所有三个脚本标签。用您服务器生成的每个请求的nonce值替换{{CSP_NONCE}}。
下表显示了哪些CSP策略与nonce扩展变体兼容。
| 策略 | 有效 | 说明 |
|---|---|---|
script-src 'self' |
否 | 不允许外部CDN来源;内联脚本也被阻止。 |
script-src 'self' https://websdk.appsflyersdk.com |
不完整数据 | 允许加载器和SDK,但内联设置脚本仍然被阻止。 |
script-src 'nonce-...' https://websdk.appsflyersdk.com |
是 | Nonce覆盖内联脚本和加载器;SDK标签通过加载器转发nonce。 |
script-src 'nonce-...' 'strict-dynamic' |
是(推荐) | Nonce覆盖内联脚本和加载器;strict-dynamic将信任传播到动态注入的SDK标签。允许列表中不需要CDN来源。 |
带有CSP nonce片段的高级SDK验证
没有智能横幅
<script nonce="{{CSP_NONCE}}">
// Queue — buffers AF() calls until the SDK is ready
window.AppsFlyerSdkObject = "AF";
window.AF = window.AF || function() {
(window.AF.q = window.AF.q || []).push([Date.now()].concat(Array.prototype.slice.call(arguments)));
};
window.AF.id = window.AF.id || { pba: { webAppId: "WEB_DEV_KEY" } };
window.AF.plugins = {};
// Manifest loader config — nonce forwarded to the injected SDK <script> tag
window.AF_LOADER_CONFIG = {
baseUrl: "https://websdk.appsflyersdk.com",
plugins: ["pba"],
nonce: "{{CSP_NONCE}}"
};
// Inject manifest loader
var loaderScript = document.createElement("script");
loaderScript.src = "https://websdk.appsflyersdk.com/manifestLoader.v1.js";
loaderScript.integrity = "sha384-Uncl2YwvjFpFz0PwEfl3bL/0JsOQcDFEpwXHzcN0MBavn9vvFEx5pZxADTq8h+CV";
loaderScript.crossOrigin = "anonymous";
loaderScript.nonce = "{{CSP_NONCE}}";
loaderScript.async = true;
document.head.appendChild(loaderScript);
</script>(智能横幅助力)
<script nonce="{{CSP_NONCE}}">
// Queue — buffers AF() calls until the SDK is ready
window.AppsFlyerSdkObject = "AF";
window.AF = window.AF || function() {
(window.AF.q = window.AF.q || []).push([Date.now()].concat(Array.prototype.slice.call(arguments)));
};
window.AF.id = window.AF.id || { pba: { webAppId: "WEB_DEV_KEY" }, banners: { key: "YOUR_BANNER_KEY" } };
window.AF.plugins = {};
// Manifest loader config — nonce forwarded to the injected SDK <script> tag
window.AF_LOADER_CONFIG = {
baseUrl: "https://websdk.appsflyersdk.com",
plugins: ["banners", "pba"],
nonce: "{{CSP_NONCE}}"
};
// Inject manifest loader
var loaderScript = document.createElement("script");
loaderScript.src = "https://websdk.appsflyersdk.com/manifestLoader.v1.js";
loaderScript.integrity = "sha384-Uncl2YwvjFpFz0PwEfl3bL/0JsOQcDFEpwXHzcN0MBavn9vvFEx5pZxADTq8h+CV";
loaderScript.crossOrigin = "anonymous";
loaderScript.nonce = "{{CSP_NONCE}}";
loaderScript.async = true;
document.head.appendChild(loaderScript);
</script>丢弃查询参数
如果您的查询参数包含您不希望AppsFlyer记录的数据,您可以要求AppsFlyer平台丢弃某些或所有查询参数。这些参数将不会出现在原始数据或报表中。
您可以使用以下方法丢弃URL、referrer和header_referer查询参数。
查询参数丢弃选项
| 方法 | 说明 |
|---|---|
| 丢弃所有查询参数 | 在URL后加上af_url=true
|
| 丢弃指定查询参数 |
通过设置查询参数掩码,指定要丢弃的参数。 使用 示例: 带掩码的Url:
丢弃后的Url:
|
事件记录原则
转化事件和标准事件
- 用户事件由SDK记录并发送到AppsFlyer平台。
- 根据市场人员设置的转化事件列表,AppsFlyer会将事件分为 标准事件和转化事件:
- 转化事件数据可在PBA面板中查看。
- 转化和标准事件数据可在原始数据报告中查看。
转化事件
- 转化事件能够帮助您洞察营销和业务成效,此类事件包括购买、下载、注册和订阅。
- PBA会将转化事件归因到驱动用户访问网站的媒体渠道。
- 通过识别被归因的媒体渠道,您可以评估并比较不同渠道带来的用户质量。
- 转化事件还可用于记录收入并计算ROI。
- 您可将广告在不同媒体渠道的投放成本与这些渠道带来的收入进行对比。
标准事件
- 标准事件主要用于验证带来最终转化的用户路径和漏斗。
- 标准事件可用来衡量用户活跃度,突出带来深度用户的媒体渠道。
- 记录的用户行为也能帮助您标记用户,以便后续进行再营销活动。
事件记录
在满足某些条件时触发Web SDK记录事件,例如,落地页加载时或用户与网页元素互动时。请参见事件记录示例。
使用客户用户ID(CUID)识别用户
- AppsFlyer通过您分配的唯一CUID对Web用户进行识别。通常CUID由您的后端服务器管理。
- 建议使用与移动端相同的CUID,以便统一分析跨平台的用户行为。移动SDK中的函数为setCustomerUserId函数(iOS/span>,Android,Unity)。
-
在Web SDK中设置CUID:
- 请在能够获取CUID后尽早设置。通常您需要等待用户通过登录或注册进行身份验证。
-
触发JavaScript调用setCustomerUserId()的方法如下所示。
请注意:即使CUID是数字,也必须以字符串形式传递(需加引号)。
- 如果使用Web S2S,可能需要在后端将CUID与Web访客ID关联后通知PBA。
- CUID不得包含可直接识别个人身份的信息,如手机号或邮箱。
示例:设置CUID
// Associate all current user web events to distinct ID 663274
AF('pba', 'setCustomerUserId' , '663274')
Web SDK事件参数
| 参数名称 | 是否必须配置 | 说明 |
|---|---|---|
| eventType | 是 |
事件类型 格式:字符串 始终填写 "EVENT" 示例:eventType:"EVENT" |
| eventName | 是 |
事件名称 格式:字符串 示例:Purchase, Subscription |
| 否 | 已弃用,将在未来移除。请改用eventValue参数。 | |
|
|
否 | 已弃用,将在未来移除。请改用eventValue参数。 |
| eventRevenue | 否 |
转化事件关联的收入。 格式:浮点数 |
| eventRevenueCurrency | 否 |
收入数据的货币单位
格式:字符串 |
| eventValue | 否 |
描述事件的事件参数映射。用于发送富应用内事件,如商品SKU、单价。
格式:JSON
示例:要发送SKU ABC123,颜色为蓝色,单价为$3.99
限制:1000个字符以内,超出部分将被截断。 |
事件记录场景示例
示例事件
// purchase event of shoes with associated revenue
AF('pba', 'event', {eventType: 'EVENT', eventName: 'purchase', eventRevenue: 12, eventValue: {"key1": 123, "key2": "name"}});
您需要发送的事件类型取决于网站的业务性质。例如:电商网站与新闻网站所需的事件类型可能有所不同。请参阅以下场景,以了解您应该在何时发送何种事件。
电商网站
假设您正在运营一家电商网站,您可能需要记录以下标准事件与转化事件:
- 搜索:标准事件
- 加入购物车:标准事件
- 从购物车中移除:标准事件
- 购买:转化事件
新闻网站
假设您正在运营一家新闻网站,您可能需要记录以下转化事件:
- 注册:转化事件
- 购买订阅:转化事件
确保事件被成功发送
请网页开发人员参阅以下内容。
您可以通过实时查看测试事件,测试PBA Web SDK是否已正确对接。
操作步骤如下:
- 打开网站。
- 打开浏览器开发者工具。
- 切换到Network(平台)标签。
- 触发事件。
-
按消息筛选。
- 查找发送到wa.appsflyer.com的网络请求。
- 检查以下内容:
- Status code = 200。
- Request Payload与事件参数一致。
示例
事件记录
以下示例代码仅供参考,请勿直接使用。
- 假设:在事件发送时,页面已经加载了Web SDK。
- 示例场景包含在以下场景下记录事件的代码:
- 落地页加载时。
- 用户与网站发生交互时。
在落地页加载时记录事件
- 您有一个新闻订阅页面,您希望在该页面记录订阅事件。
- 你也可以设置一个“感谢页面”,用户订阅后会跳转到该页面。
<html>
<head>
<!-- Assume that the server returns a response with details about the newly subscribed user -->
<!-- Alternatively, you can extract data from localStorage or cookies,
in case data was set in either of them during the subscription process
-->
<script>window.onload = function(){
AF('pba', 'event', {eventType: 'EVENT', eventValue: {'category': 'holiday_promotion', eventValue: {'label' : 'newspaper'}, eventName: 'subscription',}); } </script> </head> <body> <h1>Thank You for Subscribing to Our Newsletter</h1> </body> </html>
- 上述代码包含基本的HTML页面。页面必须先加载Web SDK,才能发送事件。
- 当用户跳转到感谢页面时,window.onload方法会调用AF(),将订阅事件发送至AppsFlyer。
用户与网站互动时记录事件
- 您运营一家电商网站,希望记录结算事件。
- 在用户点击结账按钮时,Web SDK会向AppsFlyer发送事件。
<html>
<head>
<!-- Assume that data about products in the shopping cart
is stored in localStorage -->
<script>
window.onload = function () {
document.getElementById('checkout').addEventListener('click', function () {
AF('pba', 'event', {eventType: 'EVENT', eventValue: {'category' : 'holiday_promotion'}, eventName: 'checkout'});
});
}
</script>
</head>
<body>
<h1>Shopping Cart</h1>
<h2>Shirt</h2>
<p>
<ul>
<li>Color: Blue</li>
<li>Quantity: 2</li>
<li>Price: $20</li>
</ul>
</p>
<h2>Pants</h2>
<p>
<ul>
<li>Color: Black</li>
<li>Quantity: 3</li>
<li>Price: $15</li>
</ul>
</p>
<button id='checkout'>Checkout</button>
</body>
</html>
上述代码包含基本的HTML页面。 页面必须先加载Web SDK,才能发送事件。
- 页面加载完成后,会将点击事件监听器(click listener)绑定到结账按钮。
- 当用户点击结账按钮时,回调函数:
- 从localStorage中获取数据。
- 调用AF()并传递数据。
- AF()将事件发送到AppsFlyer。
在落地页加载时记录事件
- 您有一个新闻订阅页面,您希望在该页面记录订阅事件。
- 您设置了一个感谢页面,用户在成功订阅后会跳转至该页面。
-
设置感谢页面
<html> <head> <script> // Google Tag Manager loads the Web SDK <script>(function(w,d,s,l,i){w[l]=w[l]||[];w[l].push({'gtm.start': new Date().getTime(),event:'gtm.js'});var f=d.getElementsByTagName(s)[0], j=d.createElement(s),dl=l!='dataLayer'?'&l='+l:'';j.async=true;j.src= 'https://www.googletagmanager.com/gtm.js?id='+i+dl;f.parentNode.insertBefore(j,f); })(window,document,'script','dataLayer','GTM-XXXX'); </script> <script> // Assume that the server returns a response with details about the newly subscribed user function getResponseFromServer() { return JSON.stringify({ action: 'subscribe', category: 'site actions', label: userEmail }) } //Alternatively, you can extract data from localStorage or cookies, //in case data was set in either of them during the subscription process localStorage.setItem('data', JSON.stringify({ action: 'subscribe', category: 'site actions', label: 'user@email.com' })); </script> </head> <body> <h1>Thank You for Subscribing to Our Newsletter</h1> </body> </html>上述代码加载了GTM,进而加载了Web SDK。接下来脚本中会发生两个操作:一个是从服务器获取用户详细信息的函数。另一个是将数据设置到本地存储的函数。GTM可以访问函数和localStorage。您可以通过GTM调用该函数并访问localStorage。
-
在感谢页面加载后,添加一个新的标签用于归因订阅事件。
- 给标签起一个唯一的名称,并选择自定义HTML标签类型。
-
将以下代码放入自定义HTML中。
<script> AF('pba', 'event', {eventType: 'EVENT', eventValue: {'category' : 'holiday_promotion'}, eventName: 'subscription'}); </script> -
展开高级设置控件,然后在标签顺序控件中确保设置正确,以便在该标签执行后触发转化事件。
-
要触发转换标签,请设置一个触发条件。在本示例中,触发条件为感谢页面加载。
用户与网站互动时记录事件
- 您运营一家电商网站,希望记录结算事件。
- 用户点击结账按钮后,Web SDK会向AppsFlyer发送事件。
-
设置结账页面
<html> <head> <script> // Google Tag Manager loads the Web SDK <script>(function(w,d,s,l,i){w[l]=w[l]||[];w[l].push({'gtm.start': new Date().getTime(),event:'gtm.js'});var f=d.getElementsByTagName(s)[0], j=d.createElement(s),dl=l!='dataLayer'?'&l='+l:'';j.async=true;j.src= 'https://www.googletagmanager.com/gtm.js?id='+i+dl;f.parentNode.insertBefore(j,f); })(window,document,'script','dataLayer','GTM-XXXX'); </script> </head> <body> <h1>Shopping Cart</h1> <h2>Shirt</h2> <p> <ul> <li>Color: Blue</li> <li>Quantity: 2</li> <li>Price: $20</li> </ul> </p> <h2>Pants</h2> <p> <ul> <li>Color: Black</li> <li>Quantity: 3</li> <li>Price: $15</li> </ul> </p> <button id='checkout'>Checkout</button> </body> </html>代码通过GTM加载Web SDK,其余部分为模拟的购物车HTML页面。结账按钮的ID为checkout。在GTM中配置点击事件时需要用到。
- 在GTM中,点击Variables(变量)中的Configure(配置),勾选Built-In Variables中的Click Element(点击元素)。
- 新建变量,设置有意义的名称,类型选择All Elements(所有元素)。
- 在触发条件配置中,选择Some Clicks(部分点击),根据#checkout的CSS Selector选择Click Element(点击元素)。
-
为结账操作创建一个新标签,选择自定义HTML类型,并将触发条件设置为结账。
<script> AF('pba', 'event', {eventType: 'EVENT', eventValue: {'category' : 'holiday_promotion'}, eventName: 'checkout'}); </script>
- 确保Web SDK功能标签在事件触发前已加载。
- 不要在事件值中包含特殊字符(例如货币符号)。
- 事件值字符串应少于50个字符。
设置用户注册后的CUID
以下示例中的代码仅供参考。请勿直接使用。如不确定如何使用此代码,请咨询网页开发人员。
注意事项:确保Web SDK在事件触发前已加载;请勿重复加载SDK。
使用场景:
- 用户在您的网站上注册。
- 网站代码收集用户信息并发送到服务器。
- 服务器为用户生成唯一的CUID。
- 在注册完成后跳转的感谢页面中,网站通过服务器返回的结果获取该CUID。
- 借助服务器响应,使用Web SDK的 setCustomerUserId() 方法设置CUID。
注册页面示例:
<html>
<head>
<!-- The Web SDK script loads first -->
<script>
!function(t,e,n,s,a,c,i,o,p){t.AppsFlyerSdkObject=a,t.AF=t.AF||function(){
(t.AF.q=t.AF.q||[]).push([Date.now()].concat(Array.prototype.slice.call(arguments)))},
t.AF.id=t.AF.id||i,t.AF.plugins={},o=e.createElement(n),p=e.getElementsByTagName(n)[0],o.async=1,
o.src="https://websdk.appsflyersdk.com?"+(c.length>0?"st="+c.split(",").sort().join(",")+"&":"")+(i.length>0?"af_id="+i:""),
p.parentNode.insertBefore(o,p)}(window,document,"script",0,"AF","pba",{pba: {webAppId: "WEB_DEV_KEY"}})
</script>
<script>
};
// This function stores the user email sent to the server after the user reaches the thank you page
// The response from the server is a unique CUID that should be set using the web SDK setCustomerUserId method
function storeUserEmail (){
var userEmail = document.getElementById('email').value;
localStorage.setItem('user_email', userEmail);
}
</script>
</head>
<body>
<h1>Sign Up</h1>
<form onsubmit="storeUserEmail()" action="/signup" method="post">
<div><label>Name</label>
<input type="text" name="name" id="name"></div>
<br />
<div> <label>Email</label>
<input type="email" name="email" id="email"></div>
<br />
<input type="submit" id="submit">
</form>
</body>
</html>
该代码展示了一个简单的注册表单。表单提交时,用户邮箱会保存到localStorage。跳转至感谢页面时,用户的电子邮件地址会呗发送到服务器,以生成该电子邮件地址的唯一CUID。
为注册的用户设置感谢页面:
<html>
<head>
<script>
!function(t,e,n,s,a,c,i,o,p){t.AppsFlyerSdkObject=a,t.AF=t.AF||function(){
(t.AF.q=t.AF.q||[]).push([Date.now()].concat(Array.prototype.slice.call(arguments)))},
t.AF.id=t.AF.id||i,t.AF.plugins={},o=e.createElement(n),p=e.getElementsByTagName(n)[0],o.async=1,
o.src="https://websdk.appsflyersdk.com?"+(c.length>0?"st="+c.split(",").sort().join(",")+"&":"")+(i.length>0?"af_id="+i:""),
p.parentNode.insertBefore(o,p)}(window,document,"script",0,"AF","pba",{pba: {webAppId: "WEB_DEV_KEY"}})
</script>
<script>
// Using the fetch API to send the user email to the server
// and get the unique user id in return
window.onload = function () {
var userEmail = localStorage.getItem('user_email');
fetch('users/' + userEmail).then(function (res) {
res.text().then(function (id) {
console.log(id);
AF('pba', 'setCustomerUserId', id);
});
});
} </script>
</head>
<body>
<h1>Thank You for Signing Up!</h1>
</body>
</html>
该代码使用fetch API将邮箱发送至服务器。假设服务器在注册时为用户生成唯一CUID,将电子邮件地址发送到服务器的目的是为了接收唯一的CUID。服务器返回的CUID作为setCustomerUserId()的参数传递给AppsFlyer。。
-
注册页面示例:
<html> <head> <script> // Google Tag Manager loads the Web SDK (function (w, d, s, l, i) { w[l] = w[l] || []; w[l].push({ 'gtm.start': new Date().getTime(), event: 'gtm.js' }); var f = d.getElementsByTagName(s)[0], j = d.createElement(s), dl = l != 'dataLayer' ? '&l=' + l : ''; j.async = true; j.src = 'https://www.googletagmanager.com/gtm.js?id=' + i + dl; f.parentNode.insertBefore(j, f); })(window, document, 'script', 'dataLayer', 'GTM-5VJ6C7R'); // This function stores the user email to be sent to the server after the user reaches the thank you page // the response from the server is a unique CUID that should be used in the web SDK setCustomerUserId method function storeUserEmail (){ var userEmail = document.getElementById('email').value; localStorage.setItem('user_email', userEmail); } </script> </head> <body> <h1>Sign Up</h1> <form onsubmit="storeUserEmail()" action="/signup" method="post"> <div><label>Name</label> <input type="text" name="name" id="name"></div> <br /> <div> <label>Email</label> <input type="email" name="email" id="email"></div> <br /> <input type="submit" id="submit"> </form> </body> </html>该代码展示了一个简单的注册表单。表单提交时,用户邮箱会保存到localStorage。当用户到达感谢页面时,用户的电子邮件地址会发送到服务器,以获取该电子邮件的唯一CUID。
-
为注册的用户设置感谢页面:
(t.AF.q=t.AF.q||[]).push([Date.now()].concat(Array.prototype.slice.call(arguments)))}, t.AF.id=t.AF.id||i,t.AF.plugins={},o=e.createElement(n),p=e.getElementsByTagName(n)[0],o.async=1, o.src="https://websdk.appsflyersdk.com?"+(c.length>0?"st="+c.split(",").sort().join(",")+"&":"")+(i.length>0?"af_id="+i:""), p.parentNode.insertBefore(o,p)}(window,document,"script",0,"AF","pba",{pba: {webAppId: "WEB_DEV_KEY"}}) </script> <script> // using the fetch api to send the user email to the server // and get the unique user id in return window.onload = function () { var userEmail = localStorage.getItem('user_email'); fetch('users/' + userEmail).then(function (res) { res.text().then(function (id) { console.log(id); AF('pba', 'setCustomerUserId', id); }); }); } </script> </head> <body> <h1>Thank You for Signing Up!</h1> </body> </html>前述代码示例展示了一个感谢页面,在该页面中通过GTM触发器将用户在注册表单中填写的邮箱发送到服务器。
服务器会为用户创建一个唯一的CUID。
将电子邮件发送到服务器的目的是为了获取该CUID。
服务器返回CUID后,会通过 setCustomerUserId()传递给AppsFlyer。
继续按照该流程创建触发条件和标签。 - 在感谢页面加载后,添加一个新的标签,用于归因订阅。
-
给该标签起一个唯一的名称,并选择Custom HTML(自定义HTML)作为标签类型
<script> var userEmail = localStorage.getItem('user_email'); fetch('users/' + userEmail).then(function (res) { res.text().then(function (id) { console.log(id); AF('pba', 'setCustomerUserId', id); }); }); </script> -
展开高级设置控件,然后在标签顺序控件中确保设置正确,以便在该标签执行后触发转化事件。
-
为转化标签配置一个触发条件,用来规定该标签在何时触发(在本示例中,触发条件会在 “感谢页面”加载时触发)。
setCustomerUserId()函数可以在用户流程中的任意阶段调用,例如:用户登录或注册之后。AppsFlyer会使用最近一次发送的CUID来更新该用户,应用于过去或未来的触点和事件。
请在网页端使用与移动端应用(iOS、Android、Unity)中setCustomerUserId函数相同的CUID值。
附加信息
Web SDK cookies
您网站上Web SDK设置或使用的cookies如下表所示:
缩写说明:
- AMP:Accelerated Mobile Pages(加速移动页面)
- CDN:Content Delivery Network(内容分发网络)
- 3PC:Third-party Cookies(第三方Cookie)
| Cookie名称 | 域名 | 有效期 | 使用场景 | 说明 |
|---|---|---|---|---|
| afUserid | 您的网站域名 | 395天 | 非AMP | 标识用户在网页加载和导航事件中的身份 |
| AF_SYNC | 您的网站域名 | 1周 | 非AMP |
|
| af_id | appsflyer.com | 395天 | 非AMP(允许三方Cookie时) | 标识用户在应用启动和导航事件中的身份 |
| af_id | .onelink.me | 395天 | 非AMP(允许三方Cookie时) | 将横幅交互、OneLink交互或两者与应用启动事件关联。 |
| amp-afUserid | AMP CDN或您的网站域名 | 1年 | AMP页面 | |
| AF_DEFAULT_MEASUREMENT_STATUS | 您的网站域名 | 395天 | 存储PBA同意状态。在获得用户同意前阻止SDK运行。默认不设置,仅在配置同意拦截时使用。 | 非AMP |
Web SDK发布说明
| 日期 | 版本 | 说明 |
|---|---|---|
| 2021-07-01 | 1.0 | 支持丢弃查询参数 |
| 2021-06-01 | 1.0 | 支持内容安全策略(CSP) |
| 2020-08-31 | 1.0 | 添加选择加入和退出功能 |
| 2020-04-16 | 1.0 | customerUserId()函数取代IDENTIFY事件来发送唯一的CUID |
| 2020-07-30 | 1.0 |
|
弃用日期
- 弃用通知用于提前告知某个功能或方法即将停止支持。在正式下线之前,该功能或方法仍然可以正常使用。
- 建议您将弃用通知视为优化代码的契机,提前进行调整。
| 弃用日期 | 终止日期 | 说明 |
|---|---|---|
| 2020-04-16 | 待宣布 |
弃用方法:在事件参数customUserId中发送客户用户ID(CUID),事件类型设置为"IDENTIFY" 当前方法: 使用setCustomerUserId()函数发送 CUID |