-
Notifications
You must be signed in to change notification settings - Fork 2.1k
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
Prebid Core: Functionality to Optionally Defer Billing for an Ad #9640
Conversation
src/adapterManager.js
Outdated
@@ -616,6 +616,12 @@ adapterManager.callBidWonBidder = function(bidder, bid, adUnits) { | |||
tryCallBidderMethod(bidder, 'onBidWon', bid); | |||
}; | |||
|
|||
adapterManager.callBidBillableBidder = function(bidder, bid, adUnits) { | |||
// Adding user configured params to bidWon event data | |||
bid.params = getUserConfiguredParams(adUnits, bid.adUnitCode, bid.bidder); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I don't think this is necessary. It's already happened in bidWon, and even there I'd question it.
src/auction.js
Outdated
function addWinningBid(winningBid) { | ||
function addWinningBid(winningBid, aUnits = adUnits, am = adapterManager) { | ||
const { adUnitCode } = winningBid; | ||
const winningAd = aUnits.find(adUnit => adUnit.code === adUnitCode); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think transactionId
is a better ID than code
. Multiple adUnits can have the same code.
src/prebid.js
Outdated
/** | ||
* @alias module:pbjs.triggerBilling | ||
*/ | ||
$$PREBID_GLOBAL$$.triggerBilling = (bidder, bid, adUnits, am = adapterManager) => { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
this is a public method, so its interface should be kept clean - I don't think you need anything more than bid
.
src/auction.js
Outdated
@@ -363,9 +363,12 @@ export function newAuction({adUnits, adUnitCodes, callback, cbTimeout, labels, a | |||
} | |||
} | |||
|
|||
function addWinningBid(winningBid) { | |||
function addWinningBid(winningBid, aUnits = adUnits, am = adapterManager) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think this is overdoing dependency injection - adUnits
is already something you can pass in directly to the constructor; adapterManger
could also be if you want it injected, it doesn't make a lot of sense to do it in just one method - the next guy will need to reason about an auction
with tightly coupled methods but completely disjointed depedendencies.
thanks @dgirardi, went back to address your feedback and also refactored a bit. let me know if anything else is needed. |
src/prebid.js
Outdated
/** | ||
* @alias module:pbjs.triggerBilling | ||
*/ | ||
$$PREBID_GLOBAL$$.triggerBilling = (bid) => { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
what do you think about extracting this piece of code and reusing it here?
what I am worried about is that this call comes from the publisher and here bid
could be anything at all; but the adapters will expect it to be an actual certified bid response object.
I would also improve that code a bit to look up by bidId
as well. I don't like that it apparently accepts finding multiple matching bids, and just decides that the first one is the "correct" one.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
hey @dgirardi, i agree, makes sense to extract that piece of code and reuse it in the triggerBilling func, especially to your point about how a pub could pass through anything.
for the second part of your comment, if/when the bids
var gets defined, i added an additional check to make sure that the bid we grab from that array has a matching transactionId with the bid that was passed through the triggerBilling func. should that be sufficient?
@dgirardi do you think anything else is needed for this PR? |
src/auction.js
Outdated
@@ -367,8 +367,11 @@ export function newAuction({adUnits, adUnitCodes, callback, cbTimeout, labels, a | |||
} | |||
|
|||
function addWinningBid(winningBid) { | |||
const { transactionId } = winningBid; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I don't think this helps; by the time it gets here, it should already be the correct bid. The filtering happens in markWinningBidAsUsed
.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think for this part I was just aiming to link the winning bid with it's associated adunit to check if deferBilling is true or false. Looks like that can be done by either comparing adUnitCode
& code
between the two or transactionId
. Or let me know if there is another way to do this that I may have missed.
src/prebid.js
Outdated
bids = auctionManager.getBidsReceived() | ||
.filter(bid => bid.adId === winningBid.adId && bid.adUnitCode === winningBid.adUnitCode); | ||
} else if (winningBid.adUnitCode) { | ||
bids = targeting.getWinningBids(winningBid.adUnitCode); | ||
} else if (winningBid.adId) { | ||
bids = auctionManager.getBidsReceived().filter(bid => bid.adId === winningBid.adId); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
this could be extracted no? as in, re-use code instead of copy-paste.
src/prebid.js
Outdated
} | ||
|
||
if (bids.length > 0) { | ||
const triggerBillingBid = bids.find(bid => bid.transactionId === winningBid.transactionId); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
bidId is a better identifier than transactionId; but I also think you need to do something - a warning or so - when you're left with nothing. note that you can only do this in here, not in markWinningBidAsUsed
, because that would be a breaking change.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Addressed this as well. Had one basic question though, I didn't see bidId
on the winning bids but did see requestId
which looks to have the same value. Is it safe to you that?
src/adapterManager.js
Outdated
@@ -609,6 +609,10 @@ adapterManager.callBidWonBidder = function(bidder, bid, adUnits) { | |||
tryCallBidderMethod(bidder, 'onBidWon', bid); | |||
}; | |||
|
|||
adapterManager.callBidBillableBidder = function(bid) { | |||
tryCallBidderMethod(bid.adapterCode || bid.bidder, 'onBidBillable', bid); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'd leave out the use of adapterCode, because it makes this inconsistent with every other method of this type. (also, if we were to use it, it should be the fallback and not the default).
src/auction.js
Outdated
@@ -367,8 +367,10 @@ export function newAuction({adUnits, adUnitCodes, callback, cbTimeout, labels, a | |||
} | |||
|
|||
function addWinningBid(winningBid) { | |||
const winningAd = adUnits.find(adUnit => adUnit.code === winningBid.adUnitCode); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
you probably want to use transactionId
instead of code
here; code is not unique and in theory I could set up deferred billing on only some adUnits that share the same code.
src/prebid.js
Outdated
*/ | ||
pbjsInstance.triggerBilling = (winningBid) => { | ||
const bids = fetchReceivedBids(winningBid, 'Improper use of triggerBilling. It requires a bid with at least an adUnitCode or an adId to function.'); | ||
const triggerBillingBid = bids.find(bid => (bid.adId === winningBid.adId && bid.adUnitCode === winningBid.adUnitCode) || bid.requestId === winningBid.requestId); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Didn't fetchReceivedBids
just do the searching on adId
and adUnitCode
? I think those would always be true here.
Also, the match on requestId
should be optional here IMO. e.g. const triggerBillingBid = bids.find(bid => bid.requestId === winningBid.requestId) || bids[0]
.
thanks @dgirardi, the feedback you gave makes sense. just addressed the changes you pointed out with a new commit. if this pr looks good now, would it be possible to merge this one this week? Will free us up over here to work on another ticket that depends on the code in this PR. |
Docs PR? |
…bid#9640) * logic for billing deferrals * refactored and addressed feedback * refactored triggerBilling func * addressed feedback * rebased on top of master * reverted some unneeded changes * refactored triggerBilling and addWinningBid funcs * reverted changes to example html file * addressed changes from feedback
Type of change
Description of change
Logic follows the proposal outlined here:
onBidBillable(bid)
which will be invoked by core when it deems a bid to be billable;onBidWon
andonBidBillable
one after the other;onBidWon
but notonBidBillable
;onBidBillable
.Note: For this feature to fully be enabled, the following is also required:
onBidBillable
methodpbjs.triggerBilling
when desiredOther information
Related Issue: #4494