Skip to content

Commit

Permalink
readme update
Browse files Browse the repository at this point in the history
  • Loading branch information
tom-win87 committed Apr 18, 2024
0 parents commit 5ae5f06
Show file tree
Hide file tree
Showing 23 changed files with 1,307 additions and 0 deletions.
Binary file added .DS_Store
Binary file not shown.
147 changes: 147 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,147 @@
<img src="/images/logo.png" width=25%>

Sourcepoint's HTML5 OTT solution allows you to surface a Sourcepoint CMP message on devices such as Tizen and webOS for supported regulatory frameworks.

# Table of Contents

- [Implementation overview](#implementation-overview)
- [Supported campaigns](#supported-campaigns)
- [Resurface OTT message](#resurface-ott-message)
- [Global Privacy Platform (GPP) Multi-State Privacy (MSPS) support](#global-privacy-platform-gpp-multi-state-privacy-msps-support)
- [APIs](#apis)

## Implementation overview

Every implementation requires a bundle of scripts that must be added to your `index.html` file in order to surface the appropriate message configured in the Sourcepoint portal.

- [Stub file(s)](#stub-files)
- [Client configuration script](#client-configuration-script)
- [URL to messaging library](#url-to-messaging-library)

### Stub file(s)

The first part implementation script(s) contains the IAB stub functions. The stub functions set up the IAB privacy string object `__tcfapi` (for GDPR TCF campaigns) or `__uspapi` (for U.S. Privacy (Legacy) campaigns), respectively.

This makes it available on queue to be called and released when needed. It is important to have these stub file(s) in the first position to avoid errors and failure of service.

> Note: There is no stub file when configuring a GDPR Standard campaign for your project.
```javascript
// GDPR TCF stub file. Example only. Please use stub file generated in Sourcepoint portal as it may have changed.
<script type="text/javascript">
function _typeof(t){return(_typeof="function"==typeof Symbol&&"symbol"==typeof Symbol.iterator?function(t){return typeof t}:function(t){return t&&"function"==typeof Symbol&&t.constructor===Symbol&&t!==Symbol.prototype?"symbol":typeof t})(t)}!function(){for(var t,e,o=[],n=window,r=n;r;){try{if(r.frames.__tcfapiLocator){t=r;break}}catch(t){}if(r===n.top)break;r=n.parent}t||(function t(){var e=n.document,o=!!n.frames.__tcfapiLocator;if(!o)if(e.body){var r=e.createElement("iframe");r.style.cssText="display:none",r.name="__tcfapiLocator",e.body.appendChild(r)}else setTimeout(t,5);return!o}(),n.__tcfapi=function(){for(var t=arguments.length,n=new Array(t),r=0;r<t;r++)n[r]=arguments[r];if(!n.length)return o;"setGdprApplies"===n[0]?n.length>3&&2===parseInt(n[1],10)&&"boolean"==typeof n[3]&&(e=n[3],"function"==typeof n[2]&&n[2]("set",!0)):"ping"===n[0]?"function"==typeof n[2]&&n[2]({gdprApplies:e,cmpLoaded:!1,cmpStatus:"stub"}):o.push(n)},n.addEventListener("message",(function(t){var e="string"==typeof t.data,o={};if(e)try{o=JSON.parse(t.data)}catch(t){}else o=t.data;var n="object"===_typeof(o)?o.__tcfapiCall:null;n&&window.__tcfapi(n.command,n.version,(function(o,r){var a={__tcfapiReturn:{returnValue:o,success:r,callId:n.callId}};t&&t.source&&t.source.postMessage&&t.source.postMessage(e?JSON.stringify(a):a,"*")}),n.parameter)}),!1))}();
</script>
```

```javascript
// US Privacy (Legacy) stub file. Example only. Please use stub file generated in Sourcepoint portal as it may have changed.
<script>
(function () { var e = false; var c = window; var t = document; function r() { if (!c.frames["__uspapiLocator"]) { if (t.body) { var a = t.body; var e = t.createElement("iframe"); e.style.cssText = "display:none"; e.name = "__uspapiLocator"; a.appendChild(e) } else { setTimeout(r, 5) } } } r(); function p() { var a = arguments; __uspapi.a = __uspapi.a || []; if (!a.length) { return __uspapi.a } else if (a[0] === "ping") { a[2]({ gdprAppliesGlobally: e, cmpLoaded: false }, true) } else { __uspapi.a.push([].slice.apply(a)) } } function l(t) { var r = typeof t.data === "string"; try { var a = r ? JSON.parse(t.data) : t.data; if (a.__cmpCall) { var n = a.__cmpCall; c.__uspapi(n.command, n.parameter, function (a, e) { var c = { __cmpReturn: { returnValue: a, success: e, callId: n.callId } }; t.source.postMessage(r ? JSON.stringify(c) : c, "*") }) } } catch (a) { } } if (typeof __uspapi !== "function") { c.__uspapi = p; __uspapi.msgHandler = l; c.addEventListener("message", l, false) } })();
</script>
```

```javascript
// US Multi-State Privacy stub file. Example only. Please use stub file generated in Sourcepoint portal as it may have changed.
window.__gpp_addFrame=function(e){if(!window.frames[e])if(document.body){var t=document.createElement("iframe");t.style.cssText="display:none",t.name=e,document.body.appendChild(t)}else window.setTimeout(window.__gpp_addFrame,10,e)},window.__gpp_stub=function(){var e=arguments;if(__gpp.queue=__gpp.queue||[],__gpp.events=__gpp.events||[],!e.length||1==e.length&&"queue"==e[0])return __gpp.queue;if(1==e.length&&"events"==e[0])return __gpp.events;var t=e[0],p=e.length>1?e[1]:null,s=e.length>2?e[2]:null;if("ping"===t)p({gppVersion:"1.1",cmpStatus:"stub",cmpDisplayStatus:"hidden",signalStatus:"not ready",supportedAPIs:["2:tcfeuv2","5:tcfcav1","6:uspv1","7:usnatv1","8:uscav1","9:usvav1","10:uscov1","11:usutv1","12:usctv1"],cmpId:0,sectionList:[],applicableSections:[],gppString:"",parsedSections:{}},!0);else if("addEventListener"===t){"lastId"in __gpp||(__gpp.lastId=0),__gpp.lastId++;var n=__gpp.lastId;__gpp.events.push({id:n,callback:p,parameter:s}),p({eventName:"listenerRegistered",listenerId:n,data:!0,pingData:{gppVersion:"1.1",cmpStatus:"stub",cmpDisplayStatus:"hidden",signalStatus:"not ready",supportedAPIs:["2:tcfeuv2","5:tcfcav1","6:uspv1","7:usnatv1","8:uscav1","9:usvav1","10:uscov1","11:usutv1","12:usctv1"],cmpId:0,sectionList:[],applicableSections:[],gppString:"",parsedSections:{}}},!0)}else if("removeEventListener"===t){for(var a=!1,i=0;i<__gpp.events.length;i++)if(__gpp.events[i].id==s){__gpp.events.splice(i,1),a=!0;break}p({eventName:"listenerRemoved",listenerId:s,data:a,pingData:{gppVersion:"1.1",cmpStatus:"stub",cmpDisplayStatus:"hidden",signalStatus:"not ready",supportedAPIs:["2:tcfeuv2","5:tcfcav1","6:uspv1","7:usnatv1","8:uscav1","9:usvav1","10:uscov1","11:usutv1","12:usctv1"],cmpId:0,sectionList:[],applicableSections:[],gppString:"",parsedSections:{}}},!0)}else"hasSection"===t?p(!1,!0):"getSection"===t||"getField"===t?p(null,!0):__gpp.queue.push([].slice.apply(e))},window.__gpp_msghandler=function(e){var t="string"==typeof e.data;try{var p=t?JSON.parse(e.data):e.data}catch(e){p=null}if("object"==typeof p&&null!==p&&"__gppCall"in p){var s=p.__gppCall;window.__gpp(s.command,(function(p,n){var a={__gppReturn:{returnValue:p,success:n,callId:s.callId}};e.source.postMessage(t?JSON.stringify(a):a,"*")}),"parameter"in s?s.parameter:null,"version"in s?s.version:"1.1")}},"__gpp"in window&&"function"==typeof window.__gpp||(window.__gpp=window.__gpp_stub,window.addEventListener("message",window.__gpp_msghandler,!1),window.__gpp_addFrame("__gppLocator"));
</script>
```

### Client configuration script

### URL to messaging library

## Supported campaigns

Campaign are surfaced on yout HTML5 device by adding campaign objects to your configuration

The following Sourcepoint campaigns are supported via our HTML5 OTT solution:

| **Config object** | **Campaign** |
| ----------------- | ------------------------- |
| `gdpr: {}` | GDPR TCF or GDPR Standard |
| `ccpa: {}` | U.S. Privacy (Legacy) |

> U.S. Multi-State Privacy campaigns are currently not supported for HTML5 OTT devices. If your organization needs to support the Global Privacy Platform (GPP) Multi-State Privacy (MSPS) framework, you will need to configure a U.S. Privacy (Legacy) campaign to do so. [Click here](#us-multi-state-privacy-campaign-support) for more information about this configuration.
## Resurface OTT message

The privacy manager JavaScript code is a snippet that is added to your project and allows an end-user to resurface a privacy manager. Using this link/button, end-users can directly manage their consent preferences on an ongoing basis without having to re-encounter your organization's first layer message.

Load the OTT message on demand by [retrieving the OTT message ID](https://docs.sourcepoint.com/hc/en-us/articles/20806618675603-Resurface-OTT-message) from the Sourcepoint portal and pass it to the `loadNativeOtt` function.

```javascript
//GDPR
window._sp_.gdpr.loadNativeOtt(GDPR_OTT_ID);

//U.S. Privacy (Legacy)
window._sp_.ccpa.loadNativeOtt(USP_LEGACY_OTT_ID);
```

Attach the `loadNativeOtt` function to an event handler on your project. Most organizations who implement this function will attach it to `onclick` event of an element.

```javascript
//GDPR
<button onclick="window._sp_.gdpr.loadNativeOtt(123456)">OTT GDPR</button>

//U.S. Privacy (Legacy)
<button onclick="window._sp_.ccpa.loadNativeOtt(987654)">OTT USP Legacy</button>
```

## Global Privacy Platform (GPP) Multi-State Privacy (MSPS) support

In the Sourcepoint portal, U.S. Multi-State Privacy campaigns are created to support the Global Privacy Platform (GPP) Multi-State Privacy (MSPS) framework. Currently, U.S. Multi-State Privacy campaigns are not supported in Sourcepoint's HTML5 OTT solution.

If your organization wishes to support the Global Privacy Platform (GPP) Multi-State Privacy (MSPS) framework you will need to specifically configure a U.S. Privacy (Legacy) campaign to do so.

> Once successfully, configured Sourcepoint will enable the Multi-State Privacy String (MSPS) alongside the U.S. Privacy String. The MSPS can be acessed via the [GPP API](https://sourcepoint-public-api.readme.io/reference/iab-global-privacy-platform-gpp-api).<br><br>Please be aware that this solution will only set the [U.S. National Privacy section of the MSPS](https://sourcepoint-public-api.readme.io/reference/us-national-privacy-section) and will not set values for sensitive data categories.
Add the GPP stub file in addition to the U.S. Privacy - CCPA stub file to `index.html`.

```javascript
//Example only. Please use stub file generated in Sourcepoint portal as it may have changed.
<script>
window.__gpp_addFrame=function(e){if(!window.frames[e])if(document.body){var t=document.createElement("iframe");t.style.cssText="display:none",t.name=e,document.body.appendChild(t)}else window.setTimeout(window.__gpp_addFrame,10,e)},window.__gpp_stub=function(){var e=arguments;if(__gpp.queue=__gpp.queue||[],__gpp.events=__gpp.events||[],!e.length||1==e.length&&"queue"==e[0])return __gpp.queue;if(1==e.length&&"events"==e[0])return __gpp.events;var t=e[0],p=e.length>1?e[1]:null,s=e.length>2?e[2]:null;if("ping"===t)p({gppVersion:"1.1",cmpStatus:"stub",cmpDisplayStatus:"hidden",signalStatus:"not ready",supportedAPIs:["2:tcfeuv2","5:tcfcav1","6:uspv1","7:usnatv1","8:uscav1","9:usvav1","10:uscov1","11:usutv1","12:usctv1"],cmpId:0,sectionList:[],applicableSections:[],gppString:"",parsedSections:{}},!0);else if("addEventListener"===t){"lastId"in __gpp||(__gpp.lastId=0),__gpp.lastId++;var n=__gpp.lastId;__gpp.events.push({id:n,callback:p,parameter:s}),p({eventName:"listenerRegistered",listenerId:n,data:!0,pingData:{gppVersion:"1.1",cmpStatus:"stub",cmpDisplayStatus:"hidden",signalStatus:"not ready",supportedAPIs:["2:tcfeuv2","5:tcfcav1","6:uspv1","7:usnatv1","8:uscav1","9:usvav1","10:uscov1","11:usutv1","12:usctv1"],cmpId:0,sectionList:[],applicableSections:[],gppString:"",parsedSections:{}}},!0)}else if("removeEventListener"===t){for(var a=!1,i=0;i<__gpp.events.length;i++)if(__gpp.events[i].id==s){__gpp.events.splice(i,1),a=!0;break}p({eventName:"listenerRemoved",listenerId:s,data:a,pingData:{gppVersion:"1.1",cmpStatus:"stub",cmpDisplayStatus:"hidden",signalStatus:"not ready",supportedAPIs:["2:tcfeuv2","5:tcfcav1","6:uspv1","7:usnatv1","8:uscav1","9:usvav1","10:uscov1","11:usutv1","12:usctv1"],cmpId:0,sectionList:[],applicableSections:[],gppString:"",parsedSections:{}}},!0)}else"hasSection"===t?p(!1,!0):"getSection"===t||"getField"===t?p(null,!0):__gpp.queue.push([].slice.apply(e))},window.__gpp_msghandler=function(e){var t="string"==typeof e.data;try{var p=t?JSON.parse(e.data):e.data}catch(e){p=null}if("object"==typeof p&&null!==p&&"__gppCall"in p){var s=p.__gppCall;window.__gpp(s.command,(function(p,n){var a={__gppReturn:{returnValue:p,success:n,callId:s.callId}};e.source.postMessage(t?JSON.stringify(a):a,"*")}),"parameter"in s?s.parameter:null,"version"in s?s.version:"1.1")}},"__gpp"in window&&"function"==typeof window.__gpp||(window.__gpp=window.__gpp_stub,window.addEventListener("message",window.__gpp_msghandler,!1),window.__gpp_addFrame("__gppLocator"));
</script>
```

Add the `includeGppApi` parameter to the `ccpa` object in your client configuration and set one of the following flag(s) depending on your organization's use case. [Click here](docs/MSPS_signatories.md) for more information on each attribute, possible values, and examples for signatories and non-signatories of the MSPA.

If `includeGppApi` is set to `true`, the following MSPA arguments will be set accordingly:

- `MspaCoveredTransaction`: `"no"`
- `MspaOptOutOptionMode`: `"na"`
- `MspaServiceProviderMode`: `"na"`

```
window._sp_queue = [];
window._sp_ = {
config: {
accountId: 1584,
baseEndpoint: 'https://cdn.privacy-mgmt.com',
ccpa: {
includeGppApi: true
},
propertyHref: 'https://www.testdemo.com',
```

Optionally, your organization can customize support for the MSPS by configuring the MSPA attributes as part of the GPP config.

```
window._sp_queue = [];
window._sp_ = {
config: {
accountId: 1584,
baseEndpoint: 'https://cdn.privacy-mgmt.com',
ccpa: {
includeGppApi: {
"MspaCoveredTransaction": "yes",
"MspaOptOutOptionMode": "yes",
"MspaServiceProviderMode": "no"
}
},
propertyHref: 'https://www.testdemo.com',
```

## APIs

Find comprehensive guides and documentation to help you start working with Sourcepoint's public APIs as quickly as possible for different regulatory frameworks in our [API Hub](https://sourcepoint-public-api.readme.io/reference/welcome-to-the-sourcepoint-api-hub).
55 changes: 55 additions & 0 deletions docs/MSPS_signatories.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,55 @@
The IAB Tech Lab's Global Privacy Platform's (GPP) Multi-State Privacy String (MSPS) is a signal that notifies downstream partners that participating publishers have provided end-users with specific notice and choice over data processing activities on their properties.

Your organization will need to configure the following attributes as part of the GPP config:

| Attribute | Possible values | Description |
| ------------------------- | ----------------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `MspaCoveredTransaction` | `yes`<br> `no` | Publisher or Advertiser, as applicable, is a signatory to the IAB Multistate Service Provider Agreement (MSPA), as may be amended from time to time, and declares that the transaction is a “Covered Transaction” as defined in the MSPA.<br><br>The configured value for the flag will translate to the following in the MSPS:<br>`yes` = 1<br>`no` = 2 |
| `MspaOptOutOptionMode` | `na`<br> `yes`<br> `no` | Publisher or Advertiser, as applicable, has enabled “Opt-Out Option Mode” for the “Covered Transaction,” as such terms are defined in the MSPA.<br><br>The configured value for the flag will translate to the following in the MSPS:<br>`na` = 0<br>`yes` = 1<br>`no` = 2 |
| `MspaServiceProviderMode` | `na`<br> `yes`<br> `no` | Publisher or Advertiser, as applicable, has enabled “Service Provider Mode” for the “Covered Transaction,” as such terms are defined in the MSPA.<br><br>The configured value for the flag will translate to the following in the MSPS:<br>`na` = 0 <br> `yes` = 1 <br> `no` = 2 |

Depending on whether your organization is a signatory of the Multi-State Privacy Agreement (MSPA), your organization will configure the attributes in the following ways:

### Non-signatory of the MSPA

For organizations who have not signed the MSPA and only want to listen for the MSPS. When setting the attributes thusly, the MSPA, as a contractual framework, does not cover your transactions.

> Note: This is the default settings for these attributes. Non-signatories of the MSPA can also just set the `includeGppApi` parameter to `true` within the `ccpa` object and these attributes will default to this configuration.
```
window._sp_queue = [];
window._sp_ = {
config: {
accountId: 1584,
baseEndpoint: 'https://cdn.privacy-mgmt.com',
ccpa: {
includeGppApi: {
"MspaCoveredTransaction": "no",
"MspaOptOutOptionMode": "na",
"MspaServiceProviderMode": "na"
}
},
propertyHref: 'https://www.testdemo.com',
```

### Signatory of the MSPA

For transactions covered by the MSPA, signatories can choose to operate in [Opt-Out Option Mode or Service Provider Mode](https://www.iab.com/wp-content/uploads/2022/12/IAB_MSPA_Decision_Tree.pdf).

```
window._sp_queue = [];
window._sp_ = {
config: {
accountId: 1584,
baseEndpoint: 'https://cdn.privacy-mgmt.com',
ccpa: {
includeGppApi: {
"MspaCoveredTransaction": "yes",
"MspaOptOutOptionMode": "yes",
"MspaServiceProviderMode": "no"
}
},
propertyHref: 'https://www.testdemo.com',
```
Binary file added images/logo.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
13 changes: 13 additions & 0 deletions tizen-example/config.xml
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
<?xml version="1.0" encoding="UTF-8"?>
<widget xmlns:tizen="http://tizen.org/ns/widgets" xmlns="http://www.w3.org/ns/widgets" id="http://yourdomain/SourcepointCMP" version="1.2.0" viewmodes="maximized">
<access origin="*" subdomains="true"></access>
<tizen:application id="dMsNuVOUiZ.SourcepointCMP" package="dMsNuVOUiZ" required_version="3.0" launch_mode="single"/>
<content src="index.html"/>
<feature name="http://tizen.org/feature/screen.size.all"/>
<icon src="icon.png"/>
<name>SourcepointCMP</name>
<tizen:privilege name="http://tizen.org/privilege/fullscreen"/>
<tizen:privilege name="http://tizen.org/privilege/internet"/>
<tizen:privilege name="http://tizen.org/privilege/tv.inputdevice"/>
<tizen:profile name="tv-samsung"/>
</widget>
75 changes: 75 additions & 0 deletions tizen-example/css/style.css
Original file line number Diff line number Diff line change
@@ -0,0 +1,75 @@
* {
font-family: Lucida Sans, Arial, Helvetica, sans-serif;
}

body {
margin: 50px auto;
background-color: #ffffff;
}

header h1 {
font-size: 108px;
margin: 0px;
}

header h2 {
font-size: 54px;
margin: 0px;
color: #888;
font-style: italic;
}

nav ul {
list-style: none;
padding: 20px;
display: block;
clear: right;
background-color: #666;
padding-left: 4px;
height: 48px;
}

nav ul li {
display: inline;
padding: 0px 20px 5px 10px;
border-right: 1px solid #ccc;
}

nav ul li a {
color: #EFD3D3;
text-decoration: none;
font-size: 39px;
font-weight: bold;
}

nav ul li a:hover {
color: #fff;
}

article > header h1 {
font-size: 60px;
margin-left: 14px;
}

article > header h1 a {
color: #993333;
}

article > header h1 img {
vertical-align:middle;
}

article > section header h1 {
font-size: 48px;
}

article p {
clear: both;
}

footer p {
text-align: center;
font-size: 36px;
color: #888;
margin-top: 30px;
}
Binary file added tizen-example/icon.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added tizen-example/images/tizen_32.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading

0 comments on commit 5ae5f06

Please sign in to comment.