{"id":21478294,"url":"https://github.com/appsflyersdk/appsflyer-roku-sample-app","last_synced_at":"2026-03-19T20:33:48.687Z","repository":{"id":154207311,"uuid":"614107633","full_name":"AppsFlyerSDK/appsflyer-roku-sample-app","owner":"AppsFlyerSDK","description":null,"archived":false,"fork":false,"pushed_at":"2024-03-04T12:47:29.000Z","size":59,"stargazers_count":1,"open_issues_count":0,"forks_count":0,"subscribers_count":4,"default_branch":"main","last_synced_at":"2025-01-23T17:57:16.518Z","etag":null,"topics":[],"latest_commit_sha":null,"homepage":null,"language":"Brightscript","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":null,"status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/AppsFlyerSDK.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":null,"code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null}},"created_at":"2023-03-14T22:54:40.000Z","updated_at":"2023-06-05T19:52:53.000Z","dependencies_parsed_at":"2023-12-25T14:00:49.820Z","dependency_job_id":"f3b79468-606d-4f67-bd4b-122ec4de1777","html_url":"https://github.com/AppsFlyerSDK/appsflyer-roku-sample-app","commit_stats":null,"previous_names":[],"tags_count":3,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/AppsFlyerSDK%2Fappsflyer-roku-sample-app","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/AppsFlyerSDK%2Fappsflyer-roku-sample-app/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/AppsFlyerSDK%2Fappsflyer-roku-sample-app/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/AppsFlyerSDK%2Fappsflyer-roku-sample-app/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/AppsFlyerSDK","download_url":"https://codeload.github.com/AppsFlyerSDK/appsflyer-roku-sample-app/tar.gz/refs/heads/main","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":243997164,"owners_count":20380982,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":[],"created_at":"2024-11-23T11:17:36.268Z","updated_at":"2026-01-03T21:40:42.484Z","avatar_url":"https://github.com/AppsFlyerSDK.png","language":"Brightscript","funding_links":[],"categories":[],"sub_categories":[],"readme":"---\ntitle: Roku (BrightScript)\nparentDoc: 64ad64dd8459f10012a22209\ncategory: 6446526dddf659006c7ea807\norder: 1\nhidden: false\nslug: roku-brighscript\n---\n\n\u003e Link to repository  \n\u003e [GitHub](https://github.com/AppsFlyerSDK/appsflyer-roku-sample-app)\n\n## AppsFlyer Roku SDK integration\n\nAppsFlyer empowers gaming marketers to make better decisions by providing powerful tools that solve real pain points, including cross-platform attribution, mobile and web analytics, deep linking, fraud detection, privacy management and preservation, and more.\n\nGame attribution requires the game to communicate with AppsFlyer APIs over HTTPS and report user activities like first opens, consecutive sessions, and in-app events. For example, purchase events.\nWe recommend you use this sample app as a reference for integrating AppsFlyer into your Roku channel\n\n\u003chr/\u003e\n\n## AppsFlyerRokuSDK - Interface\n\n`AppsFlyerRokuSDK.brs`, included in the `source/appsflyer-integration-files` folder, contains the required code and logic to connect to AppsFlyer servers and report events.\n\n### Init\n\nThis method receives your API key and app ID and initializes the AppsFlyer Module that sends first open and session requests to AppsFlyer.\n\n**Method signature**\n\n```brs\nAppsFlyer().init(\u003c\u003c DEV_KEY \u003e\u003e, \u003c\u003c APP_ID \u003e\u003e)\n```\n\n**Usage**:\n\n```brs\n' Initialize the AppsFlyer integration (send first-open/session event)\nAppsFlyer().init(\u003c\u003c DEV_KEY \u003e\u003e, \u003c\u003c APP_ID \u003e\u003e)\n```\n\n\u003cspan id=\"app-details\"\u003e**Arguments**:\u003c/span\u003e\n\n- `APP_ID`: Found via [ifAppInfo](https://developer.roku.com/docs/references/brightscript/interfaces/ifappinfo.md).\n- `DEV_KEY`: Get from the marketer or [AppsFlyer HQ](https://support.appsflyer.com/hc/en-us/articles/211719806-App-settings-#general-app-settings).\n\n\u003e **_NOTE:_** It is recommended to set the `APP_ID` manually.\n\u003e\n\u003e When retrieving the `APP_ID` with `GetID()` [roAppInfo](https://developer.roku.com/en-gb/docs/references/brightscript/interfaces/ifappinfo.md), the channel ID is \"dev\" if the application is sideloaded, and then app will not be able to communicate with the AppsFlyer endpoint.\n\n### Start\n\nThis method sends first open and session requests to AppsFlyer.\n\n**Method signature**\n\n```brs\nstart()\n```\n\n**Usage**:\n\n```brs\nAppsFlyer().start()\n```\n\n### Stop\n\nThis method stops the SDK from functioning and communicating with AppsFlyer servers. It's used when implementing user opt-in/opt-out.\n\n**Method signature**\n\n```brs\nstop()\n```\n\n**Usage**:\n\n```brs\n' Starting the SDK\nAppsFlyer().start()\n' ...\n' Stopping the SDK, preventing further communication with AppsFlyer\nAppsFlyer().stop()\n```\n\n### LogEvent\n\nThis method receives an event name and JSON object and sends in-app events to AppsFlyer.\n\n**Method signature**\n\n```brs\nlogEvent: function(eventName as string, eventParameters as object, eventCustomParameters = {})\n```\n\n**Usage**:\n\n```brs\n' logEvent without eventCustomParameters\ntrackEventParameters = { \"af_revenue\": 24.22, \"af_currency\": \"ILS\" }\nAppsFlyer().logEvent(\"af_purchase\", trackEventParameters)\n\n' logEvent with eventCustomParameters\ntrackEventParameters = { \"af_revenue\": 24.22, \"af_currency\": \"ILS\", \"freeHandParam\": \"freeHandValue\" }\ntrackCustomEventParameters = { \"freeHandParam\": \"freeHandValue\" }\nAppsFlyer().logEvent(\"af_purchase\", trackEventParameters, trackCustomEventParameters)\n```\n\n### SetCustomerUserId\n\nThis method sets a customer ID that enables you to cross-reference your unique ID with the AppsFlyer unique ID and other device IDs. Note: You can only use this method before calling `Start()`.\nThe customer ID is available in raw data reports and in the postbacks sent via API.\n\n**Method signature**\n\n```c#\nsetCustomerUserId(string cuid)\n```\n\n**Usage**:\n\n```c#\nAppsFlyer().init(devkey, appid)\nAppsFlyer().setCustomerUserId(\"\")\nAppsFlyer().start()\n```\n\n## Running the sample app\n\n1. Open the `appsflyer-sample-app` folder in VSCode.\n2. In `source/main.brs`, replace the following parameters with [your own](#app-details):\n\n```brs\ndevkey = \u003c\u003c DEV_KEY \u003e\u003e\nappid = \u003c\u003c APP_ID \u003e\u003e\n```\n\n3. Deploy the channel: - by ([using this plugin](https://marketplace.visualstudio.com/items?itemName=mjmcaulay.roku-deploy-vscode) makes it easier), - by zipping the content of the `source` folder\n   ![Zipped source](https://files.readme.io/9347db7-image.png)  \n   and then deploying it to Roku through Roku's Development Application Installer:\n   ![Zipped source](https://files.readme.io/2835ab0-image.png)\n\n4. After the app loads, you may use the following commands through the [Roku remote](https://developer.roku.com/en-gb/docs/references/scenegraph/component-functions/onkeyevent.md):\n   - Click the **down** button to [set customer user id](#setcustomeruserid) (cuid) to `\"AF roku test CUID\"`.\n   - Click the **right** button to [set customer user id](#setcustomeruserid) (cuid) to `\"\"` (reset it).\n   - Click the **up** button to [stop](#stop) the SDK.\n   - Click the **left** button to send the [start](#start) (first open/session) event.\n   - Click the **options** button (\\*) to send [logEvent](#logevent).\n   - Click the **replay** button (\\*) to send [logEvent](#logevent) with custom parameters.\n   - Click the **OK** button after every command in order to refresh the logs.\n\n## Implementing AppsFlyer in your Roku channel\n\n### Setup\n\n1. Copy the files from the `appsflyer-integration-files` folder into your project.\n2. Add the following code to your `main.brs` file and [Initialize](#init) the AppsFlyer integration:\n\n```brs\nFunction Main(args as Dynamic) as Void\n    ...\n    showAppsflyerChannelSGScreen(args)\n    ...\nEnd Function\n\nsub showAppsflyerChannelSGScreen(args as Dynamic)\n    screen = CreateObject(\"roSGScreen\")\n    m.port = CreateObject(\"roMessagePort\")\n    screen.setMessagePort(m.port)\n    scene = screen.CreateScene(\"AppsFlyerScene\")\n    screen.show()\n\n    ' Initialize the AppsFlyer integration\n    AppsFlyer().init(DEV_KEY, APP_ID)\n    ' Enable debugging if necessary\n    AppsFlyer().enableDebugLogs(true) ' same as AppsFlyer().setLogLevel(\"debug\")\n\n    ' ConversionData response arrives here\n    while true\n        msg = Wait(0, m.port)\n        ?\"MESSAGE RECEIVED: \"msg.GetData()\n        msgType = Type(msg)\n        if msgType = \"roSGScreenEvent\"\n            if msg.isScreenClosed() then\n                return\n            end if\n        end if\n    end while\nend sub\n```\n\n3. [Start](#start) the SDK.\n4. Report [in-app events](#logevent).\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fappsflyersdk%2Fappsflyer-roku-sample-app","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fappsflyersdk%2Fappsflyer-roku-sample-app","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fappsflyersdk%2Fappsflyer-roku-sample-app/lists"}