客户端.io 数据管道分析客户端用于浏览器.
安装
npm install @customerio/cdp-analytics-browser
使用量
import { AnalyticsBrowser } from '@customerio/cdp-analytics-browser'
const cioanalytics = AnalyticsBrowser.load({ writeKey: '<YOUR_WRITE_KEY>' })
cioanalytics.identify('hello world')
document.body?.addEventListener('click', () => {
cioanalytics.track('document body clicked!')
})
网络推 (内部 alpha)
如上安装此软件包 。 启用您的客户端. io 工作空间的网络推取 首先配置其 Web Push 证书 。 明确装入插件; 不是 默认装入 。 装入不注册服务员或申请许可. 它只检查已有的订阅以调和已更改的终点 .
import {
AnalyticsBrowser,
WebPushPlugin,
} from '@customerio/cdp-analytics-browser'
const [analytics] = await AnalyticsBrowser.load({
writeKey: '<YOUR_WRITE_KEY>',
})
await analytics.register(
WebPushPlugin({
vapidPublicKey: '<YOUR_PUBLIC_VAPID_KEY>',
serviceWorkerUrl: '/cio-webpush-sw.js',
trackUrl: 'https://track.customer.io',
})
)
await analytics.identify('your-user-id')
// Invoke directly from a user gesture, especially on Safari/iOS.
document.querySelector('#subscribe')?.addEventListener('click', () => {
void analytics.webPush!.subscribe().catch(console.error)
})
或者,通过这些设置 integrations['Customer.io Web Push Plugin']
第二个参数改为: AnalyticsBrowser.load设置 enabled: false 来禁用它.
主机必须只启用用于工作空间的α web-push 旗帜;
sDK不查询 FlightDeck .
选项 :
vapidPublicKey: 需要公共基数64url VAPID密钥(不是私人密钥).serviceWorkerUrl: 默认为/cio-webpush-sw.js必须同源. 直接注册工人文件( 插件有, 附加)?track=) (中文(简体) ). 狦 将它输入到您自己的服务员中importScripts相反,你的工人 拥有其生命周期: setself.cioWebPushLifecycle = false在导入之前 文件跳过skipWaiting()编号 :clients.claim(),并登记您的工作者 同样的?track=这样发送的查询和打开的事件仍然可以到达客户.io (和同样?runtime=如果您设置了查询runtimeUrl) (中文(简体) ).trackUrl: 默认为https://track.customer.io,或https://track-eu.customer.io在使用欧盟CDN时。 在代理 SDK 或使用 带有自定义 CDN 的独立插件.runtimeUrl:工人装入自更新运行时间的地方(见下文). 默认为https://cdp.customer.io/v1/analytics-js/cio-webpush-sw-runtime.v1.js, (中文(简体) ), 或者说cdp-eu.customer.io何时trackUrl是欧盟的东道国。 通过一个绝对 URL 或一个 根相对路径( 例如)/cio/cio-webpush-sw-runtime.v1.js为它服务 通过您的代理服务器进行首次聚会,或false保存工人的捆绑副本 不提出请求(登记为:?runtime=off. 代理的欧盟网站trackUrl默认获取 US CDN; 设定runtimeUrl页:1cdp-eu.customer.ioURL 或 网络 自己的代理服务器.
关于初始分析实例的公共API:
analytics.webPush!.requestPermission() // Promise<NotificationPermission>
analytics.webPush!.subscribe({ vapidPublicKey, serviceWorkerUrl }) // optional overrides
analytics.webPush!.subscription() // Promise<WebPushSubscriptionJSON | null>
analytics.webPush!.unsubscribe() // Promise<void>
analytics.webPush!.onClick((event) => console.log(event.customData)) // returns a cleanup function
先确认身份 匿名用户可以获得浏览器权限并创建
浏览器订阅,但其设备注册承诺等待 identify· ;
没有发送匿名设备事件 。 如果页面关闭( I)pagehide)或插件
在识别前卸下,该承诺以身份错误拒绝.
抓住承诺,不要依赖卸货时间 显示同步工作.
如果工人在30秒内没有登记和启动, subscribe()
拒绝方式 Web push service worker did not activate within 30 seconds.; 数据
浏览器可能仍会安装完毕, 因此调用 subscribe() 也还是安全的.
每个工人路径都坚持设备所有权:重置删除设备
为当前路径存储的人,并识别另一个人注册
为了他们。 即使在登录时也不订阅浏览器订阅;
删除时使用存储的所有者 .
未经承认的已删除的删除按原事件时间/顺序持续进行
以回放(30秒至1小时)重试,包括重装后. 重新装入
在备份中不排队重复删除。 HTTP 4xx 最终清理停止
(除408/429外),经过20次尝试失败,或经过了7天,因此不能
永久区块注册。 缓冲删除的确认或最终
拒绝自动调节当前识别的用户而不重新加载.
使用的设备序列 max(previous + 1, Date.now()) (64位时标)和
在整个停放期间持续。 Web 锁定序列分配
可使用;没有锁,分配仍然是最努力的。 存储损失后,
假设时钟已经超越了先前的顺序.
工人们的 URL 持续存在,所以以后的负载可以找到订阅,因为
只要有时间 serviceWorkerUrl 加载选项仍然为原始路径命名 。 何处
localStorage 不存在(例如,一些私人浏览模式),所有者
而每个调用的 URL 仅持续到当前页面.
要迁移到另一个工人路径,打电话 analytics.webPush.unsubscribe() 时
仍然使用旧路径, 然后在新路径订阅 。 这是建议
方法: 它删除旧的浏览器订阅和设备记录; 主机
仍然拥有它的工人.
直接传递到新路径 subscribe({ serviceWorkerUrl }) 获得支持
和限制。 如果新路径还没有被存储, 旧路径的存储
在创建新订阅前, 所有者将被保留在那里; 成功
订阅后删除该设备( 当已知其所有者时)并注册
新来的 如果浏览器在新路径上没有订阅而失败
创建一个,上一路径将保留选中且其存储的所有者不变,
这样 subscription(),取消订阅,识别并重新设置继续就
上一条路径。 如果失败发生在创建新路径订阅之后
或已旋转的现有路径,新路径将保留并重设或稍后
订阅可以删除其保留的所有者 。 如果新路径已经有存储的记录,
记录获胜 旧路径的设备既没有转移也没有被删除,
所以直接迁徙并不能清理两条道路。 订阅删除
目标记录的设备,只有在其端点或所有者不同时
相同的端点和所有者作为更新发送,而不删除. 在每一个
直接处理旧浏览器的注册和订阅.
改变 serviceWorkerUrl 加载选项本身不读取或迁移
旧路径存储的记录;插件只使用新路径所存储的内容.
对于相同范围的新文件名,主机还必须解除旧文件的注册
工人在未订阅后,在签署新的 URL 之前。 警卫
即使老工人以前工作过,也拒绝替代
网络推力; unsubscribe() 取消订阅,而不是东道主的工人.
复制 node_modules/@customerio/cdp-analytics-browser/dist/cio-webpush-sw.js 改为
/cio-webpush-sw.js 在你的网站上。 在 HTTPS 上作为 JavaScript( 本地主机为
发展是允许的,没有方向。 根工人有根范围. 用于
/notifications/cio-webpush-sw.js,以 serviceWorkerUrl; 默认值
范围为 /notifications/不要覆盖另一个应用程序的服务人员:
使用专用范围或将操作员融入您现有的工人中
通过工人的URL。 订阅在同一情况下拒绝不同的工人
登记或替换前的范围。 该插件将工人登记为
经典剧本,所以如果你现在的工人是模块服务工人
(单位:千美元)type: 'module'{\fn黑体\fs22\bord1\shad0\3ahbe\4ah00\fscx67\fscy66\2chffffff\3ch808080}就如往常一样 cio-webpush-sw.js 在一个专用的
范围。 普通通知许可
请求仍然发生在您的用户动作中.
工人们从它的 ?track= 查询和运行时间
地点从 ?runtime= 当你准备好 runtimeUrl。与一个
现有工人,在每一个东道主的登记电话中保留两者;
注册空 URL 后来禁用新送出/ 打开的度量衡, 但队列已队列
报告保留并重试其原始终点。 在更新 SDK 时重建/复制推手.
接待的工人更新自己。 它将整个运行时间捆绑在一起,所以它与
没有网络请求, 启动时它也会尝试 importScripts 在客户
疾控中心 cio-webpush-sw-runtime.v1.js (同一文件,由每个 SDK 发布)
页:1 当复制品比捆绑的更新时 它会运行,所以工人
在不复制文件的情况下修正到您的站点。 被屏蔽, 失败( 任何 HTTP)
错误),更古老,或已破损的导入器会留下捆绑的复制件负责和工人
仍然安装。 一个运行时主机会放下或拖住请求是不同的:
Firefox 安装失败, 或者一旦导入等待更多时间就永远不会完成
超过40-60秒,而Chrimium等待连接到超时(约75秒).
所以在浏览器登记工人之前, subscribe() 检查一下
运行时间主机答案(a) fetch 带有3秒超时;任何 HTTP 状态计数).
如果没有,工人将登记在 ?runtime=off 并运行其捆绑
copy. 安装的工人保留 ?runtime= 询问以后的电话,包括
off,所以工人的 URL 不从页面更改;更改 runtimeUrl
以同样方式检查并仅在主机答案时应用。 检查出来了
每页装入一次,从未使用 runtimeUrl: false。在
注册的浏览器 ?runtime=off (例如,在网络之后)
封锁 cdp.customer.io 固定的,或者在服完初赛后,
设定 runtimeUrl 明确:下一个 subscribe() 在浏览器中检查它
并用它重新登记 工人一旦回答。 这页
connect-src 内容安全 策略必须允许检查的运行时间主机
以通过。 登记自己的工人(拥有 importScripts)没有支票,所以
向CDN投放数据包的网络服务于运行时的首次聚会 runtimeUrl。 。 。 .
浏览器在服务工作期间重新检查成功导入的运行时间
更新检查并安装新工人版本; 安装工人
当导入失败时, 将会保留其捆绑的副本, 直到您主机文件更改 .
自动阻断器默认列表( 例如 uBlock Origin) 块
cdp.customer.io 在其它网站上,为了升级这些浏览器,服务运行时间
与 runtimeUrl。破除改变的船作为新的 .v2.js 存档
现有主机副本从不装入。 如果您的网站设置了内容安全政策
工人,允许 https://cdp.customer.io 财务报告和审定财务报表 https://cdp-eu.customer.io 联合国
script-src,或使用 runtimeUrl与 runtimeUrl: false,更新您的主机副本
当您更新 SDK.
已交付/已打开的报告在发送前保存在索引数据库的发件箱中。 离线
请求和可重试的 HTTP 失败在工人启动、推、通知时重试
单击和背景同步( 在支持的地方) , 并有 30 秒 指数回放
在一个小时后封顶。 408/429以外的HTTP 4xx是最终的并压制重放,同时
收据被保留。 背景同步仅在报告保留时注册
待定。 激活,通知显示和导航不等待报告.
打开的报表等待已排队的已交付报表完成(包括最终报告)
拒绝);无关的交货仍然可以进行.
收发箱最多保留了100份待发报告和1 000份7份总记录
超时驱逐最年长的待报者或确认收到者。 重复
同一发送、事件和设备的报告(无论按钮)
在保留记录时被压制。 保留第一个时间戳
行动 如果存储不可用或保存失败,工人将制作
每个事件都直接发出一个最优的信号,不重复或重复.
没有旧浏览器 AbortSignal.timeout 发送时无需 SDK 请求超时 .
工人的执行范围是私人的 importScripts 师曰.
浏览器终止或丢失的 HTTP 识别仍然可以重放已接受的
请求; 端到端的精确报告也需要服务器侧的一能性.
失败的可选 Web Push 块导入或插件构造被警告一次 每个分析加载并跳过;普通分析继续初始化.
Safari支持在所支持的macOS版本上进行网络推力;iOS/iPadOS 16.4+需要一个
已安装 Home Screen Web app(带有网络应用程序显示). 请求许可
a 用户动作。 不支持的浏览器或被拒绝的权限拒绝 subscribe。 。 。 .
更改 VAPID 密钥会取消已有的订阅 。 通话 subscribe 与
新密钥在注册新设备前不订阅并删除旧设备.
设备属性
每个 Device Created or Updated 注册(订阅、更新和终点)
校正)同时发送这些设备属性 webpush_p256dh 财务报告和审定财务报表
webpush_auth数字 :
| 属性 | 数值 |
|---|---|
user_agent | 原文 navigator.userAgent (不变) |
webpush_expiration_time | PushSubscription.expirationTime 以整数时间为毫秒; 当未知时以无效方式发送以清除过期(常见于Chrome、Firefox和Safari) |
browser | Chrome, (中文(简体) ), Edge, (中文(简体) ), Firefox, (中文(简体) ), Safari, (中文(简体) ), Opera, (中文(简体) ), Samsung Internet,或 Other |
browser_version | 主要版本,作为字符串(例如, '154'; 未知时省略 |
os | macOS, (中文(简体) ), Windows, (中文(简体) ), iOS, (中文(简体) ), iPadOS, (中文(简体) ), Android, (中文(简体) ), Linux, (中文(简体) ), ChromeOS,或 Other |
origin | 现场 location.origin (例如, 'https://shop.example.com'),因此每个浏览器记录其订阅的站点 |
这些有限度的浏览器/OS值支持片段而不解析UA字符串.
小小的内置分析器更喜欢 navigator.userAgentData 品牌和平台
如果有的话,就回到普遍获得的标志。 它没有高调的提示或
第三方分析器。 铬在Chrome;特定边缘、歌剧院和
三星活符比一般克罗姆活符优先. 桌面模式 iPadOS
使用Macintosh UA加接点检测。 iOS 家屏幕应用程序可能
省略浏览器版本:工人的WebKit引擎版本不是Safari主机.
未知的过期表示 不详,而不是过期订阅。 插件发送
无法清除先前存储的过期。 一个持续的浏览器指纹,
主要版本、操作系统、原产地和过期引发变化时重新登记(包括
由较老的SDK在下一页负载上注册的回填设备). 未更改
属性不会触发另一个注册.
通知有效载荷
工人们接受 title, (中文(简体) ), body选项 image (大图), icon, (中文(简体) ),
badge, (中文(简体) ), link (默认点击 URL),和 actions数字 :
{
"title": "Your order is ready",
"body": "View your order for details.",
"image": "https://example.com/order.png",
"icon": "https://example.com/icon.png",
"badge": "https://example.com/badge.png",
"link": "https://example.com/orders",
"actions": [
{
"action": "view",
"title": "View order",
"url": "https://example.com/orders/123"
},
{ "action": "later", "title": "Later" }
],
"CIO-Delivery-ID": "<delivery-id>",
"CIO-Delivery-Token": "<subscription-endpoint>"
}
HTTPS URL 用于图标、徽章和动作目的地。 行动ID必须是独一无二的
匹配 [a-z0-9_-]{1,32};标题由 Unicode 白空格(包括
U+0085和U+FEFF),必须非空并最多
32 Unicode 代码点(一个emoji计数为一),规则Consumers.io适用于当
它可以保存并传递信息.
工人放弃畸形动作,最多保留两个有效的条目。 这个
浏览器决定显示多少个按钮: Chrome 支持两个; Firefox 可能显示
无。 图像,图标,和徽章渲染也取决于浏览器和OS.
未知的有效载荷字段不是通知选项 。 可选高级选项
转至 showNotification 仅在出现时:
| 中继有效载荷场 | 数值 |
|---|---|
requireInteraction | Boolean; 保留屏幕直至解析 |
silent | 布尔; 压制声音/振动 |
tag | 替换标记 (1-64个字符:字母,数字, _ . : -(中文(简体) ) |
renotify | 布尔; 需要 tag |
vibrate | 1至10个整数,每个0至1000毫秒 |
lang | BCP 47 语言标记(最多35个字符) |
dir | auto, (中文(简体) ), ltr,或 rtl |
timestamp | 事件时间( 以相去相去数毫秒) |
app_badge | 0–9999; 0 清除应用程序徽章 |
custom_data | JSON 对象保留为 notification.data.custom_data |
中继会验证这些字段( 并将一个已实现的 ISO 时间戳转换为时代)
毫秒). 作曲家 require_interaction 成为中继 requireInteraction。 。 。 .
劳动者在没有选项时不添加默认值. 它强迫选项类型,
丢弃无效 dir/时间戳,滴出 vibrate 当静静地 renotify
没有非空标签。 畸形的强制回落到基础选择.
浏览器/OS支持不尽相同;
不支持的通知选项可能被忽略 . app_badge 区别于
通知 badge 图像:它叫工人 navigator.setAppBadge(count) 或者说
clearAppBadge() 当可用时。 不支持或拒绝作恶不能防止
通知显示或交付指标.
单击动作打开其 url后退为 link 省略时; 单击正文
打开 link。点击目的地必须解决 HTTPS 。 相对链接解析
不论工人在哪里被安置, 不安全按钮 URL
倒回经验证的机体链接. 缺少、畸形或不安全的身体联系,
包括 HTTP 链接,返回到 /在 HTTP 开发源上,例如
localhost, 相对链接因此也打开 /交付/开放
度量衡使用交付ID和订阅端点. 动作点击后添加
action 打开的度量衡的ID。 导航从不等待度量衡 POST;
关闭通知不会发出任何参数.
自定义数据和页面事件
开工后,工人打电话 openWindow 打开点击
目标(浏览器可能重新使用/聚焦现有窗口)。 它把点击
只有返回的同源客户,一次,匹配客户身份的准备状态
而不是 URL 所以重定向和路由器 URL 更改工作 。 其他匹配标签
无点击。 插件发送 { deliveryId, action, customData } 在一个
cio:webpush:click 窗口 CustomEvent 并点击回调. action 实值
按钮标识,或 '' 用于单击身体; customData 实值 undefined 缺席时
或畸形(每个插件实例记录一次畸形数据)。 工人
后Message类型名称是私人执行细节:
const stop = analytics.webPush!.onClick(
({ deliveryId, action, customData }) => {
console.log(deliveryId, action, customData?.orderId)
}
)
// Alternatively (do not use both unless you want both handlers):
window.addEventListener('cio:webpush:click', (event) => {
console.log(event.detail.customData)
})
// Remove a callback when its component unmounts:
stop()
发表 WebPushClickEvent, (中文(简体) ), WebPushReceivedEvent,以及 WebPushAPI 类型
包括这些 API; 窗口事件名称通过键入 WindowEventMap。 。 。 .
网页初始化期间,包括打开的目的地的登记册处理者
点击。 工人们要等十秒钟 插件准备握手
因此新打开的页面可以安装其消息的收听器. 未交接点击数据
除客户端返回外, 输入到任何标签 openWindow。如果没有可用的客户端(例如,交叉来源)
),或者插件没有及时加载,导航和公尺仍然
工作,但没有回调。 交接是最佳的,不是耐用储存.
卸载插件会删除其信件的收听者并点击回调.
交付有效载荷不能识别原始用户。 避免送出旧的 用户的飞行中数据到一个新的身份、重置或身份变化 注册抑制单击并收到该插件其余部分的交接 例如,即使在重新登记之后。 新的实例可以恢复 当前注册身份; 此守护者无法识别旧的交货 重新装入。 通知和衡量标准仍然有效。 不要在自定义数据中隐藏秘密 .
在推时,工人还通知受控的开窗客户。 插件
发送 cio:webpush:received 被洗干净 { deliveryId, title, customData }
细节,而不是原始工人有效载荷;它不会改变页UI:
window.addEventListener('cio:webpush:received', (event) => {
console.log(event.detail.deliveryId, event.detail.customData)
})
说明
工人没有分析案例:订阅费的变更只能通过 打开的页面或下一个负载。 对齐删除所存储的端点 登记替换。 仅存的遗迹没有已知的主人, 因此他们的前人设备无法安全删除.
阿尔法脚本演示
现有管道分析片段已经装入,为已建成的管道服务
packages/browser/dist/umd/webPushPlugin.min.js 并复制
packages/browser/dist/cio-webpush-sw.js 到站点根。 替换占位符 .
公共写入密钥属于分析片段; 绝不包括音轨 API
键或私人 VAPID 键。 公众片段使用 cioanalytics; 如果您设置
data-global-customerio-analytics-key,用这个名字代替.
<button id="subscribe" disabled>Enable notifications</button>
<script src="/dist/umd/webPushPlugin.min.js"></script>
<script>
const analytics = window.cioanalytics // match your snippet's global name
analytics.ready(async function () {
try {
await analytics.register(
CustomerIOWebPush.WebPushPlugin({
vapidPublicKey: '<YOUR_PUBLIC_VAPID_KEY>',
serviceWorkerUrl: '/cio-webpush-sw.js',
trackUrl: 'https://track.customer.io', // EU: https://track-eu.customer.io
})
)
await analytics.identify('<YOUR_USER_ID>')
const button = document.getElementById('subscribe')
button.disabled = false
button.onclick = function () {
analytics.webPush.subscribe().then(console.log).catch(console.error)
}
} catch (error) {
console.error(error)
}
})
</script>
yarn browser+deps build 发送UMD 捆绑 packages/browser/dist/umd/, (中文(简体) ),
静态工人及其CDN运行时间 packages/browser/dist/,和npm JS/类型
packages/browser/dist/{pkg,cjs,types}/工人船舶未建造: yarn browser test 运行它的测试 src/plugins/web-push-plugin/cio-webpush-sw.js,所以这个
不需要构建, 且如果 dist/cio-webpush-sw.js 或者说
dist/cio-webpush-sw-runtime.v1.js 它的写作与来源不同。 发布
cDN 运行时间 /v1/analytics-js/cio-webpush-sw-runtime.v1.js 与每个
,并使用
Cache-Control: no-cache (或 max-age=0: Safari 后安装更新
更新仍在运行的 HTTP 运行时间 . scripts/build-prep.sh 设置
工人的版本,它托管的拷贝与CDN的比较. 接受主机副本
只有在报告时才运行时间 api: 1 和严格更新的发行版本(有效)
semver 字符串; 预释从未安装过, 构建元数据被忽略), 添加
评估时没有收听者,并准确登记一个完整的处理器
install(env)是因为 addEventListener 在此之前 install 返回;否则,其无
收听者被注册,捆绑的复制件被安装. 听者选项是
被忽略 .
其他区域
如果你是我们 欧盟数据中心 您需要指定一个替代终点 :
import { AnalyticsBrowser } from '@customerio/cdp-analytics-browser'
const cioanalytics = AnalyticsBrowser.load({
cdnURL: 'https://cdp-eu.customer.io',
writeKey: '<YOUR_WRITE_KEY>',
})
cioanalytics.identify('hello world')