CleverTap Roku SDK
用于Roku频道的Analytics SDK,用BrightScript / SceneGraph编写。它记录事件和 识别用户,并将数据发送给CleverTap。
介绍
CleverTap将实时用户洞察、先进的细分引擎和 在一个平台中使用易于使用的营销工具,使您的团队能够创造体验 从而加深客户关系。
更多信息,请查看我们的 网站 和 文档. 要开始,先注册 在这里。
这个SDK涵盖了什么
第一个版本仅用于分析。它公开了四个调用:
recordEvent-记录自定义事件,带有可选属性。recordChargedEvent-用分项记录购买。onUserLogin-标识用户。profilePush-设置当前用户的属性。
另外8个调用更改一个概要文件属性,但不替换它。看到 配置文件命令。
两个电话可以保护隐私。看到 隐私和GDPR。
setOptOut-停止或恢复当前查看器的报告。enableDeviceNetworkInfoReporting-打开或关闭网络详细信息报告。
它也暴露了 getCleverTapID,它返回当前设备id (CleverTap id)
您可以在仪表板中将会话与其配置文件匹配。
需求
- 一个用BrightScript编写的Roku SceneGraph通道。
- 一个CleverTap账户。您的帐户ID,令牌和地区在您的CleverTap 指示板,在设置->集成下。
安装
SDK是一组BrightScript源文件和SceneGraph组件。安装时使用 ropm,是Roku频道的包管理器。
从通道的根目录(保存的文件夹)运行两个命令 manifest. ropm作品
因此,在更高一级运行它会将SDK写入到您的通道的某个位置
看不见。
npm install ropm --save-dev
npx ropm install clevertap-roku-sdk
ropm将SDK复制到 source/roku_modules/clevertaprokusdk/ 和
components/roku_modules/clevertaprokusdk/ 在你的频道里。提交这些文件夹或重新运行
npx ropm install 在您的构建中,您的团队喜欢哪个。
检查它是否着陆:
ls source/roku_modules/clevertaprokusdk
值得一做,因为 ropm install 即使没有安装,也退出0。构建步骤
只查看退出代码将继续并生成一个没有SDK的通道,并且
问题的第一个迹象是节点在运行时无法创建。这是ropm自己的最后一句话
输出是另一个告诉: ropm: Installed 1 module 而不是 ropm: No modules installed。
节点用前缀命名
Ropm为每个包提供了自己的前缀,以便两个包不能注册相同的包
组件的名称。前缀是去掉连字符的包名,所以SDK节点是
clevertaprokusdk_CleverTap,而不是 CleverTap。
该前缀仅适用于节点名称。在节点上进行的每个调用都保持其平直
名字,所以 callfunc("init", ...) 这一页下面的所有调用都写得很精确
就像它们出现在这里一样。
改为手工安装
Ropm是支持的路由,也是示例使用的路由。如果无法添加构建步骤,请复制
这个回购 source/ 和 components/ 文件夹到你自己的频道 source/ 和
components/ 文件夹。在这条路由上没有重命名任何东西,所以节点是普通的
CleverTap. 这一页上的每一行都是一样的。
集成
创建一次SDK节点,将其保存在每个组件都可以访问的地方,例如on
m.global,并初始化它。
' In your main scene's init():
ct = CreateObject("roSGNode", "clevertaprokusdk_CleverTap")
m.global.addFields({ clevertap: ct })
' Pass your credentials directly...
ct.callfunc("init", { accountId: "YOUR_ACCOUNT_ID", token: "YOUR_TOKEN", region: "in1" })
或者,不要在代码中传递凭证,而是将它们添加到您的通道中 manifest:
clevertap_account_id=YOUR_ACCOUNT_ID
clevertap_token=YOUR_TOKEN
clevertap_region=YOUR_REGION
并调用 init 使用空对象:
ct.callfunc("init", {})
在设备上设置频道
这不是特定于SDK的,但是您需要它才能看到上面的任何工作。
一个Roku频道是一个拉链 manifest 在顶层。建立它 内部 你的
Channel的根目录,或者manifest在子文件夹中结束,设备拒绝zip:
zip -r ../my-channel.zip manifest source components
将设备置于显影模式,然后打开 http://<roku-ip> 在浏览器中上传
邮政编码。启用开发人员模式的远程序列,以及如何查找设备的IP
在 sample/RUN_ON_DEVICE.md -步骤1和2适用于任何
通道,不只是样品。
要查看SDK正在做什么,请在旁路加载之前连接到调试控制台:
nc <roku-ip> 8085
与 clevertap_log_level=debug 在你的清单中,你应该看到SDK启动了:
[CleverTap] initialized, account TEST-123-4567, sdk 1.0.0
[CleverTap] event recorded: App Launched
[CleverTap] response status 200, body {"status":"success",...}
否 [CleverTap] 通常意味着缺少帐户id或令牌,这是SDK无法提供的
报告一次,然后保持不活动状态。
用法
初始化后,通过存储的节点从渲染线程的任何位置调用SDK:
ct = m.global.clevertap
' Identify a user
ct.callfunc("onUserLogin", [{ "Identity": "u123", "Email": "[email protected]", "Name": "Sam" }])
' Set attributes on the current user
ct.callfunc("profilePush", [{ "Name": "Sam", "plan": "pro", "favTeam": "IND" }])
' Record an event, with optional properties
ct.callfunc("recordEvent", ["Product viewed", { "id": 42, "name": "Bat" }])
' Record a purchase with line items
ct.callfunc("recordChargedEvent", [{ "Amount": 300 }, [{ "id": 1 }, { "id": 2 }]])
' Get the current CleverTap device id (the CleverTap ID)
ctId = ct.callfunc("getCleverTapID", invalid)
init 取一个地图,每隔一次调用取一个列表
这两行看起来不一致,区别很容易被忽略:
ct.callfunc("init", { accountId: "...", token: "..." }) ' a map, passed as it is
ct.callfunc("recordEvent", ["Product viewed", { "id": 42 }]) ' a list of arguments
init 直接交给您的配置映射。每隔一个电话就有一个 保存其
参数顺序, SDK将其解压缩。
接受一个参数的调用仍然接受一个参数列表。 profilePush 希望
[profileFields],而不是 profileFields:
ct.callfunc("profilePush", [{ "Name": "Sam" }]) ' right
ct.callfunc("profilePush", { "Name": "Sam" }) ' wrong
不带任何参数的调用被传递 invalid,因为 getCleverTapID 是上面。
没有什么能在构建时阻止你,因为 callfunc 之前不会检查名称和参数
这条线很长。传递list所属的map会失败,并出现以下错误:
Associative array indexes must be strings
SDK将第一个参数读取为 args[0]而地图是不能这样看的。调用
从未发生过,因此事件或概要文件更改根本不会被记录。
始终将属性键写在引号中
上面的每个键都在引号中。这对Roku很重要。
里面没有引号的键 { } 是BrightScript的标识符,而BrightScript
标识符不区分大小写,因此设备以小写存储键。 { Amount: 300 }
变成了 { amount: 300 } 在SDK看到它之前,原始拼写就消失了。
CleverTap完全匹配保留的名称。 Amount 是购买价值。 amount 是一个
普通的海关财产,并没有购买申报收入。这同样适用于
Identity, Name, Email, Phone 以及其他配置字段。
没有任何失败,所以这很容易错过。SDK报告一个看起来像保留名称的键 拼写错误:
[CleverTap] ERROR charge detail 'amount' is sent as a custom property. The server reads it as
'Amount' only when it is spelled that way. Write the key in quotes: { "Amount": ... }
引用每个关键字是避免整个问题的简单规则。
日期
DOB, Birthday 任何自定义属性都可以保存日期。把日期写在地图上
键, date. 该值可以是ISO 8601日期和时间,也可以是秒数
1970年1月1日:
ct.callfunc("profilePush", [{ "DOB": { "date": "1990-04-17T00:00:00Z" } }])
ct.callfunc("profilePush", [{ "DOB": { "date": 640310400 } }])
两行发送相同的内容。在导线上,值变成 "$D_640310400":数目
从1970年1月1日开始的秒数,后面有一个前缀,将值标记为日期。
1970年1月1日之前的日期是负的秒计数,其工作原理相同。3月3日
1965发送为 "$D_-152496000"。
用a书写ISO 8601日期 T 在日期和时间之间,如上所述。一次约会
设备无法读取报告并被遗漏,因此如果日期没有到达,请检查控制台。
event属性也可以是一个日期:
ct.callfunc("recordEvent", ["Watched", { "airedOn": { "date": 640310400 } }])
SDK会查看地图和列表,所以无论你在哪里写日期都能找到。线 购买的物品是一张地图列表,其中一张地图中的日期也是如此:
ct.callfunc("recordChargedEvent", [
{ "Amount": 300, "boughtOn": { "date": 640310400 } },
[{ "id": 1, "name": "Match ticket", "airedOn": { "date": 640310400 } }]
])
搜索分为三级,包括地图和列表。嵌套更深的值 它没有嵌套在里面的部件,写在上面的日期仍然是一张地图 而不是成为约会对象。SDK是这样说的:
[CleverTap] ERROR 'a.b.c.d' is nested more than 3 levels deep. Its own values were sent, and
anything nested inside it was left out. A date written this deep is not converted.
三级限制也是使错误便宜的原因。一张地图可以被制作成自己的样子;
show = {}
show["self"] = show ' don't do this
Roku的JSON写入器拒绝这样的值。如果没有这个限制,一个这样的属性就会 使设备上等待的每个事件都不可发送。SDK复制你给它的东西,所以a 保值的价值只会花掉你那一处房产。
为什么是地图而不是 roDateTime。 BrightScript有一个date对象, roDateTime但是你呢?
不能将其交给SDK。每个调用都通过 callfunc,还有
roDateTime 不能在电话中幸存。它的到来是虚无。地图确实保存了下来,这是
为什么日期写成1。
任何带a的地图 date 在SDK将其视为嵌套之前,key被读取为日期
数据。该地图包含的任何其他内容都将被删除,因此为日期提供一个自己的地图。
一个数字本身就是 不 作为日期阅读:
' Stored as the number 640310400, not as a date.
ct.callfunc("profilePush", [{ "DOB": 640310400 }])
SDK无法将第二个计数与分数或价格区分开来,所以它只留下一个简单的数字 独自一人。当你想要约会的时候就用地图。
设备无法读取的日期将从请求中删除并报告。它不是作为 1970年1月1日,它不能取代CleverTap已经保存的日期:
[CleverTap] ERROR date for 'DOB' could not be read from '17 April 1990', so it was left out.
Write the date as "1990-04-17T00:00:00Z", with a T between the date and the time.
嵌套的属性
属性可以保存映射或列表,而不仅仅是单个值。SDK会发送整个内容:
ct.callfunc("recordEvent", ["Product viewed", {
"id": 42
"show": {
"title": "Final over"
"airedOn": { "date": 640310400 }
"teams": ["IND", "AUS"]
}
}])
必须为您的帐户启用嵌套。 SDK发送一个嵌套的值, 但CleverTap只会在启用该功能后存储数据。事件属性和概要 属性是单独打开的,所以如果您需要这两个属性,请向CleverTap团队询问。 在此之前,请求仍然成功,控制台仍然显示嵌套的有效负载发出, 值在到达时被丢弃。两端都没有记录,所以唯一的标志是 数据永远不会到达仪表盘。
一旦开启,CleverTap就会将你发送的内容扁平化。它不保留巢。每个值
Inside变成了它自己的属性,由它所在的路径命名,map本身不是
你可以报道的财产。这个 show 上面的Map作为三个属性到达,旁边是
平 id:
show.title Final over
show.airedOn 17/04/1990
show.teams IND, AUS
列表将其位置添加到名称中,因此 teams[0].city 列表中的map是什么
调用。根据这些名称构建仪表板报告。
有两件事没有包括在内。购买被忽略了:CleverTap不会使任何东西变平
在一个 Charged 事件,因此将购买的行项保持平面并放置嵌套数据
你自己的事。日期不会受到任何影响,因为它之前不再是地图
它离开设备——它以纯文本的形式传播,并以日期的形式出现在你写的任何地方。
嵌套限制与日期搜索使用的三层相同,计算映射并列出 同样的方式。
电话号码
把电话号码用引号括起来,并加一个前导 + 国家代码:
ct.callfunc("profilePush", [{ "Phone": "+14155550123" }])
没有A的数字 + 当设备报告国家时仍然有效,因为CleverTap
从那里开始。一些Roku账户没有报告国家,然后是一个没有
+ 无法完成。SDK报告这种情况并发送号码:
[CleverTap] ERROR Phone '4155550123' carries no country code, and this device reports no
country either. The server may not be able to use the number.
把数字写成文本。 { "Phone": 14155550123 } 是一个数字,而一个数字不能装一个
领先的 + 或者是前导0。SDK也会报告这一点。
SDK永远不会改变或丢失电话号码。只有你的应用知道它的意思,所以两者都知道 检查是报告。
配置文件命令
profilePush 替换键的值。下面的调用更改值的一部分
相反,您不必先读取旧值。
ct = m.global.clevertap
' Remove a property from the profile
ct.callfunc("profileRemoveValueForKey", ["plan"])
' Replace the whole list of a multi-value property
ct.callfunc("profileSetMultiValues", ["favTeams", ["IND", "AUS"]])
' Put values into that list
ct.callfunc("profileAddMultiValue", ["favTeams", "ENG"])
ct.callfunc("profileAddMultiValues", ["favTeams", ["NZ", "SA"]])
' Take values out of that list
ct.callfunc("profileRemoveMultiValue", ["favTeams", "AUS"])
ct.callfunc("profileRemoveMultiValues", ["favTeams", ["NZ", "SA"]])
' Move a number property up or down
ct.callfunc("profileIncrementValueBy", ["points", 50])
ct.callfunc("profileDecrementValueBy", ["points", 20])
它们中的每一个都以相同的顺序接受参数:首先是属性名,然后是 价值。
以下是一些值得了解的规则:
- 多值属性保存文本。你传递的数字会被转换成文本,所以
5存储 作为"5". 一个属性最多保留100个值,超过这个值的任何值都将被删除。 - 增量或减量的金额必须大于零。要降低一个值,请使用
profileDecrementValueBy而不是负数。 - SDK不保留配置文件的副本,因此它不会将命令与当前值合并。 它发送命令,然后CleverTap应用它。这也意味着没有办法读取a 属性返回到设备上。
- 具有错误属性名称或错误值的调用将被丢弃并记录。没有别的了。 影响队列。
隐私和GDPR
压制权-选择退出
观众可以要求不被举报。那么,你的应用程序在自己的设置中提供了这种选择 告诉SDK:
' Stop reporting this viewer.
clevertap.callfunc("setOptOut", [true])
' Report this viewer again.
clevertap.callfunc("setOptOut", [false])
当一个观众被选择退出时,什么也不会发送。您记录的事件在被删除之前被删除 排队,所以它们也不会坐在设备上等待。
有一个中间设置。传递第二个参数来保留SDK自己的记账事件 流动,而你记录的一切仍然下降:
clevertap.callfunc("setOptOut", [true, true])
此SDK发送的唯一此类事件是 App Launched,它会告诉CleverTap一个会话
开始了。没有它,服务器上的会话永远不会关闭。当观众要求不要这样做时,使用这个
被跟踪,但你仍然需要使用数据,没有名字。购买是 不 治疗
作为记账事件,所以 recordChargedEvent 在任意设置下都被丢弃。
| 你记录一个事件 | recordChargedEvent | App Launched | 配置文件修改 | |
|---|---|---|---|---|
| 选择加入(默认) | 发送 | 发送 | 发送 | 发送 |
[true, true] | 下降了 | 下降了 | 发送 | 发送 |
[true] | 下降了 | 下降了 | 下降了 | 下降了 |
SDK将选择作为配置文件属性发送给CleverTap,因此活动建立在 服务器也被抑制。然后,它将选择保留在设备上,而不是观看者的选择 CleverTap ID。观看者不必在下次发射时再次选择退出,并且观看者签名 退出和回归仍然是选择退出。
默认情况下,SDK报告,选择退出为false。你的应用程序仍然是答案所在
真正的生活,如此召唤 setOptOut 在每次发射时都存储答案是很好的做法。
设备网络信息
SDK不会报告任何有关网络的信息,并告诉CleverTap不要计算出a在哪里 查看器来自请求来源的地址。要打开它:
clevertap.callfunc("enableDeviceNetworkInfoReporting", [true])
这将增加设备是否连接WiFi而不是电缆,并让CleverTap读取数据 请求地址的大致位置。Roku设备没有移动无线电,所以不像 移动sdk没有运营商或移动网络上报。
这是关闭的,除非你打开它,并设置保持在设备上。
营销选择退出
要将查看者从所有营销渠道中移除,请在其配置文件中设置这些属性。这 无需特别呼叫:
clevertap.callfunc("profilePush", [{
"MSG-email": false
"MSG-push": false
"MSG-sms": false
"MSG-push-all": false
}])
默认情况下,每个通道都是可用的。
样品通道
可运行的样本存在于 sample/. 它启动SDK并显示其中的一个菜单
电话;选择一行并按OK以触发该调用,然后检查CleverTap仪表板。看到
sample/README.md 如何组装和侧装。
发展
将从源代码构建SDK并运行其测试 DEVELOPMENT.md。
许可证
MIT,在 package.json。