Skip to content
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

Pre-Auction Filters and the Prebid Ad Slot #4149

Closed
bretg opened this issue Sep 3, 2019 · 7 comments
Closed

Pre-Auction Filters and the Prebid Ad Slot #4149

bretg opened this issue Sep 3, 2019 · 7 comments
Assignees
Labels
intent to implement pinned won't be closed by stalebot

Comments

@bretg
Copy link
Collaborator

bretg commented Sep 3, 2019

Feature Overview

The Prebid AdUnit 'code' is a mixed attribute that can be either the GPT slot name or the div ID. The undecided nature of this value makes the 'code' harder to utilize for reporting and targeting.

This feature proposes a resolution to the long-running issue of the confusing AdUnit code value by establishing conventions for passing in something more descriptive and stable. It's optional for publishers to use it, and Bid Adapters and Analytics Adapters will not need to change unless they want to take advantage of the more stable field.

Details

  1. Some publishers utilize the same 'slotname' in the page for multiple holes-in-the-page, differentiating in the ad server by size. e.g.
  • defineSlot('/1111/homepage', [[300,250]], 'div-293rj893p9wje9we9fj');
  • defineSlot('/1111/homepage', [[728,90]], 'div-j98s9u9usj987665da');
  • defineSlot('/1111/homepage', [[160,600]], 'div-B2q3s4gseshekhsei9sh');
  1. In order to be able to display the right ad in the right hole, the Prebid AdUnit therefore sets the 'code' to the div ID instead of the slotname.
  2. A div ID is sometimes a random number, and in any case, can change over time as refactoring happens
  3. Therefore, to get a stable ID that's useful from a business perspective to identify a hole-in-the-page, we need to add yet another identifier to the world... introducing the Prebid Ad Slot, or pbAdSlot

Currently, Prebid.js doesn't link the adunit to ad ad server slot until after the auction -- it happens during the call to set the targeting. But since the pbAdSlot may be the ad slot name, we need to know the GPT slot before the auction.

What's proposed is a new Prebid.js hook that gives publishers the option to define and utilize a pbAdSlot. A possible source of the pbAdSlot is a hunt-path like:

  • First use the AdUnit's pbAdSlot if defined
  • Else, see if the AdUnit.code corresponds to a div and if so, try to retrieve a data element. e.g. data-adslotid.
  • Else if AdUnit.code corresponded to a div but there was no data element, but googletag is present, then look up the GPT slot name from the div.
  • Else, just use the AdUnit.code, assuming that it's an ad unit slot

However, publishers are likely to want to customize the definition of Prebid Ad Slot in a number of ways, e.g.

  • always just using the AdUnit.code
  • using a different ad server
  • parsing the ad server's slot name
  • using a non-standard div data element ID
  • preferring to use the AdUnit.pbAdSlot as a default rather than primary
  • preferring a blank pbAdSlot to using the AdUnit.code

So any approach will need to be flexible. Instead of defining a complex module that implements a mini-compiler capable of delivering the necessary flexibility, we propose providing a generic hook in Prebid.js auction processing and reference functions that publishers can modify to work for their scenarios.

Business Case

Prebid has come a long way from its humble beginnings as a set of open-source javascript tools for header bidding. Today, Prebid is a core system within the ad stack, and publishers are asking Prebid to be able to do more: provide robust reporting, centralize common functions like pricing and ad quality controls, and target PMP deals. Power users of Prebid are learning that the wrapper performs best when its configuration can be fine tuned to suit the inventory it serves, and want the wrapper to be able to respond dynamically to the characteristics of each page view.

This set of enhancements require a system for inventory classification and segmentation that resembles what one would find in an ad server or exchange. Publishers, for example, maintain different pricing restrictions for differing segments of inventory, and therefore construct detailed pricing control schemes using inventory targeting. Today, these controls must be duplicated across multiple demand partner interfaces, and publishers are looking to see it be centralized to the wrapper. To provide this feature, the wrapper must also be able to address specific segments of inventory and set unique pricing controls for each.

There are many use cases for Ad Slot; the primary near term use is reporting. The growth of Prebid-centric analytics solutions such as Roxot, Pubwise, Rivr, and many others demonstrates the value that Prebid offers as a home for consolidated reporting on the a publisher’s programmatic business.

Where Prebid falls short today in reporting is its limited ability to provide granular, flexible inventory segmentation. Prebid’s existing inventory object, the adUnit, cannot meet these requirements because it contains a verbose list of required inventory and bidder attributes. Each ad unit created adds a significant amount to Prebid’s overall payload. For publishers with large and complex networks, segmenting inventory with adUnit is not feasible.

Prebid clearly needs a more robust inventory management structure in order to meet the use cases stated above, but developing it and driving its adoption is no small task. For that reason, the initial implementation is highly flexible, allowing publishers to insert any string that they use to identify inventory for inventory segmentation today. For the majority of users, this will be the Google Ad Manager Ad Unit Path. The GAM Ad Unit has the benefit of being easily parseable, allowing reporting and targeting systems to take advantage of its hierarchy to allow publishers to group and subdivide inventory quickly and easily. Over time, the Prebid Ad Slot could evolve into a more robust, stand alone system.

Requirements

  1. Supporting the Prebid Ad Slot should be an optional hook in Prebid.js. A function can be registered to run as a pre-auction filter that can modify the AdUnit array.
  2. The hook function should be able to add the Prebid Ad Slot to the AdUnits ad adunit-specific first party data. i.e. AdUnit.context.pbAdSlot.
  3. The hook function should be able to obtain the pbAdSlot from at least these locations:
    a. AdUnit.code
    b. AdUnit.context.pbAdSlot
    c. div data elements
    d. ad server slotname
  4. The hook function must be able to update the AdUnit context data.
  5. The Prebid Ad Slot must be available to client-side and server-side adapters as First Party Data.
  6. Publishers should be able to add other functions that modify the AdUnit array before the auction.

Proposed Interfaces

  1. The pbAdSlot attribute is added to the Prebid Ad Unit in the First Party Data context.
var AdUnit={
   code: "40989gjr9e98ajrosiero",
   fpd: {
      context: {
        pbAdSlot: "/1111111/homepage/med-rect-2"
        ...
      }
   },
   ...
};
  1. Configuration allows the page to define pre-auction filter functions:
        var setPbAdSlot = function setPbAdSlot(adunits) {
            console.log('setPbAdSlot called');
            ... logic to find and set fpd.context.pbAdSlot for each AdUnit ...
        };

        pbjs.onEvent('onBeforeRequestBids', setPbAdSlot);
  1. The Prebid Server Bid Adapter must be able to pass the Prebid AdSlot through the OpenRTB request in imp[].ext.context.data.pbadslot:
{
  imp: [{
    ...
    ext: {
      ...
      context: {
        data: {
          pbadslot: "/1111111/homepage/med-rect-2"
        }
      }
    }
  }]
}
@stale
Copy link

stale bot commented Sep 30, 2019

This issue has been automatically marked as stale because it has not had recent activity. It will be closed if no further activity occurs. Thank you for your contributions.

@stale stale bot added the stale label Sep 30, 2019
@mkendall07 mkendall07 removed the stale label Oct 7, 2019
@stale
Copy link

stale bot commented Oct 21, 2019

This issue has been automatically marked as stale because it has not had recent activity. It will be closed if no further activity occurs. Thank you for your contributions.

@stale stale bot added the stale label Oct 21, 2019
@bretg bretg removed the stale label Oct 27, 2019
@bretg
Copy link
Collaborator Author

bretg commented Oct 28, 2019

We discussed this last week and determined that we would add a “onBeforeRequestBids” external event and pass through args for mutation.

The proposal is that this event will be fired after conditional adunit processing but before adunits are copied to bidrequests. It will pass in the array of adunits and allow the page function to alter the contents.

For example:

        var setPbAdSlot = function setPbAdSlot(adunits) {
            console.log('setPbAdSlot called');
            ... logic to find and set context.pbAdSlot for each AdUnit ...
        };

        pbjs.onEvent('onBeforeRequestBids', setPbAdSlot);

@bretg
Copy link
Collaborator Author

bretg commented Oct 30, 2019

Proposal is that we limit this to cover just the stated use case. We call the event onBeforeRequestBids and it fires just before copying the adunits to the bidRequest object.

If there are other use cases in the future that require updating the ad units before conditional logic, that person can figure out the details.

@stale
Copy link

stale bot commented Nov 13, 2019

This issue has been automatically marked as stale because it has not had recent activity. It will be closed if no further activity occurs. Thank you for your contributions.

@bretg
Copy link
Collaborator Author

bretg commented Feb 7, 2020

For the record, this is done in PBJS. PBS doesn't need changes unless an adapter wants to pass the value through their endpoint on a different attribute.

@bretg
Copy link
Collaborator Author

bretg commented Aug 12, 2020

For the record, just found that the implementation was slightly mismatched from the original spec.

Originally the openrtb definition was imp[].ext.context.data.adslot, but it got implemented in pbsBidAdapter as imp[].ext.context.data.pbadslot.

Changing the spec and PBS because that's easier than upgrading clients to a patched PBJS.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
intent to implement pinned won't be closed by stalebot
Projects
None yet
Development

No branches or pull requests

3 participants