@schibsted/sourcepoint

Package containing scripts used by Schibsteds' sites to integrate with Sourcepoint CMP

Usage no npm install needed!

<script type="module">
  import schibstedSourcepoint from 'https://cdn.skypack.dev/@schibsted/sourcepoint';
</script>

README

PSI & SCC - Sourcepoint

This repository contains small JavaScript library to simplify Privacy Settings Introducer and Schibsted Cookie Consent implementation based on non-IAB (non-TCFv2.0) solution delivered by Sourcepoint.

Features

Core features:

  • Allow to integrate on the Browser or NodeJS level
  • Allows adding Sourcepoint Client Configuration Code Snippet to the site to display PSI and/or SCC.
  • Small library to implement Schibsted Cookie Consent based on Sourcepoint solution.
  • Detect mobile apps which are using web-view and pass this information to Sourcepoint.
  • Add query params to propertyHref if were not passed by a page - important for Conditions
  • Collecting user data on PSI and sending them to Pulse (consequently to Amplitude) in statistics purposes.

Usage

Install package from NPMJS.com using command:

npm install @schibsted/sourcepoint

To add Sourcepoint Client Configuration Code Snippet to the site import and call psi or scc from package.

Read more about implementation in following sections.

Pulse installation (PSI only)

PSI is integrated with Pulse. To allow us collect user and device data, you need to follow four steps:

  1. Create / select your project in Pulse Console (read details).
  2. Retrieve your Client ID (read details).
  3. Check if your Client ID is listed in filter for PSI-Amplitude-1 in yggdrasil Configuration. If you do not find your Client ID in the list, contact us on the Slack channel: #cmp-psi-scc-tcf-support.
  4. Set up Pulse SDK in your application (read details).

Config

Parameters in configuration:

Required parameters Description
propertyId: number Maps the message to a specific property (website, app, OTT) as set up in the Sourcepoint account dashboard.
consentLanguage: string Consent message language. Available: en, no, se
baseEndpoint: string A single server endpoint that serves the GDPR messaging experience.
groupPmId: number Required for SCC only Allows to use the Privacy Manager ID for the property group use of a property group's Privacy Manager ID.
Optional parameters Description
accountId: number Organization's Sourcepoint account. default:1047
propertyHref: string Maps the implementation to a specific URL as set up in the Sourcepoint account dashboard.
targetingParams: array<string> Array with key value pairs passed to Sourcepoint - could be used as conditions in scenarios.
userId: number The Schibsted account user identifier for the logged in user. E.g. 123456, not full SDRN. Send only if user is logged in. More info below.
realm: string The Schibsted account realm of the logged in user. E.g. schibsted.com, spid.no, schibsted.fi. More info below.

Passing user data

It's highly recommended for PSI to pass user data: userId and realm. You can do it in 2 ways:

  1. Pass userId and realm parameters to config data. See example in Privacy Settings Introducer (only) section.
  2. Pass actor data below Pulse tracker installation.

Example code for logged in user:

pulse('update', {
    actor: {
        id: '{USER-ID}',
        realm: '{USER-REALM}'
    }
});

Example code for logged out user:

pulse('update', { actor: undefined });

More information about sending actor data in Pulse documentation.

Privacy Settings Introducer (only)

To add Privacy Settings Introducer only to the site you can use code snippet:

NodeJS integration:

const { psi } = require('@schibsted/sourcepoint');
const config = {
    baseEndpoint: 'https://cmp.YOUR_DOMAIN/',
    propertyId: 1234,
    consentLanguage: 'se',
    userId: 123456,
    realm: 'spid.no'
};
const snippet = psi(config);

// Now you can add the snippet to the page:
// index.js
//   app.get('/', (req, res) => res.render('page', { snippet }));
// page.hbs
//   <html><head>{{snippet}}</hread><body>...</body></html>

Browser code:

import { psi } from '@schibsted/sourcepoint';
const config = {
    baseEndpoint: 'https://cmp.YOUR_DOMAIN/',
    propertyId: 1234,
    consentLanguage: 'se',
    userId: 123456,
    realm: 'spid.no'
};
psi(window, document, navigator, config);

All parameters used in the config: baseEndpoint, propertyId, consentLanguage are required.

Please follow Web Sites Integration with SourcePoint - PSI and Cookie Consent to lear more about setup and configuration.

Privacy Settings Introducer AND Schibsted Cookie Consent

Step 1: Add Sourcepoint Client Configuration Code Snippet

To add Schibsted Cookie Consent AND Privacy Settings Introducer to the site you can use code snippet.

NodeJS integration:

const { scc } = require('@schibsted/sourcepoint');
const config = {
    baseEndpoint: 'https://cmp.YOUR_DOMAIN/',
    propertyId: 1234,
    consentLanguage: 'se',
    groupPmId: 1234,
};
const snippet = scc(config);

// Now you can add the snippet to the page:
// index.js
//   app.get('/', (req, res) => res.render('page', { snippet }));
// page.hbs
//   <html><head>{{snippet}}</hread><body>...</body></html>

Browser code:

import { scc } from '@schibsted/sourcepoint';
const config = {
    baseEndpoint: 'https://cmp.YOUR_DOMAIN/',
    propertyId: 1234,
    consentLanguage: 'se',
    groupPmId: 1234,
};
scc(window, document, navigator, config);

All parameters used in config: baseEndpoint, propertyId, consentLanguageand groupPmId are required.

If your site is already integrated with PSI you need to remove existing integration (or do required changes).

Please follow Web Sites Integration with SourcePoint - PSI and Cookie Consent to lear more about setup and configuration.

Step 2: Schibsted Cookie Consent integration with the site

In step 1 you have added required code to present user Schibsted Cookie Consent and ask him about consents.

In second step you need to integrate your site with SCC Library to honour user choices.

Cookies (scripts) could belong to one of three categories:

  • Essential - Necessary cookies which could be set always, without asking user about the consent (this category is not supported by the library because consent is note required). Ads related cookies are in this category for Media brands.
  • CMP:advertising - Advertising related Cookies - user consent is required in Marketplaces, not used by Media.
  • CMP:analytics - Analytics and Product Development related cookies - user consent is required.
  • CMP:marketing - Marketing related Cookies - user consent is required.

Your site could run script only when consent was given by user.

To receive information about user choices you can use one of two provided methods:

  • getPermission - allows getting information about consent once (asynchronous)
  • getPermissionSync - allows getting information about consent (synchronous)
  • subscribe - allows getting information about the concent and be notified about future changes

Library inform your site about one of two states (PermissionValue):

  • "1" - cookies could be set / script could be run - user gave consent
  • "0" - cookies could NOT be set / script could NOT be run - user hasn't given consent
  • null - user hasn't made a decision yet (returned only by synchronous function)

Returned values are cached in LocalStorage to speed up integration.

Step 3: Allow reopening Privacy Manager

To allow users change their choices each page should contain a link to re trigger Schibsted Cookie Consent.

Function: window._scc_.showPrivacyManager allows reopening Privacy Manager.

Schibsted Cookie Consent Interface

getPermission

Function window._scc_.getPermission allows getting information about consent once:

window._scc_.getPermission(category: Categories, callback: (value: PermissionValue) => {})

Categories:

  • CMP:advertising - Advertising related Cookies - Should be used only by Marketplaces
  • CMP:analytics - Analytics and Product Development related cookies
  • CMP:marketing - Marketing related Cookies

PermissionValue:

  • "1" - cookies could be set
  • "0" - cookies could NOT be set

getPermissionSync

Function window._scc_.getPermissionSync allows getting information about consent once, synchronously:

window._scc_.getPermissionSync(category: Categories)

Categories:

  • CMP:advertising - Advertising related Cookies - Should be used only by Marketplaces
  • CMP:analytics - Analytics and Product Development related cookies
  • CMP:marketing - Marketing related Cookies

PermissionValue:

  • "1" - cookies could be set
  • "0" - cookies could NOT be set
  • null - user hasn't made a decision yet

subscribe

Function window._scc_.subscribe allows getting information about the concent and be notified about future changes.

const unsubscribeFn = window._scc_.subscribe(category: Categories, callback: (value: PermissionValue) => {}): () => void

Categories:

  • CMP:advertising - Advertising related Cookies - Should be used only by Marketplaces
  • CMP:analytics - Analytics and Product Development related cookies
  • CMP:marketing - Marketing related Cookies

PermissionValue:

  • "1" - cookies could be set
  • "0" - cookies could NOT be set

Returned value is a function which allow unsubscribing from notification about changes.

showPrivacyManager

Function window._scc_.showPrivacyManager allows reopening Privacy Manager - thanks to that user could change settings.

window._scc_.showPrivacyManager();

This function require parameter groupPmId in the config to work properly.

Excluding PSI

In some cases we don't want to display PSI.

To achieve that condition in Sourcepoint's scenario could be used.

Below you can find supported common solution which could be easly used.

Mobile applications with WebView

Many mobile apps are using WebView to display web pages. In such cases, PSI and SCC should not be displayed (state for 2021Q1).

To achieve that code snippet is detecting a mobile app based on User Agent and is passing this information to Sourcepoint using window._sp_.config.targetingParams['mobile-webview'] = true attribute.

The logic responsible for exclusion needs to be defined in Sourcepoint.

Devices with containing one of the string listed below are detected as mobile:

  • Hermes
  • _app_
  • tv.nu
  • FinnApp

Contact us if you want to add your app detection.

Referrer

For some brands, PSI should not be displayed when a user is navigating between their sites, with different root domains, i.e. when a user is going from VG to Godt.

To help exclude such traffic information about hostname from document.referrer is passed to Sourcepoint using window._sp_.config.targetingParams['referrer-hostname'] = 'www.vg.no which allow using String Match condition in Scenario.

Cookies

To limit number of views for brands with multiple domains support we can use additional information stored in cookies.

Example:

For document.cookie=_sch_cmp_displayed=true key-value pair will be passed: _sch_cmp_displayed=true allowing usage of String Match condition in Scenario.

Cookie could be set using custom Javascript action for button.

Example

You can find example PSI and SCC implementation in the folder: example.

To run it you need to clone repository and run command:

npm start

Example runs on http://localhost:10001.

You can also find examples of ESI inclusion, as well as JS tag integration in these examples.

Just visit http://localhost:10001/esi.html and http://localhost:10001/js-tag.html respectively.

For Privacy Developers

How to publish package

Package is distributed by NPMJS.com

To publish the package you need to:

  • change version in package.json file
  • create a tag from branch master

Code will be published by Travis CI.

How it works

NodeJS version uses generated static scripts during publishing by rollup (script: npm run build) - files are stored in directory: dist/.

Thanks to that code is converted to beeing compatible with old browsers, merged into one file per integration (PSI, SCC).

For debug purpose you can build files without minimization using script: npm run build:debug,

NPM Version

NPM Version used by Travis CI is defined in file .nvmrc.

This way allow you to switch to propre NodeJS version locally in an easy way too.

Running code shown below the proper NodeJS version will be used / installed.

nvm use

Pulse configuration

Events that flow into the Pulse platform via the collector needs to be routed to a destination, also called sink. Sinks collecting data from @schibsted/sourcepoint and sending them to Amplitude are calling PSI-Amplitude-1. They can be found in two files:

Mapping Pulse data to Amplitude schema is also set in routing repo in amplitude-psi.jstl2 file.

Pulse events

PSI is integrated with Pulse. Events are sent to your provided used by the page (using default Pulse object available on the page). You can analyse events on your own. All PSI related events are tagged using the property: provider.component = "PSI"

Privacy Services team sends events from all providers to their own project in Amplitude too.

PSI sends 2 types of events:

  • View - PSI: @type: "View", object.@type: "PSI"
    Triggered when PSI is about to display to user.
  • Engagement - PSI: @type: "Engagement", object.@type: "PSI"
    Triggered on user action. Actions can be distinguished in Amplitude by object.name. Supported actions:
    • click on "Okay" button
    • click on "To my saved preferences" button
    • click on "visit out Privacy pages" link

Schema / documentation of object.@type set to "PSI" can be found in event-formats repo.

Sourcepoint events

Documentation of Sourcepoint events can be found here.

However, working on this project we collected additional information which can be useful in development.

About onMessageReceiveData event:

  • It is a normal behaviour that this event listener fires on every pageview.
  • If the messageId in callback data is different from 0, it means that the message was displayed to the user.
  • Event callback is not returning the cmpgn_id (listed in documentation), because the messageId is changing from campaign to campaign. It seems that this variable was removed from the data sent to the callback since the messageId is already telling you which campaign it is.

About onMessageReady event:

  • This event fires/triggers just before the CMP message is shown to the user. Few of Sourcepoint clients decided that they want to trigger a Privacy manager as a first layer message. Therefore, they selected in their scenario in the “Show message” event the Privacy manager layer instead of the first layer message. They use the Privacy manager as a first layer message, because they want to disclose to the user from the beginning the whole vendor list, toggles, etc.
  • According to Sourcepoint team it is the best event to detect when a message is showing up to user.

Links