Roku
Configuration guide for the Recurly Engage Roku SDK, which enables native prompt display and usage tracking in your Roku applications.
Overview
The Recurly Engage Roku SDK provides the ability to monitor consumption and show configured prompts within your native Roku app. The SDK automatically handles prompt display and user-triggered events.
Key benefits
- Seamless integration: Easily add prompt functionality to your Roku apps via the Roku SceneGraph SDK.
- Automatic event handling: Built-in support for prompt display, button clicks, and lifecycle events without extra UI code.
- Flexible triggers: Activate prompts by screen name or button click to fit your application flow.
Key details
Install the SDK
Download the latest Roku SDK (v1.0.35) with Roku Pay support here and without Roku Pay support here. A demo app featuring an example integration can be provided by request.
To build a project using the RedFast SDK for Roku, your project must have been built with the Scenegraph SDK.
Unzip the SDK into the app components
directory.
Initialize SDK
- Initialize the SDK within the main scene XML (initial screen) file.
< PromotionManager id="promoMgr" />
- Within the main scene BrightScript (.brs) file, add the following lines into the
sub init()
function and specify the values for the appId and userId. The userId may be changed later on.
sub init()
' other app initialization code here
' optionally specify cta-button and timer countdown fonts
ctaF = CreateObject("roSGNode", "Font")
ctaF.uri = "pkg:/fonts/Roboto-Regular.ttf"
ctaF.size = 16
timeoutF = CreateObject("roSGNode", "Font")
timeoutF.uri = "pkg:/fonts/Roboto-Regular.ttf"
timeoutF.size = 16
m.promoMgr = m.top.GetScene().findNode("promoMgr") ' or m.top.findNode("promoMgr")
print m.promoMgr.callFunc("getVersion") ' lookup current SDK version
m.promoMgr.observeField("result", "onInitialized")
' appId argument is required, all others are optional
m.promoMgr.callFunc("initPromotion", {appId: "[YOUR APP ID]", userId: "[USER ID]", annonymousUserId: "[ANON USER ID]", ctaFont: ctaF, timeoutFont: timeoutF})
end sub
sub onInitialized()
m.promoMgr.unobserveField("result")
m.sceneStack = m.top.findNode("sceneStack")
scene = createObject("RoSGNode", "[YOUR FIRST SCREEN OF THE APP]")
m.sceneStack.appendChild(scene)
end sub
Note that it may take a few seconds after app start for the SDK initialization to complete, after which prompts will be available to present to the user.
Set UserId
You may change the userId after the SDK has been initialized. The function will return instantly, however all prompts relevant to the updated userId may take a few seconds to be ready.
m.promoMgr.callFunc("setUserId", {userId: "[new user id]"})
Set AnonymousUserId
The anonymousUserId may be updated after the SDK has been initialized. If not set, a randomly generated UUID will be assigned to the user.
m.promoMgr.callFunc("setAnonymousUserId", {userId: "[new anon user id]"})
Trigger modal via screen name
You may utilize the Redfast SDK to display a modal on a specified screen. If the prompt also requires a button click, the trigger will not occur until the associated onButtonClicked
function is called.
Add the following line in the screen init function:
sub init()
...
m.promoMgr = m.top.GetScene().findNode("promoMgr")
// Make sure a callback function is registed (and registed for only once) here to receive any status from m.promoMgr
// A sample onPromotionEvent is provided in the next section
m.promoMgr.observeField("result", "onPromotionEvent")
m.promoMgr.callFunc("onScreenChanged", {root: m.viewRoot, screenName: "ViewController" })
...
end sub
Ensure that you add an event listener before calling any function on m.promoMgr
so that you can observe the result from a screen change, button click, popup and inline item:
m.promoMgr.observeField("result", "onPromotionEvent")
Trigger modal via button click
The sample code below demonstrates:
- Tracking a button click event
- Displaying a modal if applicable to the button.
Note that a previous onScreenChanged
call is required if the prompt trigger is configured to be invoked only when the button click occurs on a specified screen name.
sub onButtonClicked()
m.promoMgr.callFunc("onButtonClicked", {root: m.viewRoot 'the root component of the screen, id: "[Optional button ID]"})
end sub
'Note: If the prompt is displayed and dismissed, the result will be passed back to:
sub onModalDismissed()
if m.promoMgr.result.value = 101 'button1
dialog = createObject("roSGNode", "Dialog")
dialog.title = "Thank you"
dialog.optionsDialog = true
dialog.message = "Thanks for accepting"
m.top.dialog = dialog
end if
end sub
' Note: The full set of status codes can be found in the SDK `const.brs` file:
' Success codes
m.ok = 1
' Error codes
m.error = -100
m.notApplicable = -101
m.disabled = -102
m.suppressed = -103
' Interactions
m.impression = 100
m.button1 = 101
m.button2 = 102
m.button3 = 103
m.dismissed = 110
m.timerExpired = 111
m.holdout = 120
Show modal via manual trigger
A prompt may triggered manually if triggering via Screen Name or Button Click is not desired.
prompt = m.promoMgr.callFunc("getPrompt", {pathId: "myPathId"})
m.promoMgr.callFunc("showPrompt", {root: m.viewRoot, prompt: prompt})
Retrieve inline prompts
The SDK provides a method to retrieve inline prompts within the specified Zone ID that are eligible for the current userId. You may access the properties of the inline prompts to render in the appropriate locations within the app.
inlineItems = m.promoMgr.callFunc("getInlines", {type: "myZoneId"})
The following is example code demonstrating accessing attributes of the prompt for rendering. A full list of attributes can be found here.
featured = createObject("RoSGNode", "ContentNode")
di = CreateObject("roDeviceInfo")
displaySize = di.GetDisplaySize()
for ii = 0 To inlineItems.count() - 1
item = featured.createChild("ContentNode")
inlineItem = inlineItems[ii]
heightSuffix = ""
if displaySize.h = 480
heightSuffix = "&screen_size=480"
else if displaySize.h = 720
heightSuffix = "&screen_size=720"
end if
item.HDPOSTERURL = inlineItem.actions.rf_settings_bg_image_roku_os_tv_composite + heightSuffix
item.Title = inlineItem.actions.rf_retention_title
item.Message = inlineItem.actions.rf_retention_message
item.Description = inlineItem.actions.rf_settings_roku_product_operation
item.ButtonText = inlineItem.actions.rf_retention_confirm_button_text
end for
featured.title = "Featured"
contentNode.insertChild(featured, 2)
Note: prompt interactions for inline prompts must be reported within your application code.
' Report impression when inline prompt is viewed
promoMgr.onInlineViewed(inlineItem)
' Report click
promoMgr.onInlineClicked(inlineItem)
' Report dismiss
promoMgr.onInlineDismissed(inlineItem)
Respond to prompt interactions
A PromptResult object is returned upon any prompt interaction performed by the user.
The PromptResult schema includes the following properties:
- code: Interaction code (ex: 100 for impression, 101 for button1 click)
- meta: Device Metadata specified within the prompt
- promptMeta
- promptName
- promptID
- promptType
- promptVariationName
- promptVariationID
- promptExperimentName
- promptExperimentID
- buttonLabel
' Observe Prompt Interactions
m.promoMgr.observeField("result", "onPromptResult")
' Perform actions on resulting interaction
sub onPromptResult()
' Call custom sendAnalytics() function
sendAnalytics(m.promoMgr.result)
' Kick off Roku Pay flow for specified SKU if specified
if m.promoMgr.result.roku <> invalid and m.promoMgr.result.roku <> ""
m.promoMgr.callFunc("purchaseIap", {sku: m.promoMgr.result.roku, qty: 1})
else
if m.modal.visible
m.detail.setFocus(true)
else
m.home.setFocus(true)
end if
end if
end sub
Send usage tracking event
Your app can report custom tracker events through the SDK. If configured as a tracker within Pulse, these custom events can be used to target prompts at specific sets of users. The custom tracker must first be created within the Redfast console so that the customFieldId
value may be retrieved.
m.promoMgr.callFunc("customTrack", {customFieldId: "my-usage-event"})
Deep link to a media asset
Invoke the Roku app deep linking functionality by specifying the mediaType and contentId for the prompt in the Redfast console. When the user invokes the CTA on the prompt, you may utilize these parameters to send the user to a specific media asset within the app. The following is an example on how to invoke deep linking after the user invokes the call to action.
sub onPromotionEvent()
if m.promoMgr.result.value = 0 // m.accepted from `const.brs` file
deeplink = m.promoMgr.result.extra.deeplink
[your deeplink handler function](deeplink)
end if
end sub
Access device metadata
Device key-value pair metadata can be added to an Prompt via the Redfast console. The app will receive these values per the examples below. These values may be used to perform an action that is not the typical media asset deep link, like sending the user to a registration screen.
Popup
When a popup is dismissed by either an Accept, Decline, or Timeout action by the user, the custom metadata will be saved in the extra.meta
field.
sub onPromotionEvent()
metadata = m.promoMgr.result.extra.meta
end sub
Inline item
When the onInlineClicked
API is invoked with the current selected inline item:
sub onPromotionEvent()
metadata = m.promoMgr.result.extra.meta
end sub
Disable SDK
There may be cases in which the Redfast SDK should be temporarily disabled for the current session. When disabled, popups are not triggered, and API communication between the SDK and Redfast servers are paused.
// To disable
m.promoMgr.callFunc("enablePromotion", {enabled: false})
// To re-enable
m.promoMgr.callFunc("enablePromotion", {enabled: true})
Debug view
The SDK provides a debug view modal in which you can use the onscreen keyboard to either reset all prompts for the current user or set a new userId.
To trigger the debug view for a specific screen, add the DebugView
component and connect it to a local variable on the screen,
<DebugView id="debugView" />
m.debugView = m.top.findNode("debugView")
In the screen's onKeyEvent
function:
m.debugView.callFunc("onKeyDetection", {key: key, screen: m.top})
When the *
key on the remote control is pressed, the debug view will be displayed.
Updated 2 days ago