Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

GPP consent module: phase one release #9321

Merged
merged 7 commits into from
Dec 21, 2022
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
124 changes: 124 additions & 0 deletions integrationExamples/gpt/gpp_us_hello_world.html
Original file line number Diff line number Diff line change
@@ -0,0 +1,124 @@
<!--
This page calls a single bidder for a single ad slot. It can be considered a "hello world" example for using
Prebid with the Google Publisher Tag.
It also makes a good test page for new adapter PR submissions. Simply set your server's Bid Params object in the
bids array inside the adUnits, and it will use your adapter to load an ad.
NOTE that many ad servers won't send back an ad if the URL is localhost... so you might need to
set an alias in your /etc/hosts file so that you can load this page from a different domain.
-->

<html>

<head>
<script type="text/javascript" data-cmp-ab="1" src="https://cdn.consentmanager.net/delivery/semiautomatic.js"
data-cmp-cdid="599af61faf55" data-cmp-host="delivery.consentmanager.net" data-cmp-cdn="cdn.consentmanager.net" data-cmp-codesrc="1"></script>


<script async src="../../build/dev/prebid.js"></script>
<script async src="https://www.googletagservices.com/tag/js/gpt.js"></script>
<script>
var FAILSAFE_TIMEOUT = 3300;
var PREBID_TIMEOUT = 1000;

var adUnits = [{
code: 'div-gpt-ad-1460505748561-0',
mediaTypes: {
banner: {
sizes: [[300, 250], [300, 600]],
}
},
// Replace this object to test a new Adapter!
bids: [{
bidder: 'appnexus',
params: {
placementId: 13144370
}
}]

}];

var pbjs = pbjs || {};
pbjs.que = pbjs.que || [];

</script>

<script>
var googletag = googletag || {};
googletag.cmd = googletag.cmd || [];
googletag.cmd.push(function () {
googletag.pubads().disableInitialLoad();
});

pbjs.que.push(function () {
pbjs.addAdUnits(adUnits);
pbjs.setConfig({
userSync: {
filterSettings: {
iframe: {
bidders: ['appnexus'],
filter: 'include'
}
}
}
})
pbjs.setConfig({
consentManagement: {
gpp: {
cmpApi: 'iab',
timeout: 5000
},
usp: {
cmpApi: 'static',
consentData: {
getUSPData: {
uspString: '1YYY'
}
}
}
}
})
pbjs.requestBids({
bidsBackHandler: sendAdserverRequest,
timeout: PREBID_TIMEOUT
});
});

function sendAdserverRequest() {
if (pbjs.adserverRequestSent) return;
pbjs.adserverRequestSent = true;
googletag.cmd.push(function () {
pbjs.que.push(function () {
pbjs.setTargetingForGPTAsync();
googletag.pubads().refresh();
});
});
}

setTimeout(function () {
sendAdserverRequest();
}, FAILSAFE_TIMEOUT);

</script>

<script>
googletag.cmd.push(function () {
googletag.defineSlot('/19968336/header-bid-tag-0', [[300, 250], [300, 600]], 'div-gpt-ad-1460505748561-0').addService(googletag.pubads());

googletag.pubads().enableSingleRequest();
googletag.enableServices();
});
</script>
</head>

<body>
<h2>Prebid.js Test</h2>
<h5>Div-1</h5>
<!-- <button onclick="googletag.cmd.push(function () {googletag.pubads().refresh();});">Refresh GAM</button> -->
<div id='div-gpt-ad-1460505748561-0'>
<script type='text/javascript'>
googletag.cmd.push(function () { googletag.display('div-gpt-ad-1460505748561-0'); });
</script>
</div>
</body>

</html>
12 changes: 12 additions & 0 deletions integrationExamples/gpt/gpp_us_hello_world_iframe.html
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
<!-- start a locally ran server under a different port than 9999 and run gulp serve.
load this page from the local server to properly replicate loading prebid.js within a 3rd party iframe -->
<html>
<head>
<script type="text/javascript" data-cmp-ab="1" src="https://cdn.consentmanager.net/delivery/autoblocking/599af61faf55.js"
data-cmp-host="delivery.consentmanager.net" data-cmp-cdn="cdn.consentmanager.net" data-cmp-codesrc="1"></script>
</head>
<body>
<iframe style="width: 100%; height: 100%;" src="http://test.localhost:9999/integrationExamples/gpt/gpp_us_hello_world_iframe_subpage.html"></iframe>
</body>
</html>

140 changes: 140 additions & 0 deletions integrationExamples/gpt/gpp_us_hello_world_iframe_subpage.html
Original file line number Diff line number Diff line change
@@ -0,0 +1,140 @@
<!--
This page calls a single bidder for a single ad slot. It can be considered a "hello world" example for using
Prebid with the Google Publisher Tag.
It also makes a good test page for new adapter PR submissions. Simply set your server's Bid Params object in the
bids array inside the adUnits, and it will use your adapter to load an ad.
NOTE that many ad servers won't send back an ad if the URL is localhost... so you might need to
set an alias in your /etc/hosts file so that you can load this page from a different domain.
-->

<html>

<head>
<script async src="../../build/dev/prebid.js"></script>
<script async src="https://www.googletagservices.com/tag/js/gpt.js"></script>
<script>
var FAILSAFE_TIMEOUT = 3300;
var PREBID_TIMEOUT = 1000;

var adUnits = [{
code: 'div-gpt-ad-1460505748561-0',
mediaTypes: {
banner: {
sizes: [[300, 250], [300, 600]],
}
},
// Replace this object to test a new Adapter!
bids: [{
bidder: 'appnexus',
params: {
placementId: 13144370
}
}]

}];

var pbjs = pbjs || {};
pbjs.que = pbjs.que || [];

</script>

<script>
var googletag = googletag || {};
googletag.cmd = googletag.cmd || [];
googletag.cmd.push(function () {
googletag.pubads().disableInitialLoad();
});

pbjs.que.push(function () {
pbjs.addAdUnits(adUnits);
pbjs.setConfig({
userSync: {
filterSettings: {
iframe: {
bidders: ['appnexus'],
filter: 'include'
}
}
}
})
pbjs.setConfig({
debug: true,
consentManagement: {
gpp: {
cmpApi: 'iab',
timeout: 5000
},
usp: {
cmpApi: 'static',
consentData: {
getUSPData: {
uspString: '1YYY'
}
}
}
}
})
pbjs.requestBids({
bidsBackHandler: sendAdserverRequest,
timeout: PREBID_TIMEOUT
});
});

function sendAdserverRequest() {
if (pbjs.adserverRequestSent) return;
pbjs.adserverRequestSent = true;
googletag.cmd.push(function () {
pbjs.que.push(function () {
pbjs.setTargetingForGPTAsync();
googletag.pubads().refresh();
});
});
}

// setTimeout(function () {
// sendAdserverRequest();
// }, FAILSAFE_TIMEOUT);

</script>

<script>
googletag.cmd.push(function () {
googletag.defineSlot('/19968336/header-bid-tag-0', [[300, 250], [300, 600]], 'div-gpt-ad-1460505748561-0').addService(googletag.pubads());

googletag.pubads().enableSingleRequest();
googletag.enableServices();
});
</script>
</head>

<body>
<h2>Prebid.js Test</h2>
<h5>Div-1</h5>
<!-- <button onclick="pbjs.que.push(function() {pbjs.setConfig({
consentManagement: {
gpp: {
cmpApi: 'iab',
timeout: 5000
},
usp: {
cmpApi: 'static',
consentData: {
getUSPData: {
uspString: '1YYY'
}
}
}
}
});
pbjs.requestBids({
bidsBackHandler: sendAdserverRequest,
timeout: PREBID_TIMEOUT
});})">Start Auction</button> -->
<div id='div-gpt-ad-1460505748561-0'>
<script type='text/javascript'>
googletag.cmd.push(function () { googletag.display('div-gpt-ad-1460505748561-0'); });
</script>
</div>
</body>

</html>
25 changes: 23 additions & 2 deletions modules/appnexusBidAdapter.js
Original file line number Diff line number Diff line change
Expand Up @@ -304,6 +304,18 @@ export const spec = {
payload.us_privacy = bidderRequest.uspConsent;
}

if (bidderRequest?.gppConsent) {
patmmccann marked this conversation as resolved.
Show resolved Hide resolved
payload.privacy = {
gpp: bidderRequest.gppConsent.gppString,
gpp_sid: bidderRequest.gppConsent.applicableSections
}
} else if (bidderRequest?.ortb2?.regs?.gpp) {
payload.privacy = {
gpp: bidderRequest.ortb2.regs.gpp,
gpp_sid: bidderRequest.ortb2.regs.gpp_sid
}
}

if (bidderRequest && bidderRequest.refererInfo) {
let refererinfo = {
// TODO: are these the correct referer values?
Expand Down Expand Up @@ -424,8 +436,17 @@ export const spec = {
}
},

getUserSyncs: function (syncOptions, responses, gdprConsent) {
if (syncOptions.iframeEnabled && hasPurpose1Consent(gdprConsent)) {
getUserSyncs: function (syncOptions, responses, gdprConsent, uspConsent, gppConsent) {
function checkGppStatus(gppConsent) {
// this is a temporary measure to supress usersync in US-based GPP regions
// this logic will be revised when proper signals (akin to purpose1 from TCF2) can be determined for US GPP
if (gppConsent && Array.isArray(gppConsent.applicableSections)) {
return gppConsent.applicableSections.every(sec => typeof sec === 'number' && sec <= 5);
}
return true;
}

if (syncOptions.iframeEnabled && hasPurpose1Consent(gdprConsent) && checkGppStatus(gppConsent)) {
return [{
type: 'iframe',
url: 'https://acdn.adnxs.com/dmp/async_usersync.html'
Expand Down
7 changes: 6 additions & 1 deletion modules/bidViewability.js
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ import * as events from '../src/events.js';
import CONSTANTS from '../src/constants.json';
import {isFn, logWarn, triggerPixel} from '../src/utils.js';
import {getGlobal} from '../src/prebidGlobal.js';
import adapterManager, {gdprDataHandler, uspDataHandler} from '../src/adapterManager.js';
import adapterManager, {gdprDataHandler, uspDataHandler, gppDataHandler} from '../src/adapterManager.js';
import {find} from '../src/polyfill.js';

const MODULE_NAME = 'bidViewability';
Expand Down Expand Up @@ -44,6 +44,11 @@ export let fireViewabilityPixels = (globalModuleConfig, bid) => {
const uspConsent = uspDataHandler.getConsentData();
if (uspConsent) { queryParams.us_privacy = uspConsent; }

const gppConsent = gppDataHandler.getConsentData();
if (gppConsent) {
// TODO - need to know what to set here for queryParams...
}

bid[BID_VURL_ARRAY].forEach(url => {
// add '?' if not present in URL
if (Object.keys(queryParams).length > 0 && url.indexOf('?') === -1) {
Expand Down
8 changes: 4 additions & 4 deletions modules/consentManagement.js
Original file line number Diff line number Diff line change
Expand Up @@ -94,7 +94,7 @@ function lookupIabConsent({onSuccess, onError}) {
const { cmpFrame, cmpFunction } = findCMP();

if (!cmpFrame) {
return onError('CMP not found.');
return onError('TCF2 CMP not found.');
}
// to collect the consent information from the user, we perform two calls to the CMP in parallel:
// first to collect the user's consent choices represented in an encoded string (via getConsentData)
Expand Down Expand Up @@ -314,11 +314,11 @@ export function resetConsentData() {
* @param {{cmp:string, timeout:number, allowAuctionWithoutConsent:boolean, defaultGdprScope:boolean}} config required; consentManagement module config settings; cmp (string), timeout (int), allowAuctionWithoutConsent (boolean)
*/
export function setConsentConfig(config) {
// if `config.gdpr` or `config.usp` exist, assume new config format.
// if `config.gdpr`, `config.usp` or `config.gpp` exist, assume new config format.
// else for backward compatability, just use `config`
config = config && (config.gdpr || config.usp ? config.gdpr : config);
config = config && (config.gdpr || config.usp || config.gpp ? config.gdpr : config);
if (!config || typeof config !== 'object') {
logWarn('consentManagement config not defined, exiting consent manager');
logWarn('consentManagement (gdpr) config not defined, exiting consent manager');
return;
}
if (isStr(config.cmpApi)) {
Expand Down
Loading