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

amp integration #756

Merged
merged 9 commits into from
Nov 1, 2016
Merged
Show file tree
Hide file tree
Changes from 7 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
59 changes: 59 additions & 0 deletions integrationExamples/gpt/amp/amp_page.html
Original file line number Diff line number Diff line change
@@ -0,0 +1,59 @@
<!doctype html>
<html amp lang="en">
<head>
<!--
This is an example AMP page. Set the amp-3p-iframe-src meta tag to your
x-domain host for remote.html and set your content, `amp-ad` and other components.
-->
<meta charset="utf-8">
<title>Hello, AMPs</title>
<link rel="canonical" href="http://example.ampproject.org/article-metadata.html" />
<meta name="viewport" content="width=device-width,minimum-scale=1,initial-scale=1">
<meta name="amp-3p-iframe-src" content="https://amp.prebidapp.com:5000/remote.html">
Copy link
Member

Choose a reason for hiding this comment

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

let's make the publisher hosted content obvious with a macro or something.

<script async custom-element="amp-ad" src="https://cdn.ampproject.org/v0/amp-ad-0.1.js"></script>
<script type="application/ld+json">
{
"@context": "http://schema.org",
"@type": "NewsArticle",
"headline": "Open-source framework for publishing content",
"datePublished": "2015-10-07T12:02:41Z",
"image": [
"logo.jpg"
]
}
</script>
<style amp-boilerplate>body{-webkit-animation:-amp-start 8s steps(1,end) 0s 1 normal both;-moz-animation:-amp-start 8s steps(1,end) 0s 1 normal both;-ms-animation:-amp-start 8s steps(1,end) 0s 1 normal both;animation:-amp-start 8s steps(1,end) 0s 1 normal both}@-webkit-keyframes -amp-start{from{visibility:hidden}to{visibility:visible}}@-moz-keyframes -amp-start{from{visibility:hidden}to{visibility:visible}}@-ms-keyframes -amp-start{from{visibility:hidden}to{visibility:visible}}@-o-keyframes -amp-start{from{visibility:hidden}to{visibility:visible}}@keyframes -amp-start{from{visibility:hidden}to{visibility:visible}}</style><noscript><style amp-boilerplate>body{-webkit-animation:none;-moz-animation:none;-ms-animation:none;animation:none}</style></noscript>
<script async src="https://cdn.ampproject.org/v0.js"></script>
</head>
<body>
<h1>Welcome to the mobile web</h1>

<amp-ad
width="300"
height="250"
layout="fixed"
type="doubleclick"
data-slot="/19968336/header-bid-tag-1">
</amp-ad>

<amp-ad
width="300"
height="250"
layout="fixed"
type="doubleclick"
data-slot="/19968336/header-bid-tag-2">
</amp-ad>

<div>Lorem ipsum dolor sit amet, consectetur adipiscing elit. Nam aliquam ac orci vitae cursus.
Nulla rutrum egestas felis ut bibendum. Maecenas blandit tellus eu turpis posuere condimentum sit amet eget eros. Donec sollicitudin sit amet enim ut ultricies. Nunc semper enim a dignissim convallis. Vestibulum faucibus eget ante non pellentesque. Maecenas convallis consectetur dolor, non facilisis felis interdum id. Cras ac leo et massa facilisis porttitor ut vitae dolor. Phasellus odio felis, pharetra vel sem vitae, ultricies ornare sapien. In sodales semper ultricies.

Suspendisse potenti. Cum sociis natoque penatibus et magnis dis parturient montes, nascetur ridiculus mus. Integer tempus rutrum libero, sit amet finibus sapien rutrum sed. Vestibulum accumsan turpis vel est cursus vulputate. Nam id risus ligula. Praesent metus elit, iaculis sit amet egestas id, interdum id nibh. Nullam egestas tempor lorem at consectetur. Fusce sit amet mattis massa, id semper elit. Mauris blandit lectus a orci lobortis malesuada.

Donec id turpis quam. Morbi fringilla justo nisi, et mattis nibh laoreet non. Aliquam orci eros, tincidunt a feugiat id, gravida ut nisl. Morbi et arcu facilisis, congue mauris ut, ultricies ligula. Vivamus vulputate est non facilisis iaculis. Phasellus quis auctor odio. Nulla facilisi. Sed convallis feugiat erat, sit amet tincidunt justo bibendum ut. Sed maximus justo sit amet pharetra tincidunt. Vivamus laoreet nisi vel est feugiat, sed egestas ante congue.

Nunc ultricies sodales dolor eget semper. Phasellus ac ligula ac mi fermentum ornare sed et lacus. Curabitur ante enim, maximus ac lacus in, hendrerit mollis enim. Lorem ipsum dolor sit amet, consectetur adipiscing elit. Maecenas posuere nisl ac nisl sagittis faucibus. Quisque pellentesque vehicula lectus, ac malesuada dui mollis pulvinar. Nam in lectus placerat eros feugiat dictum ut vel quam. Etiam magna mauris, euismod in felis sodales, interdum ultricies nisl. Nunc elit mi, pellentesque vel est nec, tempus dignissim purus. Praesent pharetra, odio ut cursus dictum, erat felis gravida lorem, at pretium justo dolor quis odio. Mauris tincidunt accumsan mi, gravida condimentum enim vulputate at. Phasellus pretium hendrerit commodo. Quisque blandit rhoncus erat, sed tincidunt dolor rutrum et.

Nunc nec condimentum mauris, vel porta sem. Donec finibus sapien lacus, quis faucibus neque lobortis non. Nam faucibus nunc odio. Aliquam dolor nisl, placerat sed ipsum quis, facilisis sollicitudin nisi. Nullam sed ultrices enim. Ut sollicitudin mi dignissim, faucibus massa in, pellentesque velit. Donec auctor vel libero in posuere. Ut venenatis odio nec euismod egestas. Nunc posuere pretium sapien finibus sagittis. Nunc volutpat ante eget eleifend consequat. Donec sed quam sit amet quam venenatis pulvinar. Nullam in ex id magna pellentesque tempus.
</div>
</body>
</html>
38 changes: 38 additions & 0 deletions integrationExamples/gpt/amp/creative.html
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
<!-- This script tag should be returned by your ad server -->

<script>
// This is the `renderAd` function from Prebid.js moved within the creative iframe
var renderAd = function (ev) {
var key = ev.message ? "message" : "data";
var data = {};
try {
data = JSON.parse(ev[key]);
} catch (e) {
// Do nothing. No ad found.
}
if (data.ad || data.adUrl) {
if (data.ad) {
document.write(data.ad);
document.close();
} else if (data.adUrl) {
document.write('<IFRAME SRC="' + data.adUrl + '" FRAMEBORDER="0" SCROLLING="no" MARGINHEIGHT="0" MARGINWIDTH="0" TOPMARGIN="0" LEFTMARGIN="0" ALLOWTRANSPARENCY="true"></IFRAME>');
document.close();
}
}
};

var requestAdFromPrebid = function () {
var message = JSON.stringify({
message: 'Prebid creative requested: %%PATTERN:hb_adid%%',
adId: '%%PATTERN:hb_adid%%'
});
window.parent.postMessage(message, '*');
};

var listenAdFromPrebid = function () {
window.addEventListener("message", renderAd, false);
};

listenAdFromPrebid();
requestAdFromPrebid();
</script>
12 changes: 12 additions & 0 deletions integrationExamples/gpt/amp/gulpfile.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
var gulp = require('gulp');
var connect = require('gulp-connect');
var port = 5000;

gulp.task('serve', function() {
connect.server({
port: port,
root: './',
livereload: true,
https: true
});
});
207 changes: 207 additions & 0 deletions integrationExamples/gpt/amp/remote.html
Original file line number Diff line number Diff line change
@@ -0,0 +1,207 @@
<!doctype html>
<html>
<head>
<meta charset="utf-8">
<meta name="robots" content="noindex">
<script>

/** AMP x-domain iframe custom source file
* host this file on a remote domain from your AMP pages,
* set the `amp-3p-iframe-src` meta tag on your AMP pages
* (see `./amp_page.html`)
*
*
* see "Enhance incoming ad configuration" section of AMP docs
* https://www.ampproject.org/docs/reference/components/amp-ad
*/

(function() {
var v = location.search.substr(1);
if (!(/^\d+(-canary)?$/.test(v))) return;
var u = 'https://3p.ampproject.net/'+encodeURIComponent(v)+'/f.js';
document.write('<script'+' src="'+encodeURI(u)+'"><'+'/script>');
})();
</script>
<script>
Copy link
Member

Choose a reason for hiding this comment

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

Let's add a <!-- start Prebid.js AMP integration --> comment

// The Prebid global must match Prebid.js setting
var $$PREBID_GLOBAL$$ = pbjs;

// Standard Prebid.js setup
var rightSlotSizes = [[300, 250], [300, 600], [300, 250], [100, 100]];

var pbjs = pbjs || {};
pbjs.que = pbjs.que || [];
var PREBID_TIMEOUT = 3000;

var date = new Date().getTime();

// wrap the rest of the setup in a function that will be called by the
// AMP `draw3p` hook
function loadPrebidJS() {

setTimeout(function() {
return initAdserver;
}(), PREBID_TIMEOUT);
Copy link
Member

Choose a reason for hiding this comment

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

Do we need this timeout ?



pbjs.que.push(function () {

Copy link
Member

Choose a reason for hiding this comment

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

nit: extra line breaks / spacing.

pbjs.logging = true;

var adUnits = [
Copy link
Member

Choose a reason for hiding this comment

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

can we clean this up a little bit so all publisher defined variables are declared in one spot and that's the only code that has to change on the page?

{
code: '/19968336/header-bid-tag-1',
sizes: rightSlotSizes,
bids: [
{
bidder: 'appnexusAst',
params: {
placementId: '4799418',
dealId: 'some deal!'
}
},
{
bidder: 'aol',
params: {
network: '10077.1',
placement: 3671670
}
},
{
bidder: 'sovrn',
params: {
tagid: "315045"
}
}
]
},
{
code: '/19968336/header-bid-tag-2',
sizes: rightSlotSizes,
bids: [
{
bidder: 'appnexusAst',
params: {
placementId: '4799418',
dealId: 'some deal!'
}
},
{
bidder: 'aol',
params: {
network: '10077.1',
placement: 3671670
}
},
{
bidder: 'sovrn',
params: {
tagid: "315045"
}
}
]
}
];

pbjs.addAdUnits(adUnits);

pbjs.requestBids({
bidsBackHandler: function (bidResponses) {
initAdserver();
console.log('bidsBackHandler responses: ', bidResponses);
},
timeout: 3000
});
});

// load Prebid.js
(function () {
var d = document, pbs = d.createElement("script"), pro = d.location.protocal;
pbs.type = "text/javascript";
pbs.src = 'https://localhost:9999/build/dev/prebid.js';
Copy link
Member

Choose a reason for hiding this comment

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

can we load this in the head?

var target = document.getElementsByTagName("head")[0];
target.insertBefore(pbs, target.firstChild);
})();
}

/**
*
* @param config
* @param done
*/
function setTargeting(config, done) {
config.targeting = getTargeting(config.slot);
done(config);
}

function getTargeting(slot) {
var targeting = window.context.master.pbjs.getAdserverTargeting()[slot];
for (var key in targeting) {
if (targeting.hasOwnProperty(key)) {
targeting[key] = [targeting[key]];
}
}
targeting['prebid_amp'] = ['true'];
return targeting;
}

function initAdserver() {
var i;
var adCalls = window.context.master.adCalls;
var adCallsLength = adCalls.length;
for (i = 0; i < adCallsLength; i++) {
adCalls.pop()();
}
}

function listenAdRequestFromCreative() {
addEventListener('message', sendAdToCreative, false);
}

function sendAdToCreative(ev) {
var key = ev.message ? 'message' : 'data';
var data = {};
try {
data = JSON.parse(ev[key]);
} catch (e) {
// Do nothing. No ad found.
}
if (data.adId) {
// AMP ads a `context` object to `window`s and that is used to find the
// `master` iframe where Prebid is loaded
var adObject = window.context.master.pbjs._bidsReceived.find(function (bid) {
return bid.adId === data.adId;
});

var ad = adObject.ad;
var adUrl = adObject.adUrl;
var message = JSON.stringify({
message: 'Prebid creative sent: ' + data.adId,
ad: ad,
adUrl: adUrl
});
ev.source.postMessage(message, '*');
}
}
</script>
</head>
<body style="margin:0">
<div id="c" style="position:absolute;top:0;left:0;bottom:0;right:0;">
<script>
draw3p(function(config, done) {
if (typeof window.context.master.adCalls === 'undefined') {
window.context.master.adCalls = [];
}
if (window.context && window.context.isMaster) {
loadPrebidJS();
}
window.context.master.adCalls.push(setTargeting.bind(null, config, done));
}, ['doubleclick'], ['prebidapp.com']);
Copy link
Member

Choose a reason for hiding this comment

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

What's the meaning prebidapp.com here?


listenAdRequestFromCreative();
</script>
</div>

<script>if (window.docEndCallback) window.docEndCallback()</script>
</body>
</html>