Roku SDK
This guide explains how to integrate an MTRIBES Space into your Roku application.
You'll learn how to synchronize changes from your Space into your codebase using our CLI's code generation, and how to use this code to control the UX of your end users.
Sample apps
Check out our sample app covering BrightScript to fast-track your integration.
#
Requirements- A Roku SceneGraph project ready to integrate with MTRIBES
- An MTRIBES Space with at least one Collection and Experience
- The MTRIBES CLI installed
- Roku SceneGraph code generated for your Space
Our SDK is designed for use in Roku SceneGraph applications that use rsg_version=1.2
in
their 'manifest' file and are ready to work with Roku OS version 9.2 and higher
#
Code integrationWith your Space code generated, you're ready to integrate MTRIBES into your Roku SceneGraph application.
In the code examples which follow, we'll build out an example Space containing:
- A
homepage
Collection, which contains:- A
banner
Experience - A
body
Section, which supports:Hero
Experience typesCarousel
Experience types
- A
The generated code is output to ./src/mtspace/example
Don't worry if this isn't clear yet, as it will make more sense after we run through some examples.
To integrate our Roku SDK, first create a single MTRIBES instance using global scope.
function initialize() createObject("roSGNode", "Mtribes")end function
Once created, the instance will be available at m.global.mtribes
, where it's public contract gives you access
to all available features.
#
Client configurationThe MTRIBES Client
is a top-level object for configuring your MTRIBES SDK.
A Client
instance is generated along with your Mtribes
instance and can be accessed via the
global app scope.
client = m.global.mtribes.client
Defaults are sensible, but can be overridden to further harmonize MTRIBES with your application.
Example: Disable session locking to enable Section and Experience change events during a user session.
m.global.mtribes.client.sessionLock = false;
It's best to configure the Client before starting the session, but configuration can be adjusted at anytime.
See a full list of available configuration properties in the Client API reference.
#
Session startBefore accessing an Experience, it's important to start a session for the active user, so we can serve them personalized states.
We represent an MTRIBES session via the session
object, which you can access via the global app
scope.
session = m.global.mtribes.session
#
Anonymous userStart a session for an anonymous user.
m.global.mtribes.session.callFunc("start").observeFieldScoped("result", "render")
function render() ' make UI updates here according to new user statusend render
This should be done:
- on app launch if the user is anonymous
- when a user logs out
It's important to wait for the completion of start()
before accessing Experiences and Sections.
#
Logged in userStarting a session for a logged in user is similar to an anonymous one, except you must provide their unique identifier.
m.global.mtribes.session.callFunc("start", {userId: user.id}).observeFieldScoped("result", "render")
function render() ' make UI updates here according to new user statusend render
This should be done:
- on app launch if the user is already logged in
- when a user logs in
Again, wait for the completion of start()
before accessing Experiences and Sections.
Note
- User Id passed to SDK has to be consistent across all the devices/platforms.
- User Id passed should be attached to a same user for at least 30days.
Personal Information
A user ID should be opaque and not personally identifiable. For example, you should avoid email addresses, social security numbers or similarly personal information.
If you don't have an opaque ID for a user, you can use a secure hashing algorithm such as
SHA256 to encode it before passing it to session.start
.
#
Contextual propertiesWhen starting a session, you can also provide fields with values specific to the user. These open up powerful Tribe targeting options in the MTRIBES platform.
Example 1: Start a session for an anonymous user with a contextual property of campaign
.
m.global.mtribes.session.callFunc("start", { fields: { "campaign": campaignId }}).observeFieldScoped("result", "render")
function render() ' make UI updates here according to new user statusend render
Example 2: Start a session for a logged in user with a contextual property of subscription
.
m.global.mtribes.session.callFunc("start", {userId: user.id, fields: { "subscription": user.subscription }}).observeFieldScoped("result", "render")
function render() ' make UI updates here according to new user statusend render
Example 3: Start a session for a logged in user with a boolean, number and date property (date property should be in this format "YYYY-MM-DDTHH:MM:SSZ" - that is a standard output of "toIsoString()" method of "roDateTime" object ).
m.global.mtribes.session.callFunc("start", {userId: user.id, fields: { "isSuperUser": true "accessLevel": 2 "date": createObject("roDateTime").toIsoString() }}).observeFieldScoped("result", "render")
function render() ' make UI updates here according to new user statusend render
We currently support the following contextual property types.
roBoolean
:true
orfalse
roInt/roDouble
: e.g.842
,0.332
roString
: e.g."gold"
roDateTime
: ISO-8601 UTC string encoded timestamp e.g."2020-12-02T02:45:02.076Z"
This must include the date and time.
Property Limits
A maximum of 50 contextual properties can be active at one time. You can remove unused properties to make room for new ones in the contextual property settings page.
To avoid exceeding these limits or sending PII by mistake, we recommend selecting specific contextual properties to include when starting a session.
#
Experience accessWith the session primed, you can now check whether Experiences modeled in the Space are enabled for a user, and if so, what custom data properties have been defined for them.
function access() ' access the banner Experience from the homepage Collection m.banner = m.global.mtribes.collections.homepage.bannerend function
function renderBanner() ' only render the banner Experience if it's enabled if m.banner.callFunc("enabled") then ' access customized data for the banner imageURL = m.banner.callFunc("data").imageURL drawBanner(imageURL) end ifend function
#
Section iterationSections contain a list of child Experiences defined at runtime by a Scheduler in the MTRIBES platform. You can iterate over these child Experiences and render each in turn, depending on its type.
Each Section defines its supported
Experience types. You can use these as switch cases and render
appropriately given an Experience kind
.
function renderBody() ' access the body Section from the homepage Collection body = m.global.mtribes.collections.homepage.body bodyChildren = body.children supported = body.supported ' render each Experience of the Section in order for i = 0 to bodyChildren.count() - 1 exp = bodyChildren[i] if exp.isSubtype(supported.Hero) then drawHero(exp.callFunc("data")) else if exp.isSubtype(supported.Carousel) then drawCarousel(exp.callFunc("data")) end if end forend function
#
Change eventsThe state of an Experience or Section may change for a user during their session. You can monitor these changes and reflect them in your code.
Live updates
If you want published change events to fire during a user's session, then you'll need to set
Client.sessionLock to false
. By default, session locking is enabled to avoid
published changes negatively impacting UX.
function monitorChanges() ' access the members of the homepage Collection m.banner = m.global.mtribes.collections.homepage.banner m.body = m.global.mtribes.collections.homepage.body
' add observers for changes of "banner" and "body" m.banner.observeFieldScoped("changed", "renderBanner") m.body.observeFieldScoped("changed", "renderBody")end function
function renderBanner(message as object) data = m.banner.callFunc("data")end function
function renderBody(message as object) children = m.body.childrenend function
#
Behavior trackingTo help you gather user analytical behavioral patterns associated with an Experience, we expose a
track
function.
Analytic events support a Category
and Action
to help with event classification. These
properties are encoded as a string in the format <category>/<action>
. If only <action>
is
provided, a default Category of user
is assumed.
Here are a few examples from our banner Experience above.
function trackEvents() ' access the banner Experience from the homepage Collection banner = m.global.mtribes.collections.homepage.banner ' track an ad viewed event ' category 'advert', action 'viewed' banner.callFunc("track", "advert/viewed") ' track a signed in event ' category 'user' (default), action 'signed_in' banner.callFunc("track", "signed_in") ' optional details can be provided including ' a contextual label and integer value banner.callFunc("track", "item/clicked", {label:"Winter Specials", value: 1})end function
#
Trusted IdentityTrusted Identity helps ensure the authenticity of users identified into your MTRIBES Space. View our comprehensive Trusted Identity guide to understand what this is and how to enable it.
Once you have a hashed user signature returned from your server, you should pass this as an option when starting a session for a logged in user.
function onLogin(user, signature) m.global.mtribes.session.callFunc("start", { userId: user.id, options: { signed: signature } }).observeFieldScoped("result", "render")end function
function render() ' make UI updates here according to new user statusend render