Skip to content

Commit

Permalink
Update emoteevBidAdapter.js (#3928)
Browse files Browse the repository at this point in the history
* Update emoteevBidAdapter.js

Retrieve various data from the adapter configuration, and ensure they
are properly formatted:
- GDPR vendor consent
- Metadata: intended to be used as an ID for external partners
- Context: describe the context of the current ad unit

Test coverage for emoteevBidAdapter.js:
- Statements 94.83%
- Branches 98.39%
- Functions 100%
- Lines 94.34%

fixup! Update emoteevBidAdapter.js

* remove pubCommonId import from emoteevBidAdapter

* Format indentation

* More detailed integration page example

* Rename attribute to externalId

* Simplify names of constants

* Minor tweak

* Update context value
  • Loading branch information
piotr-yuxuan authored and Mike Chowla committed Jul 1, 2019
1 parent 9c73631 commit be76682
Show file tree
Hide file tree
Showing 4 changed files with 263 additions and 79 deletions.
145 changes: 88 additions & 57 deletions integrationExamples/gpt/hello_world_emoteev.html
Original file line number Diff line number Diff line change
Expand Up @@ -5,68 +5,99 @@
<script async src="//www.googletagservices.com/tag/js/gpt.js"></script>
<script type="text/javascript" src="../../build/dev/prebid.js" async></script>
<script>
const sizes = [
[300, 250],
[250, 300],
[300, 600]
];
const PREBID_TIMEOUT = 3000;
const FAILSAFE_TIMEOUT = 3000;
const sizes = [
[728, 90], // Footer
[750, 200], // Content
[300, 250], // Content
[320, 480], // Overlay

const adUnits = [{
code: '/19968336/header-bid-tag-1',
mediaTypes: {
banner: {
sizes: sizes
}
},
bids: [{
bidder: 'emoteev',
params: {
adSpaceId: 5084,
}
}]
}];
// some further examples from https://www.iab.com/wp-content/uploads/2017/08/IABNewAdPortfolio_FINAL_2017.pdf
[900, 225], // IAB: horizontal, Billboard
[900, 450], // IAB: horizontal, Half Page
[300, 150], // IAB: horizontal 2x1 and tiles Financial
[300, 600], // IAB: vertical 1x2
[300, 900] // IAB: vertical 1x3 Portrait
];
const PREBID_TIMEOUT = 3000;
const FAILSAFE_TIMEOUT = 3000;

// ======== DO NOT EDIT BELOW THIS LINE =========== //
var googletag = googletag || {};
googletag.cmd = googletag.cmd || [];
googletag.cmd.push(function () {
googletag.pubads().disableInitialLoad();
});
const adUnits = [{
code: '/19968336/header-bid-tag-1',
mediaTypes: {
banner: {
sizes: sizes
}
},
bids: [{
bidder: 'emoteev',
params: {
adSpaceId: 5084,
context: 'content',
externalId: null
}
}, {
bidder: 'emoteev',
params: {
adSpaceId: 5084,
context: 'footer',
externalId: null
}
}, {
bidder: 'emoteev',
params: {
adSpaceId: 5084,
context: 'overlay',
externalId: null
}
}, {
bidder: 'emoteev',
params: {
adSpaceId: 5084,
context: 'wallpaper',
externalId: null
}
}]
}];

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

pbjs.que.push(function () {
pbjs.addAdUnits(adUnits);
pbjs.requestBids({
bidsBackHandler: initAdserver,
timeout: PREBID_TIMEOUT
// ======== DO NOT EDIT BELOW THIS LINE =========== //
var googletag = googletag || {};
googletag.cmd = googletag.cmd || [];
googletag.cmd.push(function () {
googletag.pubads().disableInitialLoad();
});
});

function initAdserver() {
if (pbjs.initAdserverSet) return;
pbjs.initAdserverSet = true;
googletag.cmd.push(function () {
pbjs.que.push(function () {
pbjs.setTargetingForGPTAsync();
googletag.pubads().refresh();
});
var pbjs = pbjs || {};
pbjs.que = pbjs.que || [];

pbjs.que.push(function () {
pbjs.addAdUnits(adUnits);
pbjs.requestBids({
bidsBackHandler: initAdserver,
timeout: PREBID_TIMEOUT
});
});
}

setTimeout(function () {
initAdserver();
}, FAILSAFE_TIMEOUT);
function initAdserver() {
if (pbjs.initAdserverSet) return;
pbjs.initAdserverSet = true;
googletag.cmd.push(function () {
pbjs.que.push(function () {
pbjs.setTargetingForGPTAsync();
googletag.pubads().refresh();
});
});
}

setTimeout(function () {
initAdserver();
}, FAILSAFE_TIMEOUT);

googletag.cmd.push(function () {
googletag.defineSlot('/19968336/header-bid-tag-1', sizes, 'div-1')
.addService(googletag.pubads());
googletag.pubads().enableSingleRequest();
googletag.enableServices();
});
googletag.cmd.push(function () {
googletag.defineSlot('/19968336/header-bid-tag-1', sizes, 'div-1')
.addService(googletag.pubads());
googletag.pubads().enableSingleRequest();
googletag.enableServices();
});
</script>
</head>

Expand All @@ -75,9 +106,9 @@ <h2>Basic Prebid.js Example</h2>
<h5>Div-1</h5>
<div id='div-1'>
<script type='text/javascript'>
googletag.cmd.push(function () {
googletag.display('div-1');
});
googletag.cmd.push(function () {
googletag.display('div-1');
});

</script>
</div>
Expand Down
52 changes: 46 additions & 6 deletions modules/emoteevBidAdapter.js
Original file line number Diff line number Diff line change
Expand Up @@ -22,11 +22,12 @@ import {
contains,
deepAccess,
isArray,
getParameterByName
isInteger,
getParameterByName,
getCookie
} from '../src/utils';
import {config} from '../src/config';
import * as url from '../src/url';
import {getCookie} from './pubCommonId';

export const BIDDER_CODE = 'emoteev';

Expand Down Expand Up @@ -60,6 +61,19 @@ export const ON_ADAPTER_CALLED = 'on_adapter_called';
export const ON_BID_WON = 'on_bid_won';
export const ON_BIDDER_TIMEOUT = 'on_bidder_timeout';

export const IN_CONTENT = 'content';
export const FOOTER = 'footer';
export const OVERLAY = 'overlay';
export const WALLPAPER = 'wallpaper';

/**
* Vendor ID assigned to Emoteev from the Global Vendor & CMP List.
*
* See https://vendorlist.consensu.org/vendorinfo.json for more information.
* @type {number}
*/
export const VENDOR_ID = 15;

/**
* Pure function. See http://prebid.org/dev-docs/bidder-adaptor.html#valid-build-requests-array for detailed semantic.
*
Expand All @@ -71,6 +85,8 @@ export const isBidRequestValid = (bidRequest) => {
bidRequest &&
bidRequest.params &&
deepAccess(bidRequest, 'params.adSpaceId') &&
validateContext(deepAccess(bidRequest, 'params.context')) &&
validateExternalId(deepAccess(bidRequest, 'params.externalId')) &&
bidRequest.bidder === BIDDER_CODE &&
validateSizes(deepAccess(bidRequest, 'mediaTypes.banner.sizes')));
};
Expand All @@ -89,7 +105,7 @@ export const buildRequests = (env, debug, currency, validBidRequests, bidderRequ
return {
method: 'POST',
url: bidderUrl(env),
data: JSON.stringify(requestsPayload(debug, currency, validBidRequests, bidderRequest))
data: JSON.stringify(requestsPayload(debug, currency, validBidRequests, bidderRequest)) // Keys with undefined values will be filtered out.
};
};

Expand Down Expand Up @@ -264,7 +280,23 @@ export const userSyncImageUrl = env => url.format({
* @param {Array<Array<int>>} sizes
* @returns {boolean} are sizes valid?
*/
const validateSizes = sizes => isArray(sizes) && sizes.some(size => isArray(size) && size.length === 2);
export const validateSizes = sizes => isArray(sizes) && sizes.length > 0 && sizes.every(size => isArray(size) && size.length === 2);

/**
* Pure function.
*
* @param {string} context
* @returns {boolean} is param `context` valid?
*/
export const validateContext = context => contains([IN_CONTENT, FOOTER, OVERLAY, WALLPAPER], context);

/**
* Pure function.
*
* @param {(number|null|undefined)} externalId
* @returns {boolean} is param `externalId` valid?
*/
export const validateExternalId = externalId => externalId === undefined || externalId === null || (isInteger(externalId) && externalId > 0);

/**
* Pure function.
Expand All @@ -282,6 +314,14 @@ export const conformBidRequest = bidRequest => {
};
};

/**
* Pure function.
*
* @param {object} bidderRequest
* @returns {(boolean|undefined)} raw consent data.
*/
export const gdprConsent = (bidderRequest) => (deepAccess(bidderRequest, 'gdprConsent.vendorData.vendorConsents') || {})[VENDOR_ID];

/**
* Pure function.
*
Expand All @@ -306,7 +346,7 @@ export const requestsPayload = (debug, currency, validBidRequests, bidderRequest
isWebGLEnabled(document)),
userAgent: navigator.userAgent,
gdprApplies: deepAccess(bidderRequest, 'gdprConsent.gdprApplies'),
gdprConsent: deepAccess(bidderRequest, 'gdprConsent.consentString'),
gdprConsent: gdprConsent(bidderRequest),
};
};

Expand Down Expand Up @@ -426,7 +466,7 @@ export const getDeviceInfo = (deviceDimensions, viewDimensions, documentDimensio
* Pure function
* @param {object} config pbjs config value
* @param {string} parameter Environment override from URL query param.
* @returns One of [PRODUCTION, STAGING, DEVELOPMENT].
* @returns {string} One of [PRODUCTION, STAGING, DEVELOPMENT].
*/
export const resolveEnv = (config, parameter) => {
const configEnv = deepAccess(config, 'emoteev.env');
Expand Down
6 changes: 4 additions & 2 deletions modules/emoteevBidAdapter.md
Original file line number Diff line number Diff line change
Expand Up @@ -18,14 +18,16 @@ Module that connects to Emoteev's demand sources
code: 'test-div',
mediaTypes: {
banner: {
sizes: [[300, 250]],
sizes: [[720, 90]],
}
},
bids: [
{
bidder: 'emoteev',
params: {
adSpaceId: 5084
adSpaceId: 5084,
context: 'footer',
externalId: 42,
}
}
]
Expand Down
Loading

0 comments on commit be76682

Please sign in to comment.