Skip to content

Commit

Permalink
NoBid Analytics Adapter: support for counting blocked requests for th…
Browse files Browse the repository at this point in the history
…e Optimizer (#10842)

* Enable supplyChain support

* Added support for COPPA

* rebuilt

* Added support for Extended User IDs.

* Added support for the "meta" attribute in bid response.

* Delete nobidBidAdapter.js.orig

* Delete a

* Delete .jsdtscope

* Delete org.eclipse.wst.jsdt.ui.superType.container

* Delete org.eclipse.wst.jsdt.ui.superType.name

* Delete .project

* Added support for counting blocked requests for the Optimizer.

* Added missing function for testing.

* Added unit tests

---------

Co-authored-by: Reda Guermas <reda.guermas@nobid.io>
  • Loading branch information
redaguermas and Reda Guermas authored Dec 20, 2023
1 parent cd787eb commit 0b59d4d
Show file tree
Hide file tree
Showing 2 changed files with 61 additions and 14 deletions.
67 changes: 55 additions & 12 deletions modules/nobidAnalyticsAdapter.js
Original file line number Diff line number Diff line change
Expand Up @@ -6,10 +6,10 @@ import CONSTANTS from '../src/constants.json';
import adapterManager from '../src/adapterManager.js';
import {MODULE_TYPE_ANALYTICS} from '../src/activities/modules.js';

const VERSION = '1.0.4';
const VERSION = '1.1.0';
const MODULE_NAME = 'nobidAnalyticsAdapter';
const ANALYTICS_DATA_NAME = 'analytics.nobid.io';
const RETENTION_SECONDS = 7 * 24 * 3600;
const ANALYTICS_OPT_FLUSH_TIMEOUT_SECONDS = 5 * 1000;
const RETENTION_SECONDS = 1 * 24 * 3600;
const TEST_ALLOCATION_PERCENTAGE = 5; // dont block 5% of the time;
window.nobidAnalyticsVersion = VERSION;
const analyticsType = 'endpoint';
Expand Down Expand Up @@ -148,7 +148,7 @@ nobidAnalytics = {
return isExpired(data, this.retentionSeconds);
},
isAnalyticsDisabled () {
let stored = storage.getDataFromLocalStorage(ANALYTICS_DATA_NAME);
let stored = storage.getDataFromLocalStorage(this.ANALYTICS_DATA_NAME);
if (!isJson(stored)) return false;
stored = JSON.parse(stored);
if (this.isExpired(stored)) return false;
Expand All @@ -157,42 +157,85 @@ nobidAnalytics = {
processServerResponse (response) {
if (!isJson(response)) return;
const resp = JSON.parse(response);
storage.setDataInLocalStorage(ANALYTICS_DATA_NAME, JSON.stringify({ ...resp, ts: Date.now() }));
}
storage.setDataInLocalStorage(this.ANALYTICS_DATA_NAME, JSON.stringify({ ...resp, ts: Date.now() }));
},
ANALYTICS_DATA_NAME: 'analytics.nobid.io',
ANALYTICS_OPT_NAME: 'analytics.nobid.io.optData'
}

adapterManager.registerAnalyticsAdapter({
adapter: nobidAnalytics,
code: 'nobidAnalytics',
gvlid: GVLID
});
nobidAnalytics.originalAdUnits = {};
window.nobidCarbonizer = {
getStoredLocalData: function () {
return storage.getDataFromLocalStorage(ANALYTICS_DATA_NAME);
const a = storage.getDataFromLocalStorage(nobidAnalytics.ANALYTICS_DATA_NAME);
const b = storage.getDataFromLocalStorage(nobidAnalytics.ANALYTICS_OPT_NAME);
const ret = {};
if (a) ret[nobidAnalytics.ANALYTICS_DATA_NAME] = a;
if (b) ret[nobidAnalytics.ANALYTICS_OPT_NAME] = b
return ret;
},
isActive: function () {
let stored = storage.getDataFromLocalStorage(ANALYTICS_DATA_NAME);
let stored = storage.getDataFromLocalStorage(nobidAnalytics.ANALYTICS_DATA_NAME);
if (!isJson(stored)) return false;
stored = JSON.parse(stored);
if (isExpired(stored, nobidAnalytics.retentionSeconds)) return false;
return stored.carbonizer_active || false;
},
carbonizeAdunits: function (adunits, skipTestGroup) {
function processBlockedBidders (blockedBidders) {
function sendOptimizerData() {
let optData = storage.getDataFromLocalStorage(nobidAnalytics.ANALYTICS_OPT_NAME);
storage.removeDataFromLocalStorage(nobidAnalytics.ANALYTICS_OPT_NAME);
if (isJson(optData)) {
optData = JSON.parse(optData);
if (Object.getOwnPropertyNames(optData).length > 0) {
const event = { o_bidders: optData };
if (nobidAnalytics.topLocation) event.topLocation = nobidAnalytics.topLocation;
sendEvent(event, 'optData');
}
}
}
if (blockedBidders && blockedBidders.length > 0) {
let optData = storage.getDataFromLocalStorage(nobidAnalytics.ANALYTICS_OPT_NAME);
optData = isJson(optData) ? JSON.parse(optData) : {};
const bidders = blockedBidders.map(rec => rec.bidder);
if (bidders && bidders.length > 0) {
bidders.forEach(bidder => {
if (!optData[bidder]) optData[bidder] = 1;
else optData[bidder] += 1;
});
storage.setDataInLocalStorage(nobidAnalytics.ANALYTICS_OPT_NAME, JSON.stringify(optData));
if (window.nobidAnalyticsOptTimer) return;
window.nobidAnalyticsOptTimer = setInterval(sendOptimizerData, ANALYTICS_OPT_FLUSH_TIMEOUT_SECONDS);
}
}
}
function carbonizeAdunit (adunit) {
let stored = storage.getDataFromLocalStorage(ANALYTICS_DATA_NAME);
let stored = storage.getDataFromLocalStorage(nobidAnalytics.ANALYTICS_DATA_NAME);
if (!isJson(stored)) return;
stored = JSON.parse(stored);
if (isExpired(stored, nobidAnalytics.retentionSeconds)) return;
const carbonizerBidders = stored.bidders || [];
const allowedBidders = adunit.bids.filter(rec => carbonizerBidders.includes(rec.bidder));
let originalAdUnit = null;
if (nobidAnalytics.originalAdUnits && nobidAnalytics.originalAdUnits[adunit.code]) originalAdUnit = nobidAnalytics.originalAdUnits[adunit.code];
const allowedBidders = originalAdUnit.bids.filter(rec => carbonizerBidders.includes(rec.bidder));
const blockedBidders = originalAdUnit.bids.filter(rec => !carbonizerBidders.includes(rec.bidder));
processBlockedBidders(blockedBidders);
adunit.bids = allowedBidders;
}
for (const adunit of adunits) {
if (!nobidAnalytics.originalAdUnits[adunit.code]) nobidAnalytics.originalAdUnits[adunit.code] = JSON.parse(JSON.stringify(adunit));
};
if (this.isActive()) {
// 5% of the time do not block;
if (!skipTestGroup && Math.floor(Math.random() * 101) <= TEST_ALLOCATION_PERCENTAGE) return;
adunits.forEach(adunit => {
for (const adunit of adunits) {
carbonizeAdunit(adunit);
});
};
}
}
};
Expand Down
8 changes: 6 additions & 2 deletions test/spec/modules/nobidAnalyticsAdapter_spec.js
Original file line number Diff line number Diff line change
Expand Up @@ -466,8 +466,8 @@ describe('NoBid Prebid Analytic', function () {
const previousRetention = nobidAnalytics.retentionSeconds;
nobidAnalytics.retentionSeconds = 3;
nobidAnalytics.processServerResponse(JSON.stringify({carbonizer_active: true}));
const stored = nobidCarbonizer.getStoredLocalData();
expect(stored).to.contain(`{"carbonizer_active":true,"ts":`);
let stored = nobidCarbonizer.getStoredLocalData();
expect(stored[nobidAnalytics.ANALYTICS_DATA_NAME]).to.contain(`{"carbonizer_active":true,"ts":`);
clock.tick(5000);
active = nobidCarbonizer.isActive(adunits, true);
expect(active).to.equal(false);
Expand All @@ -486,6 +486,10 @@ describe('NoBid Prebid Analytic', function () {
}
]
nobidCarbonizer.carbonizeAdunits(adunits, true);
stored = nobidCarbonizer.getStoredLocalData();
expect(stored[nobidAnalytics.ANALYTICS_DATA_NAME]).to.contain('{"carbonizer_active":true,"ts":');
expect(stored[nobidAnalytics.ANALYTICS_OPT_NAME]).to.contain('{"bidder1":1,"bidder2":1}');
clock.tick(5000);
expect(adunits[0].bids.length).to.equal(0);

done();
Expand Down

0 comments on commit 0b59d4d

Please sign in to comment.