Skip to content

Commit

Permalink
Bid Viewability Module: Support Core's Billing Deferral Logic (prebid…
Browse files Browse the repository at this point in the history
…#10326)

* wrote tests

* reverted changes used for dev debugging

* minor change

* updated markdown file
  • Loading branch information
jlquaccia authored and Santiago Carabone committed Aug 22, 2023
1 parent 3b1f22c commit a4fa473
Show file tree
Hide file tree
Showing 3 changed files with 48 additions and 9 deletions.
7 changes: 7 additions & 0 deletions modules/bidViewability.js
Original file line number Diff line number Diff line change
Expand Up @@ -67,13 +67,20 @@ export let logWinningBidNotFound = (slot) => {

export let impressionViewableHandler = (globalModuleConfig, slot, event) => {
let respectiveBid = getMatchingWinningBidForGPTSlot(globalModuleConfig, slot);
let respectiveDeferredAdUnit = getGlobal().adUnits.find(adUnit => adUnit.deferBilling && respectiveBid.adUnitCode === adUnit.code);

if (respectiveBid === null) {
logWinningBidNotFound(slot);
} else {
// if config is enabled AND VURL array is present then execute each pixel
fireViewabilityPixels(globalModuleConfig, respectiveBid);
// trigger respective bidder's onBidViewable handler
adapterManager.callBidViewableBidder(respectiveBid.adapterCode || respectiveBid.bidder, respectiveBid);

if (respectiveDeferredAdUnit) {
adapterManager.callBidBillableBidder(respectiveBid);
}

// emit the BID_VIEWABLE event with bid details, this event can be consumed by bidders and analytics pixels
events.emit(CONSTANTS.EVENTS.BID_VIEWABLE, respectiveBid);
}
Expand Down
17 changes: 9 additions & 8 deletions modules/bidViewability.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,19 +2,20 @@

Module Name: bidViewability

Purpose: Track when a bid is viewable
Purpose: Track when a bid is viewable (and also ready for billing)

Maintainer: harshad.mane@pubmatic.com

# Description
- This module, when included, will trigger a BID_VIEWABLE event which can be consumed by Analytics adapters, bidders will need to implement `onBidViewable` method to capture this event
- Bidderes can check if this module is part of the final build and whether it is enabled or not by accessing ```pbjs.getConfig('bidViewability')```
- This module, when included, will trigger a BID_VIEWABLE event which can be consumed by Analytics adapters, bidders will need to implement the `onBidViewable` method to capture this event
- Bidders can check if this module is part of the final build and whether it is enabled or not by accessing ```pbjs.getConfig('bidViewability')```
- GPT API is used to find when a bid is viewable, https://developers.google.com/publisher-tag/reference#googletag.events.impressionviewableevent . This event is fired when an impression becomes viewable, according to the Active View criteria.
Refer: https://support.google.com/admanager/answer/4524488
- The module does not work with adserver other than GAM with GPT integration
- This module does not work with any adserver's other than GAM with GPT integration
- Logic used to find a matching pbjs-bid for a GPT slot is ``` (slot.getAdUnitPath() === bid.adUnitCode || slot.getSlotElementId() === bid.adUnitCode) ``` this logic can be changed by using param ```customMatchFunction```
- When a rendered PBJS bid is viewable the module will trigger BID_VIEWABLE event, which can be consumed by bidders and analytics adapters
- For the viewable bid if ```bid.vurls type array``` param is and module config ``` firePixels: true ``` is set then the URLs mentioned in bid.vurls will be executed. Please note that GDPR and USP related parameters will be added to the given URLs
- When a rendered PBJS bid is viewable the module will trigger a BID_VIEWABLE event, which can be consumed by bidders and analytics adapters
- If the viewable bid contains a ```vurls``` param containing URL's and the Bid Viewability module is configured with ``` firePixels: true ``` then the URLs mentioned in bid.vurls will be called. Please note that GDPR and USP related parameters will be added to the given URLs
- This module is also compatible with Prebid core's billing deferral logic, this means that bids linked to an ad unit marked with `deferBilling: true` will trigger a bid adapter's `onBidBillable` function (if present) indicating an ad slot was viewed and also billing ready (if it were deferred).

# Params
- enabled [required] [type: boolean, default: false], when set to true, the module will emit BID_VIEWABLE when applicable
Expand Down Expand Up @@ -44,6 +45,6 @@ Refer: https://support.google.com/admanager/answer/4524488
```

# Please Note:
- Doesn't seems to work with Instream Video, https://docs.prebid.org/dev-docs/examples/instream-banner-mix.html as GPT's impressionViewable event is not triggered for instream-video-creative
- Works with Banner, Outsteam, Native creatives
- This module doesn't seem to work with Instream Video, https://docs.prebid.org/dev-docs/examples/instream-banner-mix.html as GPT's impressionViewable event is not triggered for instream-video-creative
- Works with Banner, Outsteam and Native creatives

33 changes: 32 additions & 1 deletion test/spec/modules/bidViewability_spec.js
Original file line number Diff line number Diff line change
Expand Up @@ -245,18 +245,31 @@ describe('#bidViewability', function() {
let logWinningBidNotFoundSpy;
let callBidViewableBidderSpy;
let winningBidsArray;
let callBidBillableBidderSpy;
let adUnits = [
{
'code': 'abc123',
'bids': [
{
'bidder': 'pubmatic'
}
]
}
];

beforeEach(function() {
sandbox = sinon.sandbox.create();
triggerPixelSpy = sandbox.spy(utils, ['triggerPixel']);
eventsEmitSpy = sandbox.spy(events, ['emit']);
callBidViewableBidderSpy = sandbox.spy(adapterManager, ['callBidViewableBidder']);
callBidBillableBidderSpy = sandbox.spy(adapterManager, ['callBidBillableBidder']);
// mocking winningBidsArray
winningBidsArray = [];
sandbox.stub(prebidGlobal, 'getGlobal').returns({
getAllWinningBids: function (number) {
return winningBidsArray;
}
},
adUnits
});
});

Expand Down Expand Up @@ -293,5 +306,23 @@ describe('#bidViewability', function() {
// CONSTANTS.EVENTS.BID_VIEWABLE is NOT triggered
expect(eventsEmitSpy.callCount).to.equal(0);
});

it('should call the callBidBillableBidder function if the viewable bid is associated with an ad unit with deferBilling set to true', function() {
let moduleConfig = {};
const deferredBillingAdUnit = {
'code': '/harshad/Jan/2021/',
'deferBilling': true,
'bids': [
{
'bidder': 'pubmatic'
}
]
};
adUnits.push(deferredBillingAdUnit);
winningBidsArray.push(PBJS_WINNING_BID);
bidViewability.impressionViewableHandler(moduleConfig, GPT_SLOT, null);
expect(callBidBillableBidderSpy.callCount).to.equal(1);
sinon.assert.calledWith(callBidBillableBidderSpy, PBJS_WINNING_BID);
});
});
});

0 comments on commit a4fa473

Please sign in to comment.