prebid / Prebid.js

Setup and manage header bidding advertising partners without writing code or confusing line items. Prebid.js is open source and free.
https://docs.prebid.org
Apache License 2.0
1.31k stars 2.07k forks source link

Feature Request: Support for loading the ad but not firing the billing notifications #4494

Closed patmmccann closed 1 year ago

patmmccann commented 4 years ago

Type of issue

Feature Request

Description

Many publishers can now pre-fetch ads in a Lazy Load scenario before rendering them. https://developers.google.com/doubleclick-gpt/reference#googletag.PubAdsService_enableLazyLoad The goal of this is so that the render can be quicker and viewability is improved.

In the case of an ad in an exit intent pop-up, conducting an auction and rendering an ad before the user exits is quite difficult.

In prebid, if a publisher wanted the browser to start fetching an ad before the publisher is ready to show it, it would just call the adm. However, if the publisher does this too early, they will have low viewability on the unit.

However, if an adapter were to separate billing events from the adm, as per section F of OpenRTB 3.0 updates at https://iabtechlab.com/wp-content/uploads/2017/09/OpenRTB-3.0-Draft-Framework-for-Public-Comment.pdf and https://github.com/InteractiveAdvertisingBureau/openrtb/blob/master/OpenRTB%20v3.0%20FINAL.md the browser could begin to fetch resources for the ad before the billing events were fired.

We could then write separate fetch and render functions and only fire the billing events on render. Another scenario is the billing events only fire on in view impressions.

A final scenario is a publisher could fetch an ad before calling dfp and render if dfp chose the ad in its response. A publisher may want to do this for all bids over a certain threshold, or other scenarios where the publisher predicts prebid is likely to be the chosen dfp order.

Also, #2246 seems to recognize burl, but doesn't seem to add support for calling fetch methods before render methods; so I am not sure how a publisher can take advantage of the burl information now.

bretg commented 4 years ago

This is a big project. Getting bidders to split the body and the tracking could take a while.

What would the 'fetch' actually do? I get that the goal is having assets in browser cache, but it's unclear to me how that's feasible.

1) render every relevant bid into an invisible iframe? 2) parse every adm for strings that look like image URLs and use ?

patmmccann commented 4 years ago

I know it's a big project; my hope is new members joining at the leader tier are both committing resources to the project and are very interested in the outcome of this issue

The whole community will benefit from a variety of scenarios in which ads can be preassembled to some degree so they are ready to display before the billing event is fired. I imagine that's why the IAB added burl to the spec.

patmmccann commented 2 years ago

This might be smaller than originally scoped; we could delay the callBurl portion of rendering functions to wait for a trigger of some sort.

dgirardi commented 1 year ago

Here's a tentative proposal for how this could work:

  1. publisher flags adUnits as being separately billable: pbjs.addAdUnits({deferBilling: true, ...})
  2. bid adapters provide bidResponse.burl. Several adapters seem to do this already, possibly by accident (more on this below).
  3. the winning bid is rendered as normal. if the adUnit is not marked with deferBilling, rendering will also trigger burl (if one exists), in the same way nurl is triggered currently.
  4. when appropriate (e.g. interstitial is displayed), the publisher calls a new public API, pbjs.triggerBilling({adId}).

Currently we deal with bidResponse.burl in a confusing way. We fire it at the time of rendering only for s2s bids and only through renderAd:

https://github.com/prebid/Prebid.js/blob/cb1a982182816e8a8b47ec1c769dd40bfd223c37/src/utils.js#L552-L556

Many other adapters beside PBS set bidResponse.nurl but I don't think core makes use of them in any way. Even PBS bids that go through safeframe do not get their burl triggered.

dgirardi commented 1 year ago

Updated proposal:

  1. bid adapters can provide a new method onBidBillable(bid) which will be invoked by core when it deems a bid to be billable;
  2. when a bid wins, it is by default also billable; that is, by default, core will invoke onBidWon and onBidBillable one after the other;
  3. publisher can flag adUnits as being separately billable: pbjs.addAdUnits({deferBilling: true, ...})
  4. winning bids for those adUnits trigger onBidWon but not onBidBillable;
  5. when appropriate (e.g. interstitial is displayed), the publisher calls a new public API, pbjs.triggerBilling({adId}), which would trigger onBidBillable.
jlquaccia commented 1 year ago

Hey @dgirardi, had some interest in working on this ticket. What do you think of the following? (I took your proposal above and expanded upon point #5):

  1. bid adapters can provide a new method onBidBillable(bid) which will be invoked by core when it deems a bid to be billable;
  2. when a bid wins, it is by default also billable; that is, by default, core will invoke onBidWon and onBidBillable one after the other;
  3. publisher can flag adUnits as being separately billable: pbjs.addAdUnits( {deferBilling: true, ...})
  4. winning bids for those adUnits trigger onBidWon but not onBidBillable;
  5. create a new module called visibilityForBilling which does the following: keeps track of winnings bids, whether or not the associated ad unit of the winning bid is flagged with deferBilling or not and lastly if the associated ad unit of the winning bid has become visible in the viewport. Visibility detection can be utilized via gpt.js and/or the intersection observer api. If this module determines if billing for a bidder is appropriate, then it will inform core of this and emit the billable event
  6. On the billable event, the publisher calls a new public API, pbjs.triggerBilling({adId}), which would trigger onBidBillable.

Note: For now, was thinking that the new visibilityForBilling module doesn't need to be behind configuration (via pbjs.setConfig({ ... }), etc.). Thinking at the moment just having the module included in core and simply listening for flagged ad units with deferBilling set to true would be ok?

dgirardi commented 1 year ago

I would keep point 5 separate; visibility is not trivial and I expect it would double the scope alone. As long as we still provide the new triggerBilling api, I don't see a reason to do them together.

jlquaccia commented 1 year ago

I would keep point 5 separate; visibility is not trivial and I expect it would double the scope alone. As long as we still provide the new triggerBilling api, I don't see a reason to do them together.

Thanks for the feedback. Keeping the visibility logic separate sounds like it makes sense to me

jlquaccia commented 1 year ago

Wanted to post a quick update on this ticket, I had to shift focus over the past few weeks to work on a handful of other internal PubMatic tickets, but will resume work on this ticket this week (on the updated proposal above: https://github.com/prebid/Prebid.js/issues/4494#issuecomment-1412487621) and also https://github.com/prebid/Prebid.js/issues/9531