-
Notifications
You must be signed in to change notification settings - Fork 2.2k
Mass Module: add module to support MASS protocol #6332
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
Changes from 20 commits
def532d
7544628
d57c9ae
255216d
4d03e3e
23f2d54
b419408
76181e0
cbd8d06
8cd13f2
821baa9
ccaf65f
03e7246
daeac99
1b6ecdd
645379b
01207e9
72e202d
89b44d0
5115b4e
05ba36b
10b9fb0
2d7add2
2aad196
7a0177f
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,107 @@ | ||
<html> | ||
<head> | ||
<script> | ||
window.massConfig = { | ||
inskin: { | ||
default: { | ||
plr_PubfileId: '000000/mass' | ||
} | ||
} | ||
}; | ||
|
||
var PREBID_TIMEOUT = 3300; | ||
|
||
var adUnits = [{ | ||
code: 'div-gpt-ad-1460505748561-0', | ||
mediaTypes: { | ||
banner: { | ||
sizes: [[300, 250], [300, 600]], | ||
} | ||
}, | ||
bids: [{ | ||
bidder: 'ix', | ||
params: { | ||
siteId: '123456', | ||
size: [300, 250] | ||
} | ||
}] | ||
}]; | ||
|
||
var pbjs = pbjs || {}; | ||
pbjs.que = pbjs.que || []; | ||
</script> | ||
|
||
<script> | ||
pbjs.que.push(function() { | ||
pbjs.setConfig({ | ||
mass: { | ||
enabled: true | ||
} | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. can you set even the defaults you have here on endpoint and deal pattern so that it serves as an example of how to change them |
||
}); | ||
}); | ||
</script> | ||
|
||
<script type="text/javascript" src="/build/dist/prebid.js" async></script> | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Is this working on your local after you execute There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. @FilipStamenkovic Thanks for this, it's now fixed. I also added a notice to let people know that in order for the page to actually work, you need access to a bid simulation tool. |
||
<script> | ||
var googletag = googletag || {}; | ||
googletag.cmd = googletag.cmd || []; | ||
googletag.cmd.push(function() { | ||
googletag.pubads().disableInitialLoad(); | ||
}); | ||
|
||
pbjs.que.push(function() { | ||
pbjs.addAdUnits(adUnits); | ||
pbjs.requestBids({ | ||
bidsBackHandler: sendAdserverRequest | ||
}); | ||
}); | ||
|
||
function sendAdserverRequest() { | ||
if (pbjs.adserverRequestSent) return; | ||
pbjs.adserverRequestSent = true; | ||
googletag.cmd.push(function() { | ||
pbjs.que.push(function() { | ||
pbjs.setTargetingForGPTAsync(); | ||
googletag.pubads().refresh(); | ||
}); | ||
}); | ||
} | ||
|
||
setTimeout(function() { | ||
sendAdserverRequest(); | ||
}, PREBID_TIMEOUT); | ||
</script> | ||
|
||
<script> | ||
(function () { | ||
var gads = document.createElement('script'); | ||
gads.async = true; | ||
gads.type = 'text/javascript'; | ||
var useSSL = 'https:' == document.location.protocol; | ||
gads.src = (useSSL ? 'https:' : 'http:') + | ||
'//www.googletagservices.com/tag/js/gpt.js'; | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. this isnt the current url for gpt |
||
var node = document.getElementsByTagName('script')[0]; | ||
node.parentNode.insertBefore(gads, node); | ||
})(); | ||
</script> | ||
|
||
<script> | ||
googletag.cmd.push(function () { | ||
googletag.defineSlot('/19968336/header-bid-tag-0', [[300, 250], [300, 600]], 'div-gpt-ad-1460505748561-0').addService(googletag.pubads()); | ||
|
||
googletag.pubads().enableSingleRequest(); | ||
googletag.enableServices(); | ||
}); | ||
</script> | ||
</head> | ||
|
||
<body style="margin: 0;"> | ||
<div id="content" style="width: 920px; padding: 20px; height: 2500px; margin: 0 auto; background-color: #222;"> | ||
<div id="div-gpt-ad-1460505748561-0"> | ||
<script type="text/javascript"> | ||
googletag.cmd.push(function() { googletag.display('div-gpt-ad-1460505748561-0'); }); | ||
</script> | ||
</div> | ||
</div> | ||
</body> | ||
</html> |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,130 @@ | ||
/** | ||
* This module adds MASS support to Prebid.js. | ||
*/ | ||
|
||
import { config } from '../src/config.js'; | ||
import { getHook } from '../src/hook.js'; | ||
import find from 'core-js-pure/features/array/find.js'; | ||
|
||
export let listenerAdded = false; | ||
export let massEnabled = false; | ||
|
||
const defaultCfg = { | ||
bootloaderUrl: 'https://cdn.massplatform.net/bootloader.js', | ||
dealIdPattern: /^MASS/i | ||
}; | ||
let cfg; | ||
|
||
const massBids = {}; | ||
|
||
init(); | ||
config.getConfig('mass', config => init(config.mass)); | ||
|
||
/** | ||
* Module init. | ||
*/ | ||
export function init(customCfg) { | ||
cfg = Object.assign({}, defaultCfg, customCfg); | ||
|
||
if (cfg.enabled === false) { | ||
if (massEnabled) { | ||
massEnabled = false; | ||
getHook('addBidResponse').getHooks({hook: addBidResponseHook}).remove(); | ||
} | ||
} else { | ||
if (!massEnabled) { | ||
getHook('addBidResponse').before(addBidResponseHook); | ||
massEnabled = true; | ||
} | ||
} | ||
} | ||
|
||
/** | ||
* Before hook for 'addBidResponse'. | ||
*/ | ||
export function addBidResponseHook(next, adUnitCode, bid) { | ||
if (!isMassBid(bid)) { | ||
return next(adUnitCode, bid); | ||
} | ||
|
||
const bidRequest = find(this.bidderRequest.bids, bidRequest => | ||
bidRequest.bidId === bid.requestId | ||
); | ||
|
||
massBids[bid.requestId] = { | ||
bidRequest, | ||
bid, | ||
adm: bid.ad | ||
}; | ||
|
||
bid.ad = '<script>window.parent.postMessage({massBidId: "' + bid.requestId + '"}, "*");\x3c/script>'; | ||
|
||
addListenerOnce(); | ||
|
||
next(adUnitCode, bid); | ||
} | ||
|
||
/** | ||
* Check if a bid is MASS. | ||
*/ | ||
export function isMassBid(bid) { | ||
// either bid.meta.mass is set or deal ID matches a publisher specified pattern: | ||
if (!((bid.meta && bid.meta.mass) || (cfg.dealIdPattern && cfg.dealIdPattern.test(bid.dealId)))) { | ||
return false; | ||
} | ||
|
||
// there must be a 'mass://' or 'pcreative?' in the ad markup: | ||
return /mass:\/\/|\/pcreative\?/i.test(bid.ad); | ||
} | ||
|
||
/** | ||
* Add listener to detect requests to render MASS ads. | ||
*/ | ||
export function addListenerOnce() { | ||
if (!listenerAdded) { | ||
window.addEventListener('message', e => { | ||
if (e && e.data && e.data.massBidId) { | ||
render(getRenderPayload(e)); | ||
} | ||
}); | ||
|
||
listenerAdded = true; | ||
} | ||
} | ||
|
||
/** | ||
* Prepare payload for render. | ||
*/ | ||
export function getRenderPayload(e) { | ||
const payload = { | ||
type: 'prebid', | ||
e | ||
}; | ||
|
||
Object.assign(payload, massBids[e.data.massBidId]); | ||
delete payload.bid.ad; | ||
|
||
return payload; | ||
} | ||
|
||
/** | ||
* Render a MASS ad. | ||
*/ | ||
export function render(payload) { | ||
const ns = window.mass = window.mass || {}; | ||
|
||
ns.bootloader = ns.bootloader || {queue: []}; | ||
ns.bootloader.queue.push(payload); | ||
|
||
if (!ns.bootloader.loaded) { | ||
const s = document.createElement('script'); | ||
s.type = 'text/javascript'; | ||
s.async = true; | ||
s.src = cfg.bootloaderUrl; | ||
|
||
const x = document.getElementsByTagName('script')[0]; | ||
x.parentNode.insertBefore(s, x); | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. You should load external script with function There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. loadExternalScript requires the module to be whitelisted, but, I think the MASS module does not fall under the category of modules that load external content, at least not in the way it is assumed for the current whitelisted modules. All currently whitelisted modules use the external code they load to implement Prebid specific logic, that is, the external code that is loaded affects how the module behaves. This is not the case for MASS. We only load external code when the bid is won, and that code is not Prebid-specific... it deals with rendering the ad, something that all other Prebid modules / bid adapters do via the "ad markup" field. The external code we load does not change any functionality implemented in mass.js. Makes sense? There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. |
||
|
||
ns.bootloader.loaded = true; | ||
} | ||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,61 @@ | ||
## Overview | ||
|
||
``` | ||
Module Name: MASS | ||
Module Type: Other | ||
Maintainer: [email protected] | ||
``` | ||
|
||
This module enables the MASS protocol for Prebid. To use it, you'll need to | ||
work with a MASS enabled provider. | ||
|
||
This module scans incoming bids for the presence of a "mass" flag being set to | ||
true in the bid meta or a publisher specified DealID pattern and uses | ||
external resources to decypher and process the MASS:// URI found within the ad markup. | ||
This modules is designed to work with MASS enabled Exchanges and DSP's. | ||
|
||
This module only loads external JavaScript resources if the publisher ad server has | ||
selected a MASS enabled bid as a winner. | ||
|
||
Find out more [here](https://massplatform.net). | ||
|
||
## Disclosure | ||
|
||
- This module loads external JavaScript to render creatives | ||
- This module should only be used by publishers that have been invited to the MASS network | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Can you remove this sentence and add the generic mode desription here as well? |
||
|
||
## Integration | ||
|
||
Build the MASS module into the Prebid.js package with: | ||
|
||
``` | ||
gulp build --modules=mass,... | ||
``` | ||
|
||
## Module Configuration | ||
|
||
```js | ||
pbjs.que.push(function() { | ||
pbjs.setConfig({ | ||
mass: { | ||
enabled: true, | ||
bootloaderUrl: 'https://cdn.massplatform.net/bootloader.js', | ||
dealIdPattern: /^MASS/i | ||
} | ||
}); | ||
}); | ||
``` | ||
|
||
## Disable MASS | ||
|
||
The MASS module is enabled by default, but you can disable it using: | ||
|
||
```js | ||
pbjs.que.push(function() { | ||
pbjs.setConfig({ | ||
mass: { | ||
enabled: false | ||
} | ||
}); | ||
}); | ||
``` |
Uh oh!
There was an error while loading. Please reload this page.