Skip to content

Commit

Permalink
Audigent RTD Provider HaloId Support & RTD Phase 3 Compliance (#5777)
Browse files Browse the repository at this point in the history
* real time data module,
browsi sub module for real time data,
new hook bidsBackCallback,
fix for config unsubscribe

* change timeout&primary ad server only to auctionDelay
update docs

* support multiple providers

* change promise to callbacks
configure submodule on submodules.json

* bug fixes

* use Prebid ajax

* tests fix

* browsi real time data provider improvements

* real time data module,
browsi sub module for real time data,
new hook bidsBackCallback,
fix for config unsubscribe

* change timeout&primary ad server only to auctionDelay
update docs

* support multiple providers

* change promise to callbacks
configure submodule on submodules.json

* bug fixes

* use Prebid ajax

* tests fix

* browsi real time data provider improvements

* RTD module extend #4610

* add hook for submodule init
variables naming

* RTD bug fix

* remove auction delay and related hooks

* update audigent rtd provider

* style update

* change onDone() logic

* RTD phase 3

* return on data unavailable

* api endpoint update

* update audigent RTD provider for new spec

* design changes

* fix loop continuation

* proper fix this time

* linter

* update rtd parameters, onDone semantics

* reduce loops

* documentation update

* working update to rtd3 spec, update segment example, documentation

* remove unused vars, reference module name

* resolve haloid for segments

* update documentation to markdown

* update description in documentation

* minify optimizations

Co-authored-by: omerdotan <[email protected]>
Co-authored-by: bretg <[email protected]>
  • Loading branch information
3 people authored Oct 20, 2020
1 parent 5d9a0e6 commit c4eb742
Show file tree
Hide file tree
Showing 4 changed files with 202 additions and 139 deletions.
86 changes: 65 additions & 21 deletions integrationExamples/gpt/audigentSegments_example.html
Original file line number Diff line number Diff line change
Expand Up @@ -84,11 +84,10 @@
{
code: 'test-div',
mediaTypes: {
banner: {
sizes: [[300,250],[300,600],[728,90]]
}
banner: {
sizes: [[300,250],[300,600],[728,90]]
}
},

bids: [
{
bidder: 'rubicon',
Expand Down Expand Up @@ -120,20 +119,9 @@
consentManagement: {
cmpApi: 'iab',
timeout: 1000,
allowAuctionWithoutConsent: true
defaultGdprScope: true
},
// consentManagement: {
// cmpApi: 'static',
// consentData: {
// consentString: 'BOEFEAyOEFEAyAHABDENAI4AAAB9vABAASA'
// vendorData: {
// purposeConsents: {
// '1': true
// }
// }
// }
// },
usersync: {
userSync: {
userIds: [{
name: "unifiedId",
params: {
Expand All @@ -145,6 +133,16 @@
name: "unifiedid",
expires: 30
},
}, {
name: "intentIqId",
params: {
partner: 0, //Set your real IntentIQ partner ID here for production.
},
storage: {
type: "cookie",
name: "intentIqId",
expires: 30
},
}, {
name: "id5Id",
params: {
Expand All @@ -157,6 +155,18 @@
refreshInSeconds: 8*3600 // Refresh frequency of cookies, defaulting to 'expires'
},

}, {
name: "merkleId",
params: {
ptk: '12345678-aaaa-bbbb-cccc-123456789abc', //Set your real merkle partner key here
pubid: 'EXAMPLE' //Set your real merkle publisher id here
},
storage: {
type: "html5",
name: "merkleId",
expires: 30
},

}, {
name: "parrableId",
params: {
Expand All @@ -174,7 +184,7 @@
// foo: '9879878907987',
// bar:'93939'
// }
}, {
}, {
name: 'identityLink',
params: {
pid: '14' // Set your real identityLink placement ID here
Expand All @@ -184,13 +194,46 @@
name: 'idl_env',
expires: 30
}
}, {
name: "sharedId",
params: {
syncTime: 60 // in seconds, default is 24 hours
},
storage: {
type: "cookie",
name: "sharedid",
expires: 28
}
}, {
name: 'lotamePanoramaId'
}, {
name: "liveIntentId",
params: {
publisherId: "9896876"
},
storage: {
type: "cookie",
name: "_li_pbid",
expires: 28
}
}, {
name: "zeotapIdPlus"
}, {
name: 'haloId',
storage: {
type: "cookie",
name: "haloId",
expires: 28
}
}, {
name: "quantcastId"
}],
syncDelay: 5000,
auctionDelay: 1000
auctionDelay: 1000
},
realTimeData: {
auctionDelay: 1000,
dataProviders: [{name: "audigent"}]
dataProviders: [{name: "audigent", waitForIt: true}]
}
});
pbjs.addAdUnits(adUnits);
Expand All @@ -199,7 +242,7 @@

function sendAdserverRequest() {
document.getElementById('tdid').innerHTML = adUnits[0].bids[0].userId['tdid'];
document.getElementById('audigent_segments').innerHTML = JSON.stringify(adUnits[0].bids[0].realTimeData.audigent_segments);
document.getElementById('audigent_segments').innerHTML = JSON.stringify(adUnits[0].bids[0].audigent_segments);

if (pbjs.adserverRequestSent) return;
pbjs.adserverRequestSent = true;
Expand Down Expand Up @@ -246,6 +289,7 @@ <h2>Audigent Segments Prebid</h2>
googletag.cmd.push(function() { googletag.display('test-div'); });
</script>
</div>

TDID:
<div id='tdid'>
</div>
Expand Down
174 changes: 89 additions & 85 deletions modules/audigentRtdProvider.js
Original file line number Diff line number Diff line change
Expand Up @@ -5,17 +5,6 @@
* @module modules/audigentRtdProvider
* @requires module:modules/realTimeData
*/

/**
* @typedef {Object} ModuleParams
* @property {string} siteKey
* @property {string} pubKey
* @property {string} url
* @property {?string} keyName
* @property {number} auctionDelay
*/

import {config} from '../src/config.js';
import {getGlobal} from '../src/prebidGlobal.js';
import * as utils from '../src/utils.js';
import {submodule} from '../src/hook.js';
Expand All @@ -26,116 +15,131 @@ const storage = getStorageManager();

/** @type {string} */
const MODULE_NAME = 'realTimeData';

/** @type {ModuleParams} */
let _moduleParams = {};
const SUBMODULE_NAME = 'audigent';
const HALOID_LOCAL_NAME = 'auHaloId';
const SEG_LOCAL_NAME = '__adgntseg';

/**
* XMLHttpRequest to get data form audigent server
* @param {string} url server url with query params
* decorate adUnits with segment data
* @param {adUnit[]} adUnits
* @param {Object} data
*/
function addSegmentData(adUnits, data) {
adUnits.forEach(adUnit => {
if (adUnit.hasOwnProperty('bids')) {
adUnit.bids.forEach(bid => {
bid.audigent_segments = data;
})
}
})

export function setData(data) {
storage.setDataInLocalStorage('__adgntseg', JSON.stringify(data));
return adUnits;
}

function getSegments(adUnits, onDone) {
try {
let jsonData = storage.getDataFromLocalStorage('__adgntseg');
if (jsonData) {
let data = JSON.parse(jsonData);
if (data.audigent_segments) {
let dataToReturn = adUnits.reduce((rp, cau) => {
const adUnitCode = cau && cau.code;
if (!adUnitCode) { return rp }
rp[adUnitCode] = data;
return rp;
}, {});

onDone(dataToReturn);
return;
}
/**
* segment retrieval from audigent's backends
* @param {Object} reqBidsConfigObj
* @param {function} onDone
* @param {Object} config
* @param {Object} userConsent
*/
function getSegments(reqBidsConfigObj, onDone, config, userConsent) {
const adUnits = reqBidsConfigObj.adUnits || getGlobal().adUnits;

let jsonData = storage.getDataFromLocalStorage(SEG_LOCAL_NAME);
if (jsonData) {
let data = JSON.parse(jsonData);
if (data.audigent_segments) {
addSegmentData(adUnits, data.audigent_segments);
onDone();
return;
}
getSegmentsAsync(adUnits, onDone);
} catch (e) {
getSegmentsAsync(adUnits, onDone);
}
}

function getSegmentsAsync(adUnits, onDone) {
const userIds = (getGlobal()).getUserIds();
let tdid = null;
if (typeof userIds == 'undefined' || userIds == null) {
onDone();
return;
}

if (userIds && userIds['tdid']) {
tdid = userIds['tdid'];
let haloId = storage.getDataFromLocalStorage(HALOID_LOCAL_NAME);
if (haloId) {
userIds.haloId = haloId;
getSegmentsAsync(adUnits, onDone, config, userConsent, userIds);
} else {
onDone({});
var script = document.createElement('script')
script.type = 'text/javascript';

script.onload = function() {
userIds.haloId = storage.getDataFromLocalStorage(HALOID_LOCAL_NAME);
getSegmentsAsync(adUnits, onDone, config, userConsent, userIds);
}

script.src = 'https://id.halo.ad.gt/api/v1/haloid';
document.getElementsByTagName('head')[0].appendChild(script);
}
}

const url = `https://seg.ad.gt/api/v1/rtb_segments?tdid=${tdid}`;
/**
* async segment retrieval from audigent's backends
* @param {adUnit[]} adUnits
* @param {function} onDone
* @param {Object} config
* @param {Object} userConsent
* @param {Object} userIds
*/
function getSegmentsAsync(adUnits, onDone, config, userConsent, userIds) {
let reqParams = {}
if (typeof config == 'object' && config != null && Object.keys(config).length > 0) {
reqParams = config.params
}

const url = `https://seg.halo.ad.gt/api/v1/rtb_segments`;
ajax(url, {
success: function (response, req) {
if (req.status === 200) {
try {
const data = JSON.parse(response);
if (data && data.audigent_segments) {
setData(data);
let dataToReturn = adUnits.reduce((rp, cau) => {
const adUnitCode = cau && cau.code;
if (!adUnitCode) { return rp }
rp[adUnitCode] = data;
return rp;
}, {});

onDone(dataToReturn);
addSegmentData(adUnits, data.audigent_segments);
onDone();
storage.setDataInLocalStorage(SEG_LOCAL_NAME, JSON.stringify(data));
} else {
onDone({});
onDone();
}
} catch (err) {
utils.logError('unable to parse audigent segment data');
onDone({})
onDone();
}
} else if (req.status === 204) {
// unrecognized site key
onDone({});
// unrecognized partner config
onDone();
}
},
error: function () {
onDone({});
onDone();
utils.logError('unable to get audigent segment data');
}
}
},
JSON.stringify({'userIds': userIds, 'config': reqParams}),
{contentType: 'application/json'}
);
}

/**
* module init
* @param {Object} config
* @return {boolean}
*/
export function init(config) {
return true;
}

/** @type {RtdSubmodule} */
export const audigentSubmodule = {
/**
* used to link submodule with realTimeData
* @type {string}
*/
name: 'audigent',
/**
* get data and send back to realTimeData module
* @function
* @param {adUnit[]} adUnits
* @param {function} onDone
*/
getData: getSegments
name: SUBMODULE_NAME,
getBidRequestData: getSegments,
init: init
};

export function init(config) {
const confListener = config.getConfig(MODULE_NAME, ({realTimeData}) => {
try {
_moduleParams = realTimeData.dataProviders && realTimeData.dataProviders.filter(pr => pr.name && pr.name.toLowerCase() === 'audigent')[0].params;
_moduleParams.auctionDelay = realTimeData.auctionDelay;
} catch (e) {
_moduleParams = {};
}
confListener();
});
}

submodule('realTimeData', audigentSubmodule);
init(config);
submodule(MODULE_NAME, audigentSubmodule);
Loading

0 comments on commit c4eb742

Please sign in to comment.