clevertap-roku-sdk

中文文档
1.0.0发布于 2026/11/03MIT零依赖

CleverTap SDK for Roku (BrightScript / SceneGraph) -分析:recordEvent, recordChargedEvent, onUserLogin, profilePush。

中文使用文档
文档目录22 节
  1. 介绍
  2. 这个SDK涵盖了什么
  3. 需求
  4. 安装
  5. 节点用前缀命名
  6. 改为手工安装
  7. 集成
  8. 在设备上设置频道
  9. 用法
  10. init 取一个地图,每隔一次调用取一个列表
  11. 始终将属性键写在引号中
  12. 日期
  13. 嵌套的属性
  14. 电话号码
  15. 配置文件命令
  16. 隐私和GDPR
  17. 压制权-选择退出
  18. 设备网络信息
  19. 营销选择退出
  20. 样品通道
  21. 发展
  22. 许可证

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 在任意设置下都被丢弃。

你记录一个事件recordChargedEventApp 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。

版本与发布记录

clevertap-roku-sdk 共发布 2 个版本,首次发布于 2026/11/03;过去 12 个月发布了 2 个版本。

版本发布日期距今
1.0.0latest2026/11/03今天
0.0.0-stage2026/11/03今天

关于 clevertap-roku-sdk 的常见问题

clevertap-roku-sdk 是什么?

CleverTap SDK for Roku (BrightScript / SceneGraph) -分析:recordEvent, recordChargedEvent, onUserLogin, profilePush。

如何安装 clevertap-roku-sdk?

在项目目录运行 npm install clevertap-roku-sdk,或使用 pnpm add / yarn add / bun add。

clevertap-roku-sdk 支持 TypeScript 吗?

该包的 package.json 没有声明类型入口。需要类型提示时,可以在 npm 上查找社区维护的 @types/clevertap-roku-sdk 是否存在。

clevertap-roku-sdk 可以商用吗?

clevertap-roku-sdk 使用 MIT 许可。宽松许可:允许商业使用、修改和再分发,通常只需在分发时保留原版权与许可声明。以上为概括,不构成法律意见,请以许可原文为准。

clevertap-roku-sdk 还在维护吗?

最新版本 1.0.0 发布于 2026/11/03(今天);至今共发布 2 个版本,其中过去 12 个月发布了 2 个;首次发布于 2026/11/03。发布频率只是参考信号:功能稳定的工具可能很少需要更新,建议结合源码仓库的 issue 和提交记录判断。