{"id":29105512,"url":"https://github.com/googleads/gam-utils-roku","last_synced_at":"2026-02-03T05:34:03.166Z","repository":{"id":282492594,"uuid":"770499994","full_name":"googleads/gam-utils-roku","owner":"googleads","description":null,"archived":false,"fork":false,"pushed_at":"2025-04-17T14:21:16.000Z","size":39,"stargazers_count":7,"open_issues_count":0,"forks_count":0,"subscribers_count":12,"default_branch":"main","last_synced_at":"2025-06-28T18:52:53.204Z","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":"apache-2.0","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/googleads.png","metadata":{"files":{"readme":"README.md","changelog":"CHANGELOG.md","contributing":"CONTRIBUTING","funding":null,"license":"LICENSE","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,"publiccode":null,"codemeta":null}},"created_at":"2024-03-11T16:55:33.000Z","updated_at":"2025-05-05T15:20:29.000Z","dependencies_parsed_at":"2025-03-15T01:12:11.371Z","dependency_job_id":"26a117e5-e3a0-4670-971c-0950c6847db9","html_url":"https://github.com/googleads/gam-utils-roku","commit_stats":null,"previous_names":["googleads/gam-utils-roku"],"tags_count":2,"template":false,"template_full_name":null,"purl":"pkg:github/googleads/gam-utils-roku","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/googleads%2Fgam-utils-roku","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/googleads%2Fgam-utils-roku/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/googleads%2Fgam-utils-roku/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/googleads%2Fgam-utils-roku/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/googleads","download_url":"https://codeload.github.com/googleads/gam-utils-roku/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/googleads%2Fgam-utils-roku/sbom","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":262524628,"owners_count":23324063,"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":"2025-06-29T02:31:16.743Z","updated_at":"2026-02-03T05:33:58.148Z","avatar_url":"https://github.com/googleads.png","language":"Brightscript","funding_links":[],"categories":[],"sub_categories":[],"readme":"# GAM Utils for Roku\n\nGAM Utils is a small helper script, written in the BrightScript language, that\nhelps enable programmatic monetization on Google Ad Manager for Roku apps. It\nserves as a lightweight alternative to the\n[IMA DAI SDK](https://developers.google.com/ad-manager/dynamic-ad-insertion/sdk/roku).\n\n## Building the sample app\n\nThe `/sample` folder contains a minimal sample integration of `gam_utils.brs`.\nTo prepare the sample channel for sideload, simply:\n\n1. Copy `./gam_utils.brs` to `./sample/source/gam_utils.brs`\n2. Compress all of the contents of `./sample/` into `sample.zip`.\n\nAlternatively, you can run the included shell script:\n\n```bash\n$ ./build_sample.sh\n```\nto automatically copy `./gam_utils.brs` into place and compress the sample as\n`sample.zip`.\n\n## Integrating GAM Utils\n\n### 1. Load the Roku Advertising Framework library\n\nFollow Roku's documentation for [integrating\nRAF](https://developer.roku.com/docs/developer-program/advertising/integrating-roku-advertising-framework.md).\n\n### 2. Load GAM Utils\n\n1. Place `gam_utils.brs` in your `components` directory.\n2. In your component XML file, add a `\u003cscript\u003e` tag to load GAM Utils, as seen\nbelow:\n\n```xml\n\u003cscript type=\"text/brightscript\" uri=\"gam_utils.brs\" /\u003e\n```\n\n### 3. Create a new app session\n\nCall the `newAppSession` function to create a new app session. Create this app\nsession as soon as possible on ad start. This session must be reused for the\nlifespan of the app.\n\n#### Example\n\n```brs\nm.appSession = newAppSession()\n```\n\n### 4. Create a new content session\n\nCall the function `appSession.newContentSession()` to create a new content\nsession for each stream request or content video change. This function takes a\nsingle parameter which is an associative array containing the values described\nin the table below:\n\n| **Key** \t| **Value Type** \t| **Description** \t|\n|---\t|---\t|---\t|\n| `adWillAutoPlay` \t| Boolean \t| Indicates whether video ad starts by autoplay (true) or by click (false). \t|\n| `adWillPlayMuted` \t| Boolean \t| Indicates whether playback starts while the video is muted. \t|\n| `continuousPlayback` \t| Boolean \t| Indicates whether the player intends to continuously play video content, similar to a TV broadcast. \t|\n| `descriptionUrl` \t| Valid URL String \t| Web URL describing the content. See the [Help Center][HC-URL] for more information. \t|\n| `directedForChildOrUnknownAge` \t| Boolean \t| Indicates whether the ad request should receive [child directed treatment][CDT]. \t|\n| `iconsSupported` \t| Boolean \t| Indicates whether the player supports VAST Icons, such as [Why this ad?][WTA] \t|\n| `publisherProvidedId` \t| String \t| The [PPID][PPID] is used for frequency capping, audience segmentation and targeting, sequential ad rotation, and other audience-based ad delivery controls across devices. \t|\n| `raf` | Object of type `Roku_Ads()`  | An instance of the (Roku Advertising Framework)[RAF]  |\n| `skippablesSupported` \t| Boolean \t| Indicates whether to make skippable ads eligible for ad responses in this session.  |\n| `storageAllowed` \t| Boolean \t| Indicates whether the user has provided permission to use local storage. \t|\n| `supportedApiFrameworks` \t| Array of Integers \t| Indicates all of the [API frameworks][APIS] that this player supports. \t|\n| `videoHeight` \t| Integer \t| The height of the video player. \t|\n| `videoWidth` \t| Integer \t| The width of the video player. \t|\n\n#### Example\n\n```brs\n' Create a new content session.\nm.contentSession = m.appSession.newContentSession({\n  adWillAutoPlay: True,\n  adWillPlayMuted: False,\n  continuousPlayback: False,\n  descriptionUrl: \"https://your-example-website\",\n  directedForChildOrUnknownAge: False,\n  iconsSupported: True,\n  publisherProvidedId: \"123456\",\n  raf: m.raf,\n  skippablesSupported: False,\n  storageAllowed: True,\n  supportedApiFrameworks: [],\n  videoHeight: 480,\n  videoWidth: 640\n })\n```\n\n### 5. Attach `\u0026givn` parameter to stream or ad request\n\nCall the `contentSession.getGivn()` function to retrieve the string value that\nmust be sent in the `\u0026givn=` parameter. You'll need to add this `\u0026givn=`\nparameter to all ad requests that belong to the current video content or stream.\nEach time the viewer changes content or starts playing a new stream, call this\nfunction again to get a new `\u0026givn=` parameter value for each video stream.\n\n#### Ad request example\n\n```brs\ngivn = m.contentSession.getGivn()\n\n' Build a VAST tag URL\nadTag = \"https://pubads.g.doubleclick.net/gampad/ads?iu=/21775744923/external/single_ad_samples\u0026sz=640x480\u0026cust_params=sample_ct%3Dlinear\u0026gdfp_req=1\u0026output=vast\u0026unviewed_position_start=1\u0026env=vp\u0026impl=s\u0026correlator=\"\nurl = adTag + \"\u0026givn=\" + givn\n\n' Make an ad request (not implemented here)\nxmlResponse = makeGETRequest(adTag)\n```\n\n#### Stream request example\n\n```brs\ngivnStr = m.contentSession.getGivn()\nrequestBody = formatJson( { givn: givnStr } )\nurl = \"https://dai.google.com/linear/v1/dash/event/0ndl1dJcRmKDUPxTRjvdog/stream\"\n\n' Make a stream request (not implemented here)\njsonResponse = makePOSTRequest(url, requestBody)\n```\n\n### 6. Trigger started and ended beacons\n\nBefore starting ad playback on your stream or video content, call\n`contentSession.sendStartedBeacon` to trigger a started beacon. When the\nplayback ends, call `contentSession.sendEndedBeacon` to trigger an ended beacon.\n\n#### Example\n\n```brs\nm.contentSession.sendStartedBeacon()\n' begin playback\nwhile adIsActive\n  ...\nend while\n' playback ends\nm.contentSession.sendEndedBeacon()\n```\n\n### 7. Trigger interaction beacons\n\nWhile an ad is playing, if the user interacts with their control, that\ninteraction should be sent to the `contentSession.sendAdTouchBeacon` with the\nkey code being pressed. In addition, if the interaction is a click through on an\nad, call `contentSession.sendAdClickBeacon` to register an ad click.\n\n#### Example\n\n```brs\nfunction onKeyEvent(key as String, press as Boolean) as Boolean\n  if (press AND m.adIsPlaying) then\n    ' m.mainAdIsSelected indicates that the user is interacting with the ad\n    ' itself, rather than an icon, overlay, or ui element.\n    if (key = \"OK\" AND m.mainAdIsSelected) then\n      m.contentSession.sendAdClickBeacon()\n      ..\n    end if\n    m.contentSession.sendAdTouchBeacon(key)\n  end if\nend function\n```\n\n### 8. Trigger ad progress poll\n\nWhile ad content is playing, call the `contentSession.poll` method once per\nsecond, to notify the Google Ad Manager that the ad is still playing.\n\n#### Example\n\n```brs\nmessagePort = createObject(\"roMessagePort\")scx cv\nwhile streamIsActive\n  ' Poll the helper code so it can send progress beacons as needed.\n  message = messagePort.waitMessage(1000)\n  m.contentSession.poll()\n  ...\nend while\n```\n\n### 9. Send VAST tracking events\n\nCall ad progress tracking event URLs to support ad tracking and reporting.\nAdditional steps are needed to\n[support skippable ads](https://github.com/googleads/gam-utils-roku/blob/main/skippable-ads.md).\nSee the [IAB VAST standards](https://iabtechlab.com/standards/vast/) for more\ninformation on the tracking events.\n\n[hc link]: https://github.com/InteractiveAdvertisingBureau/AdCOM/blob/main/AdCOM%20v1.0%20FINAL.md#list_apiframeworks\n[HC-URL]: https://support.google.com/admanager/answer/10678356#description_url\n[CDT]: https://support.google.com/admanager/answer/3671211\n[RAF]: https://developer.roku.com/en-gb/docs/developer-program/advertising/integrating-roku-advertising-framework.md\n[WTA]: https://support.google.com/admanager/answer/2695279?sjid=16481471245632903346-NA#video\u0026zippy=\n[PPID]: https://support.google.com/admanager/answer/2880055#requirements\n[APIS]: https://github.com/InteractiveAdvertisingBureau/AdCOM/blob/main/AdCOM%20v1.0%20FINAL.md#list_apiframeworks\n[IMA DevSite]: https://developers.google.com/interactive-media-ads\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fgoogleads%2Fgam-utils-roku","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fgoogleads%2Fgam-utils-roku","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fgoogleads%2Fgam-utils-roku/lists"}