Rendezvous style registration has the benefit of not requiring the user to type information directly into the channel using an on-screen keyboard. The downside is that the user may have to move to a different room to access the website and enter the code. In a future tutorial, we will look at the method where the user directly enters their username and password into the channel.
The first step in a rendezvous style registration is for the channel to request a linking code from your API. When your API receives that request, it should generate a new linking code and store it along with an expiration timestamp that is some reasonable amount of time in the future. Linking codes should be unique enough that no other device will be assigned the same code before the code has expired.
In the simplest case, the API can respond with the newly generated linking code and a timestamp indicating when the code expires. The API response to this request might look like this:
<apiResponse> <linkingCode expires="1310598793">ABC123</linkingCode> </apiResponse>
To make the API request in BrighScript and extract the linking code, your channel would have a function similar to this one:
function GetLinkingCode()
result = invalid
xfer = CreateObject("roURLTransfer")
xfer.SetURL("http://api.example.com/getLinkingCode")
response = xfer.GetToString()
xml = CreateObject("roXMLElement")
if xml.Parse(response)
result = {
code: xml.linkingCode.GetText()
expires: StrToI(xml.linkingCode@expires)
}
end if
return result
end function
When the user validates their linking code, the API should generate a unique token for the device and store that token along with its association to the user’s account. This token will be stored by the channel in the Roku’s registry and used to identify the device to the API during future sessions.
While the registration screen is visible, the channel should periodically poll the API to find out whether the user has validated their linking code and to retrieve the associated token. A successful API response to this request might look like this:
<apiResponse> <status>success</status> <deviceToken>3F2504E0-4F89-11D3-9A0C-0305E82C3301</deviceToken> </apiResponse>
The API may also respond to the polling request with a failure status if the user has not yet validated the linking code or the linking code has expired or some other error occurs. That response might look like this:
<apiResponse> <status>failure</status> </apiResponse>
To make this API request in BrightScript and process the result, your channel might implement a function similar to the following. This function will poll the API to check whether the linking code has been validated. If the code has been validated, it saves the associated token in the registry for future use. The function returns a boolean value indicating whether the linking code has been validated.
function ValidateLinkingCode(linkingCode)
result = false
xfer = CreateObject("roURLTransfer")
xfer.SetURL("http://api.example.com/validateLinkingCode?code=" + linkingCode)
response = xfer.GetToString()
xml = CreateObject("roXMLElement")
if xml.Parse(response)
if UCase(xml.status.GetText()) = "SUCCESS"
sec = CreateObject("roRegistrySection", "mySection")
sec.Write("deviceToken", xml.deviceToken.GetText())
sec.Flush()
result = true
end if
end if
return result
end function
With these two functions, you are ready to build your channel’s rendezvous linking experience. This chunk of BrightScript will get a linking code from the API, display it on a roCodeRegistrationScreen, and then start polling the API waiting for the linking code to be validated. Once the code has been validated, the screen will close.
sub ShowLinkScreen()
dt = CreateObject("roDateTime")
' create a roCodeRegistrationScreen and assign it a roMessagePort
port = CreateObject("roMessagePort")
screen = CreateObject("roCodeRegistrationScreen")
screen.SetMessagePort(port)
' add some header text
screen.AddHeaderText("Link Your Account")
' add some buttons
screen.AddButton(1, "Get new code")
screen.AddButton(2, "Back")
' Add a short narrative explaining what this screen is
screen.AddParagraph("Before you can use this channel, you must link the channel to your account.")
' Focal text should give specific instructions to the user
screen.AddFocalText("Go to http://www.example.com/roku, log into your account, and enter the following code.", "spacing-normal")
' display a retrieving message until we get a linking code
screen.SetRegistrationCode("Retrieving...")
screen.Show()
' get a new code
linkingCode = GetLinkingCode()
if linkingCode <> invalid
screen.SetRegistrationCode(linkingCode.code)
else
screen.SetRegistrationCode("Failed to get code...")
end if
screen.Show()
while true
' we want to poll the API every 15 seconds for validation,
' so set a 15000 millisecond timeout on the Wait()
msg = Wait(15000, screen.GetMessagePort())
if msg = invalid
' poll the API for validation
if ValidateLinkingCode(linkingCode.code)
' if validation succeeded, close the screen
exit while
end if
dt.Mark()
if dt.AsSeconds() > linkingCode.expires
' the code expired. display a message, then get a new one
d = CreateObject("roMessageDialog")
dPort = CreateObject("roMessagePort")
d.SetMessagePort(dPort)
d.SetTitle("Code Expired")
d.SetText("This code has expired. Press OK to get a new one")
d.AddButton(1, "OK")
d.Show()
Wait(0, dPort)
d.Close()
screen.SetRegistrationCode("Retrieving...")
screen.Show()
linkingCode = GetLinkingCode()
if linkingCode <> invalid
screen.SetRegistrationCode(linkingCode.code)
else
screen.SetRegistrationCode("Failed to get code...")
end if
screen.Show()
end if
else if type(msg) = "roCodeRegistrationScreenEvent"
if msg.isScreenClosed()
exit while
else if msg.isButtonPressed()
if msg.GetIndex() = 1
' the user wants a new code
code = GetLinkingCode()
linkingCode = GetLinkingCode()
if linkingCode <> invalid
screen.SetRegistrationCode(linkingCode.code)
else
screen.SetRegistrationCode("Failed to get code...")
end if
screen.Show()
else if msg.GetIndex() = 2
' the user wants to close the screen
exit while
end if
end if
end if
end while
screen.Close()
end sub
Once the channel is successfully linked with your API, the device token will be stored in the Roku’s registry. By including the device token in subsequent API requests, your API will be able to associate the channel with the user’s account and provide the channel with appropriate data.
Pingback: Logging Into an Online Account | Developer Blog