prebid / prebid-server

Open-source solution for running real-time advertising auctions in the cloud.
https://prebid.org/product-suite/prebid-server/
Apache License 2.0
431 stars 739 forks source link

AMP endpoint to support RTC configurations #263

Closed mkendall07 closed 6 years ago

mkendall07 commented 6 years ago

AMP has a new configuration option to allow header bidding called Real Time Config (RTC). https://github.com/ampproject/amphtml/blob/master/extensions/amp-a4a/rtc-documentation.md

Prebid server is looking to support this specification by providing an endpoint that returns preprocessed key values instead of raw bids. Relates to https://github.com/prebid/Prebid.js/issues/1832

sirjonathan commented 6 years ago

Just wanting to call out that progress here is of high interest to us and a number of our clients. Happy to provide input / feedback if we can be of any help.

hhhjort commented 6 years ago

Looking t how to best implement this. Will likely require new creatives on the publisher adserver side, as they will have to know to read key values to find the link for the ad content, as there won't be a prebid.js on the page that can provide the creative for the winning bid.

Any idea how important deal support is for this, and do you happen to know if there is a limit for the total size of all the key values combined?

oliverfernandez commented 6 years ago

I can speak regarding DFP. The ad request sent to DFP has a payload limit of 8KB. Also, the macros for creatives configured in DFP also have a length limit.

Not sure if this answers your question.

mkendall07 commented 6 years ago

I don't think there is an overall limit on the key values combined.

Not sure about deal support but we probably want to include it.

hhhjort commented 6 years ago

The 8KB was the limit I was looking for, thanks. That should hopefully be plenty for what we need to support AMP. I am aware of the 20 character limit for the key value names. :)

oliverfernandez commented 6 years ago

How do you resolve the final PreBid creative that will render, from the DFP creative? Until now, the creative code was stored by PreBid.js

dbemiller commented 6 years ago

Maybe it could do something like Mobile apps do today? It seems like Mobile and AMP have similar limitations.

AMP limits client-side code to prevent people from shooting themselves in the foot with regards to page performance. Prebid Mobile limits client-side code to minimize the number of app updates. In both cases, the Prebid ecosystem just needs a solution which doesn't rely on client-side code.

I don't know exactly what the Prebid Mobile folks in DFP creatives... but I know they worked something out which basically removed the need for client-side code. From PBS perspective, I know we save the bids inside Prebid Cache, and we return a UUID in the targeting params. I'm guessing that the DFP creatives are somehow designed to pull the bid from Prebid Cache using that UUID and render it.

At a high level, something similar might work for AMP pages too?

mkendall07 commented 6 years ago

Yes that's correct. The AMP ad will render using the prebid cache. It's still client side code, but it's inside the iframe so it's allowed from the AMP perspective.

bretg commented 6 years ago

@mkendall07 or @DucChau - can you give a concrete example of how AMP-RTC creatives render?

This is how it's currently set up for us in mobile -- it pulls pbm.js from PBS, but requires that hb_cache_id be passed through with the targeting.

<script type="text/javascript" src = "//prebid-server.WHEREVER.com/static/pbm.js"></script>
<script type="text/javascript">
    pbm.showAdFromCacheId({
        admCacheID : '%%PATTERN:hb_cache_id%%'
    });
</script>

I'm not seeing where AMP-RTC allows for hb_cache_id to be passed through with the targeting, but must be missing something.

Also, am disappointed that AMP-RTC seems to only support one set of targeting -- i.e. it's not sendAllBids. This isn't ideal for deals. @DucChau - this may be worth taking up with the AMP group for v2... maybe you can check with mobile product?

mkendall07 commented 6 years ago

@bretg I'll provide an example shortly. Regarding sendAllBids support - that should work. AMP RTC doesn't care how many keys you send back. What am I missing?

hhhjort commented 6 years ago

Yes, AMP-RTC in the current PR just wraps the current OpenRTB2 code, and then extracts and sends all the targeting keys it finds in the bids. (It will skip any bids that do not have a cache ID set). This is based on a tag_id that points to an OpenRTB request stored on the server. So it will support all targeting options that OpenRTB2 supports, and if any are added it will support them automatically as well.

bretg commented 6 years ago

Ok, working with a solutions engineer, we figured out that the response from PBC would just be like this:

{"targeting": {"hb_pb": "0.50", "hb_bidder": "rubicon", "hb_cache_id": "1111-2222"}}

I can see how the mobile creative shown above works with this targeting to render.

But I'm not sure a single RTC request can return more than one set of targeting:

{"targeting": {"hb_pb": "0.50", "hb_bidder": "rubicon", "hb_cache_id": "1234-5678"}}
{"targeting": {"hb_pb": "0.55", "hb_bidder": "appnexus", "hb_cache_id": "2222-3333"}}

There aren't any examples of this happening in any of the RTC docs I've seen. There is a section on how results from multiple RTC requests should be 'merged', but that doesn't imply a single response can have more than one set of targeting.

hhhjort commented 6 years ago

DFP cannot support more than a single set of targeting. So the above example would actually be: {"targeting":{ "hb_pb: "0.55", "hb_bidder": "appnexus", "hb_cache_id": "2222-3333", "hb_pb_rubicon": "0.50", "hb_bidder_rubicon": "rubicon", "hb_cache_id_rubicon": "1234-5678", "hb_pb_appnexus": "0.55", "hb_bidder_appnexus": "appnexus", "hb_cache_id_appnexus": "2222-3333" } }

This is how plain prebid sends keys to DFP today when we want to send all bids back to DFP as opposed to just the winning bid.

bretg commented 6 years ago

Yup. Sounds like they're going to making one AMP-RTC call per adSlot -- no "Single Request Architecture".

bretg commented 6 years ago

So here's how I understand this working end-to-end. Not convinced we understand the DFP creative yet. I think we need to write something there.

1) pub adds the following HTML to their page:

<amp-ad width="320" height="50"
            type="doubleclick"
            data-slot="/1234/5678"
            rtc-config='{
            "vendors": {
              "prebid": {"REQUEST_ID": "17777-1"}
              },
            "urls": [
              "https://optional.pub-specific-domain.com/theirOwnSource"
            ], 
            "timeoutMillis": 750}'>
</amp-ad>

2) pub sets up a "vendor config" like this:

/** amp-a4a/0.1/callout-vendors.js */
vendors: {
   "prebid": {
     "url": "https://prebid-server.rubiconproject.com/openrtb2/amp?tag_id=REQUEST_ID",
     "macros": ["REQUEST_ID"]
   }
};

3) The AMP platform makes up to 5 calls to defined vendors.

https://prebid-server.rubiconproject.com/openrtb2/amp?tag_id=17777-1

4) Each vendor responds with targeting values.

The Prebid-Server openRTB endpoint takes the "tag_id" field and looks up the bidders+parameters in postgres. It initiates the calls to the various exchanges, then responds with just the targeting:

{"targeting":{ "hb_pb: "0.55", "hb_bidder": "appnexus", "hb_cache_id": "2222-3333",
"hb_pb_rubicon": "0.50", "hb_bidder_rubicon": "rubicon", "hb_cache_id_rubicon": "1234-5678",
"hb_pb_appnexus": "0.55", "hb_bidder_appnexus": "appnexus", "hb_cache_id_appnexus": "2222-3333" } }

5) AMP calls DFP with the targeting values

6) When DFP chooses header bidding as a winner, a creative is served.

7) The browser runs JS which causes a fetch to Prebid Cache server (or Prebid Server's upcoming /cache API)

8) The server responds with the creative which the browser displays

bretg commented 6 years ago

When displaying the creative, I don't think safeframe matters, but we won't have BID_WON notifications. Really need to get that PBS analytics interface going... will open a separate thread on that.

mkendall07 commented 6 years ago

Yep, you got it mostly right Bret. I'm working on the creative piece. Will have a PR up shortly

mkendall07 commented 6 years ago

Safeframe isn't supported yet but the AMP folks are working on adding it. They tell me it will be ready before mid Feb

AntoineJac commented 6 years ago

Should we not also passed in the targeting the adType (data.ad || data.adUrl) so the render function inside the creative could display it correctly?

Also a few important points to notice about AMP limitations: https://support.google.com/dfp_premium/answer/7177589

mkendall07 commented 6 years ago

Here is the creative template for AMP (and also supports legacy formats):

<!-- Universal Prebid Creative --> 
<script src = "https://acdn.adnxs.com/prebid/test/creative.js"></script>
<script>
var adId = "%%PATTERN:hb_adid%%";
var host = "%%PATTERN:hb_cache_host%%";
var uuid = "%%PATTERN:hb_cache_id%%";
var channel = "%%PATTERN:hb_channel%%";
var mediaType = "%%PATTERN:hb_format%%";
var pubUrl = "%%PATTERN:url%%";

try{    
    pbjs.renderAd(document, adId, {host: host, uuid: uuid, channel: channel, mediaType: mediaType, pubUrl: pubUrl});
}catch(e){
    console.log(e);
}
</script>

Note: the above template will need to be modified to support "sendAllBids" mode. Namely the keys will have to be appended per bidder.

Couple of things are still WIP. You can see the rendering code here with some TODOs: https://github.com/prebid/Prebid.js/blob/feature/universal_creative/src/creative/creative.js

Once this is finalized, we'll create a separate repo for the rendering code, and we'll switch to https://www.jsdelivr.com/ to host the creative code.

AntoineJac commented 6 years ago

I have looked at the code and just propose 2 small changes: https://github.com/prebid/Prebid.js/pull/2071

If we move all script in header first, some JS playing with the html could raise an error, example: https://jsfiddle.net/oeg8ftuL/

Also parseFromString has strange behaviour if the string is not correctly respecting html structure (for instance no space between 2 tags).

mkendall07 commented 6 years ago

Thanks @AntoineJac - I haven't looked at it yet but I will.

dbemiller commented 6 years ago

Reopening because it's missing the required headers. To be done in #316

dbemiller commented 6 years ago

This adds prebid support through AMP's Real Time Config 2 feature: https://github.com/ampproject/amphtml/issues/11321