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

Add native support #1072

Merged
merged 19 commits into from
May 18, 2017
Merged

Add native support #1072

merged 19 commits into from
May 18, 2017

Conversation

matthewlane
Copy link
Collaborator

@matthewlane matthewlane commented Mar 23, 2017

  • Feature

A native advertisement comprises a set of assets--a title, a description, and an image url, for example--that are plugged into a publisher-defined HTML template. The template includes placeholder macros for those assets, and may be styled to match the form of the surrounding page. This change adds capabilities for requesting native demand from bidder adapters, and sending the received assets to a native template defined in an ad server via key-value targeting.

Publisher Setup

To signal a native demand request, configure an adUnit's mediaType to 'native'.

Optionally specify the individual assets to request from the demand partner with a nativeParams object. This object will be passed to bidder adapters for use in constructing their network requests. The possible nativeParams are

  • title
  • body
  • image
  • sponsoredBy
  • icon
  • clickUrl

Any field in nativeParams configured as {required: true} will be required on the bid response object. If not present, the bid is not added to the auction.

Prebid also has a pre-defined native type, image, which is an abstraction over a set of commonly requested native assets. This expands to the following set of native parameters

image: {required: true}
title: {required: true}
sponsoredBy: {required: true}
clickUrl: {required: true}
body: {required: false}
icon: {required: false}

Use this by setting nativeParams to type: 'image'.

Example native ad unit

pbjs.addAdUnits({
  code: slot.code,
  sizes: slot.size,
  mediaType: 'native',
  nativeParams: {
    title: {required: true},
    body: {required: false}
    image: {required: false}
    sponsoredBy: {required: true},
  },
  bids: [{
    bidder: 'appnexusAst',
    params: {placementId: 123}
  }]
});

Bidder Adapter Setup

The adapter is given the nativeParams object in its callBids function and may send these parameters directly or transform them to fit their endpoint's expected parameters. For example, the appnexusAst endpoint recognizes title and icon as native asset request parameters and passes those on directly, but expects description instead of body and creates a mapping between these identifiers.

When demand is returned to the adapter, it should mark the bid response object with mediaType: 'native', and attach the received assets to a native object on the bid with properties that match the nativeParams identifiers. For example, an adapter might construct its native bid response object in its response handler function as follows

let bid = bidfactory.createBid(STATUS.GOOD, response);

// bid.cpm, bid.code, etc. set

bid.mediaType = 'native';
bid.native = {
  title: response.title,
  body: response.desc,  // endpoint responds with `desc`, set to body
  sponsoredBy: response.sponsored,
  image: response.main_img.url,
  icon: response.icon.url,
  clickUrl: response.link.url,
  impressionTrackers: response.impression_trackers, // an array of urls that are fired if this bid wins
};

// other bid setup, etc.

bidmanager.addBidResponse(placementId, bid);

Ad Server Setup

Once the bid response object has all its required native properties set, if it wins the auction, targeting keys are set thusly:

bid attribute targeting key
title hb_native_title
body hb_native_body
sponsoredBy hb_native_brand
image hb_native_image
icon hb_native_icon
clickUrl hb_native_linkurl

Toggling pbjs.enableSendAllBids() will also set landscape targeting for these native assets. Due to DFPs 20 character limit, the full bidder code appendix for these keys may be truncated.

A publisher's ad server should contain a template with macros for these keys, for example

<div class="sponsored-post">
  <div class="content">
    <h1>
      <a href="%%CLICK_URL_UNESC%%%%PATTERN:hb_native_linkurl%%" target="_blank">
        %%PATTERN:hb_native_title%%
      </a>
    </h1>
    <p>%%PATTERN:hb_native_body%%</p>
    <div class="attribution">%%PATTERN:hb_native_brand%%</div>
  </div>
</div>

Additionally, this snippet can be added to a template to call back to prebid.js to fire impression trackers for the winning native bid

<script>
window.parent.postMessage(JSON.stringify({
  message: 'Prebid Native',
  adId: '%%PATTERN:hb_adid%%'
}), '*');
</script>

closes #1012

@mkendall07 mkendall07 self-assigned this Apr 10, 2017
@matthewlane matthewlane force-pushed the feature/native branch 3 times, most recently from e6e0eea to 5dd369a Compare April 30, 2017 01:15
@matthewlane matthewlane force-pushed the feature/native branch 4 times, most recently from ef6c5c1 to b109fc2 Compare May 8, 2017 14:56
src/native.js Outdated
/*
* Create an invisible pixel
*/
function createImpressionPixel(src) {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

this code should be in utils now (might have to rebase to get it)


// map standard native asset identifier to what /ut expects
Object.keys(bid.nativeParams).forEach(key => {
let requestKey = NATIVE_MAPPING[key] && NATIVE_MAPPING[key].serverName || NATIVE_MAPPING[key] || key;
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This code is a bit confusing. Why is this mapping required?

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It's required because some of the standard native assets prebid defines don't translate exactly to v3 endpoint parameters. v3 looks for description request parameter rather than body for example. Agreed this code is confusing though, I'll refactor to be more clear

src/native.js Outdated
/*
* Append to head
*/
function attachPixel(pixel) {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

also in utils

src/prebid.js Outdated
@@ -393,6 +394,16 @@ $$PREBID_GLOBAL$$.requestBids = function ({ bidsBackHandler, timeout, adUnits, a
}
});

// for native-enabled adUnits, only request bids if all bidders support native
// TODO: abstract this and the video adunit validation into general adunit validation function
const invalidNativeAdUnits = adUnits.filter(nativeAdUnit).filter(hasNonNativeBidder);
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We should still fire requests for bidders that support native.

src/native.js Outdated
import { getBidRequest, logError } from './utils';

/** INSERT NATIVE ADAPTERS - DO NOT EDIT OR REMOVE */
const nativeAdapters = [];
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Probably don't want this line in between these 2.

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is to prevent a linting error 'nativeAdapters' is not defined

src/native.js Outdated

/** INSERT NATIVE ADAPTERS - DO NOT EDIT OR REMOVE */
const nativeAdapters = [];
/** END INSERT NATIVE ADAPTERS */
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The adapter registration has to go into this file? seems inconsistent.

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Writing it to adaptermanager.js like the other loader does causes a circular dependency. Can move it though if there's another place that makes more sense

Copy link
Member

@mkendall07 mkendall07 left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM!

@jaiminpanchal27 jaiminpanchal27 self-requested a review May 18, 2017 21:49
Copy link
Collaborator

@jaiminpanchal27 jaiminpanchal27 left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM

@mkendall07 mkendall07 merged commit 694dfba into master May 18, 2017
@mkendall07 mkendall07 deleted the feature/native branch May 19, 2017 00:42
outoftime pushed a commit to Genius/Prebid.js that referenced this pull request May 24, 2017
…built

* 'master' of https://github.com/prebid/Prebid.js: (23 commits)
  Increment pre version
  Probed 0.24.0 Release
  Beachfront adapter - add ad unit size (prebid#1183)
  Thoughtleadr adapter - fix postMessage (prebid#1207)
  When prebid server issues a no-bid response, call addBidResponse for every adUnit requested (prebid#1204)
  Improvement/timeout xhr (prebid#1172)
  Add native support (prebid#1072)
  Improvement/alias queue (prebid#1156)
  Updated documentaion (prebid#1160)
  Improvement/prebid iframes amp pages (prebid#1119)
  Fixes prebid#1114 possible xss issue (prebid#1186)
  Allowed setTargetingForGPTAsync() to target specific ad unit codes. (prebid#1158)
  updated tag (prebid#1212)
  Common user-sync (prebid#1144)
  Rename secureCreatives file and lint (prebid#1203)
  HIRO Media: Remove batching mechanism and use AJAX instead of JSONP (prebid#1133)
  Add Support for DigiTrust in Rubicon Adapter (prebid#1201)
  Upgrade linters to ESLint with stricter code style (prebid#1111)
  Add dynamic bidfloor parameter to Smart Adserver Adapter (prebid#1194)
  Bug fix: bids served by secure creatives does not get pushed into _winningBids (prebid#1192)
  ...
vzhukovsky added a commit to aol/Prebid.js that referenced this pull request Jul 17, 2017
….23.0 to aolgithub-master

* commit '136fc37637749a764070c35c03e7e87a5c157947': (33 commits)
  Added changelog entry.
  Implemented passing key values feature.
  Update code to ESlint rules.
  Prebid 0.24.1 Release
  tests: drop ie9 browserstack test
  Audience Network: separate size from format (prebid#1218)
  Bugfix/target filtering api fix (prebid#1220)
  Map sponsor request param to endpoint param (prebid#1219)
  Increment pre version
  Probed 0.24.0 Release
  Beachfront adapter - add ad unit size (prebid#1183)
  Thoughtleadr adapter - fix postMessage (prebid#1207)
  When prebid server issues a no-bid response, call addBidResponse for every adUnit requested (prebid#1204)
  Improvement/timeout xhr (prebid#1172)
  Add native support (prebid#1072)
  Improvement/alias queue (prebid#1156)
  Updated documentaion (prebid#1160)
  Improvement/prebid iframes amp pages (prebid#1119)
  Fixes prebid#1114 possible xss issue (prebid#1186)
  Allowed setTargetingForGPTAsync() to target specific ad unit codes. (prebid#1158)
  ...
dluxemburg pushed a commit to Genius/Prebid.js that referenced this pull request Jul 17, 2018
* Prebid native

* Support native mediaType on adUnits and validate native bidders

* Recognize native mediaType on bid request and set on bid response

* Validate bid response contains required native assets

* Test native bid validation

* Support v3 endpoint and response

* Set up for writing native adapters array at build time

* Fire native impression trackers

* Use native targeting keys in enableSendAllBids

* Update v3 native bid shapes

* Build native-enabled adapters list from adapters.json

* Fix linting errors

* Move functions to utils

* Use existing utils function

* Fire requests for bidders that support native

* Clarify mapping mechanism

* Test native request

* Add served ad to _winningBids

* Camel case asset properties
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging this pull request may close these issues.

DFP Native ads in prebid
5 participants