Skip to content

Commit

Permalink
Invibes Bid Adapter : infinite scroll tcf (#10764)
Browse files Browse the repository at this point in the history
* added prevent page view event param in order to differentiate from the first and following request on multi request; added disableUserSyncs in order to disable that functionality as default and added the option to activate it from the bidRequest

* added infinite scroll and page refresh params, updated tcf, changed randomId to guid, updated the subdomain

* reverted subdomain

* Update invibesBidAdapter.js with code review suggestion

* Moved new variables to invibes object

* Update invibesBidAdapter.js add placementIds to invibes object

* initialized window.invibes
  • Loading branch information
gabrielIvbs authored Dec 12, 2023
1 parent fd35856 commit 1c4bc7a
Show file tree
Hide file tree
Showing 2 changed files with 149 additions and 6 deletions.
56 changes: 50 additions & 6 deletions modules/invibesBidAdapter.js
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ const CONSTANTS = {
SYNC_ENDPOINT: 'https://k.r66net.com/GetUserSync',
TIME_TO_LIVE: 300,
DEFAULT_CURRENCY: 'EUR',
PREBID_VERSION: 10,
PREBID_VERSION: 11,
METHOD: 'GET',
INVIBES_VENDOR_ID: 436,
USERID_PROVIDERS: ['pubcid', 'pubProvidedId', 'uid2', 'zeotapIdPlus', 'id5id'],
Expand Down Expand Up @@ -49,14 +49,36 @@ registerBidder(spec);
// some state info is required: cookie info, unique user visit id
const topWin = getTopMostWindow();
let invibes = topWin.invibes = topWin.invibes || {};
invibes.purposes = invibes.purposes || [false, false, false, false, false, false, false, false, false, false];
invibes.legitimateInterests = invibes.legitimateInterests || [false, false, false, false, false, false, false, false, false, false];
invibes.purposes = invibes.purposes || [false, false, false, false, false, false, false, false, false, false, false];
invibes.legitimateInterests = invibes.legitimateInterests || [false, false, false, false, false, false, false, false, false, false, false];
invibes.placementBids = invibes.placementBids || [];
invibes.pushedCids = invibes.pushedCids || {};
let preventPageViewEvent = false;
let isInfiniteScrollPage = false;
let isPlacementRefresh = false;
let _customUserSync;
let _disableUserSyncs;

function updateInfiniteScrollFlag() {
const { scrollHeight } = document.documentElement;

if (invibes.originalURL === undefined) {
invibes.originalURL = window.location.href;
return;
}

if (invibes.originalScrollHeight === undefined) {
invibes.originalScrollHeight = scrollHeight;
return;
}

const currentURL = window.location.href;

if (scrollHeight > invibes.originalScrollHeight && invibes.originalURL !== currentURL) {
isInfiniteScrollPage = true;
}
}

function isBidRequestValid(bid) {
if (typeof bid.params !== 'object') {
return false;
Expand Down Expand Up @@ -87,10 +109,24 @@ function buildRequest(bidRequests, bidderRequest) {
const _placementIds = [];
const _adUnitCodes = [];
let _customEndpoint, _userId, _domainId;
let _ivAuctionStart = bidderRequest.auctionStart || Date.now();
let _ivAuctionStart = Date.now();
window.invibes = window.invibes || {};
window.invibes.placementIds = window.invibes.placementIds || [];

if (isInfiniteScrollPage == false) {
updateInfiniteScrollFlag();
}

bidRequests.forEach(function (bidRequest) {
bidRequest.startTime = new Date().getTime();

if (window.invibes.placementIds.includes(bidRequest.params.placementId)) {
isPlacementRefresh = true;
}

window.invibes.placementIds.push(bidRequest.params.placementId);

_placementIds.push(bidRequest.params.placementId);
_placementIds.push(bidRequest.params.placementId);
_adUnitCodes.push(bidRequest.adUnitCode);
_domainId = _domainId || bidRequest.params.domainId;
Expand Down Expand Up @@ -138,6 +174,8 @@ function buildRequest(bidRequests, bidderRequest) {
tc: invibes.gdpr_consent,
isLocalStorageEnabled: storage.hasLocalStorage(),
preventPageViewEvent: preventPageViewEvent,
isPlacementRefresh: isPlacementRefresh,
isInfiniteScrollPage: isInfiniteScrollPage,
};

let lid = readFromLocalStorage('ivbsdid');
Expand Down Expand Up @@ -368,7 +406,9 @@ function addMeta(bidModelMeta) {
}

function generateRandomId() {
return (Math.round(Math.random() * 1e12)).toString(36).substring(0, 10);
return '10000000100040008000100000000000'.replace(/[018]/g, c =>
(c ^ crypto.getRandomValues(new Uint8Array(1))[0] & 15 >> c / 4).toString(16)
);
}

function getDocumentLocation(bidderRequest) {
Expand Down Expand Up @@ -568,7 +608,7 @@ function readGdprConsent(gdprConsent) {
}

let legitimateInterests = getLegitimateInterests(gdprConsent.vendorData);
tryCopyValueToArray(legitimateInterests, invibes.legitimateInterests, 10);
tryCopyValueToArray(legitimateInterests, invibes.legitimateInterests, purposesLength);

let invibesVendorId = CONSTANTS.INVIBES_VENDOR_ID.toString(10);
let vendorConsents = getVendorConsents(gdprConsent.vendorData);
Expand Down Expand Up @@ -621,6 +661,10 @@ function tryCopyValueToArray(value, target, length) {

function getPurposeConsentsCounter(vendorData) {
if (vendorData.purpose && vendorData.purpose.consents) {
if (vendorData.tcfPolicyVersion >= 4) {
return 11;
}

return 10;
}

Expand Down
99 changes: 99 additions & 0 deletions test/spec/modules/invibesBidAdapter_spec.js
Original file line number Diff line number Diff line change
Expand Up @@ -44,6 +44,78 @@ describe('invibesBidAdapter:', function () {
}
];

let bidRequestsWithDuplicatedplacementId = [
{
bidId: 'b1',
bidder: BIDDER_CODE,
bidderRequestId: 'r1',
params: {
placementId: PLACEMENT_ID,
disableUserSyncs: false

},
adUnitCode: 'test-div1',
auctionId: 'a1',
sizes: [
[300, 250],
[400, 300],
[125, 125]
],
transactionId: 't1'
}, {
bidId: 'b2',
bidder: BIDDER_CODE,
bidderRequestId: 'r2',
params: {
placementId: PLACEMENT_ID,
disableUserSyncs: false
},
adUnitCode: 'test-div2',
auctionId: 'a2',
sizes: [
[300, 250],
[400, 300]
],
transactionId: 't2'
}
];

let bidRequestsWithUniquePlacementId = [
{
bidId: 'b1',
bidder: BIDDER_CODE,
bidderRequestId: 'r1',
params: {
placementId: 'PLACEMENT_ID_1',
disableUserSyncs: false

},
adUnitCode: 'test-div1',
auctionId: 'a1',
sizes: [
[300, 250],
[400, 300],
[125, 125]
],
transactionId: 't1'
}, {
bidId: 'b2',
bidder: BIDDER_CODE,
bidderRequestId: 'r2',
params: {
placementId: 'PLACEMENT_ID_2',
disableUserSyncs: false
},
adUnitCode: 'test-div2',
auctionId: 'a2',
sizes: [
[300, 250],
[400, 300]
],
transactionId: 't2'
}
];

let bidRequestsWithUserId = [
{
bidId: 'b1',
Expand Down Expand Up @@ -185,17 +257,44 @@ describe('invibesBidAdapter:', function () {
expect(request.data.preventPageViewEvent).to.be.false;
});

it('sends isPlacementRefresh as false when the placement ids are used for the first time', function () {
let request = spec.buildRequests(bidRequestsWithUniquePlacementId, bidderRequestWithPageInfo);
expect(request.data.isPlacementRefresh).to.be.false;
});

it('sends preventPageViewEvent as true on 2nd call', function () {
let request = spec.buildRequests(bidRequests, bidderRequestWithPageInfo);
expect(request.data.preventPageViewEvent).to.be.true;
});

it('sends isPlacementRefresh as true on multi requests on the same placement id', function () {
let request = spec.buildRequests(bidRequestsWithDuplicatedplacementId, bidderRequestWithPageInfo);
expect(request.data.isPlacementRefresh).to.be.true;
});

it('sends isInfiniteScrollPage as false initially', function () {
let request = spec.buildRequests(bidRequests, bidderRequestWithPageInfo);
expect(request.data.isInfiniteScrollPage).to.be.false;
});

it('sends isPlacementRefresh as true on multi requests multiple calls with the same placement id from second call', function () {
let request = spec.buildRequests(bidRequests, bidderRequestWithPageInfo);
expect(request.data.isInfiniteScrollPage).to.be.false;
let duplicatedRequest = spec.buildRequests(bidRequests, bidderRequestWithPageInfo);
expect(duplicatedRequest.data.isPlacementRefresh).to.be.true;
});

it('sends bid request to ENDPOINT via GET', function () {
const request = spec.buildRequests(bidRequests, bidderRequestWithPageInfo);
expect(request.url).to.equal(ENDPOINT);
expect(request.method).to.equal('GET');
});

it('generates a visitId of length 32', function () {
spec.buildRequests(bidRequests, bidderRequestWithPageInfo);
expect(top.window.invibes.visitId.length).to.equal(32);
});

it('sends bid request to custom endpoint via GET', function () {
const request = spec.buildRequests([{
bidId: 'b1',
Expand Down

0 comments on commit 1c4bc7a

Please sign in to comment.