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 instream video and native support to ucfunnel adapter #2725

Merged
merged 27 commits into from
Jul 9, 2018
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
27 commits
Select commit Hold shift + click to select a range
d18db95
Add a new ucfunnel Adapter and test page
Jun 5, 2017
f82a4b7
Add a new ucfunnel Adapter and test page
Jun 5, 2017
4c91775
1. Use prebid lib in the repo to keep updated
RyanChouTw Jun 16, 2017
52eaecb
Merge branch 'master' into master
RyanChouTw Jun 16, 2017
96a70a4
utils.getTopWindowLocation is a function
RyanChouTw Jun 20, 2017
7202a62
Merge branch 'master' of https://github.com/prebid/Prebid.js
RyanChouTw Jun 28, 2017
858b833
Change to modules from adapters
RyanChouTw Jun 28, 2017
8b46932
Migrate to module design
RyanChouTw Jun 28, 2017
d7e043b
[Dev Fix] Remove width and height which can be got from ad unit id
RyanChouTw Jul 13, 2017
badfa53
Merge branch 'master' of https://github.com/prebid/Prebid.js
RyanChouTw Jul 13, 2017
8d81704
Merge pull request #1 from prebid/master
RyanChouTw Sep 25, 2017
8e7fe31
Merge branch 'master' of https://github.com/prebid/Prebid.js
RyanChouTw Dec 21, 2017
5dc00f3
Update ucfunnelBidAdapter to fit into new spec
RyanChouTw Dec 21, 2017
66c3a06
Correct the endpoint. Fix the error of query string
RyanChouTw Dec 21, 2017
0328e97
Add test case for ucfunnelBidAdapter
RyanChouTw Jan 11, 2018
c2c5eb0
Merge branch 'master' of https://github.com/prebid/Prebid.js
RyanChouTw Jan 11, 2018
86fdd23
Fix lint error
RyanChouTw Jan 12, 2018
c331f57
Update version number
RyanChouTw Jan 16, 2018
28acb40
Combine all checks on bid request
RyanChouTw Jan 18, 2018
93621b8
Merge branch 'master' of https://github.com/prebid/Prebid.js
RyanChouTw May 25, 2018
f7f2515
Add GDPR support for ucfunnel adapter
RyanChouTw May 25, 2018
d4f3467
Merge branch 'master' of https://github.com/prebid/Prebid.js
RyanChouTw Jun 14, 2018
1f79c44
Add in-stream video and native support for ucfunnel adapter
RyanChouTw Jun 14, 2018
7d8dc52
Remove demo page. Add more test cases.
RyanChouTw Jun 20, 2018
99fa86e
Change request method from POST to GET
RyanChouTw Jun 26, 2018
03e37e6
Remove unnecessary comment
RyanChouTw Jun 27, 2018
aabfdd4
Support vastXml and vastUrl for video request
RyanChouTw Jul 3, 2018
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
97 changes: 0 additions & 97 deletions integrationExamples/gpt/pbjs_ucfunnel_gpt.html

This file was deleted.

217 changes: 162 additions & 55 deletions modules/ucfunnelBidAdapter.js
Original file line number Diff line number Diff line change
@@ -1,43 +1,54 @@
import * as utils from 'src/utils';
import {registerBidder} from 'src/adapters/bidderFactory';
import { BANNER } from 'src/mediaTypes';
import {BANNER, VIDEO, NATIVE} from 'src/mediaTypes';

const VER = 'ADGENT_PREBID-2018011501';
const BID_REQUEST_BASE_URL = '//hb.aralego.com/header';
const UCFUNNEL_BIDDER_CODE = 'ucfunnel';
const BIDDER_CODE = 'ucfunnel';

const VIDEO_CONTEXT = {
INSTREAM: 0,
OUSTREAM: 2
}

export const spec = {
code: UCFUNNEL_BIDDER_CODE,
supportedMediaTypes: [BANNER],
code: BIDDER_CODE,
ENDPOINT: '//hb.aralego.com/header',
supportedMediaTypes: [BANNER, VIDEO, NATIVE],
/**
* Check if the bid is a valid zone ID in either number or string form
* @param {object} bid the ucfunnel bid to validate
* @return boolean for whether or not a bid is valid
*/
isBidRequestValid: function(bid) {
return !!(bid && bid.params && bid.params.adid && typeof bid.params.adid === 'string');
const isVideoMediaType = utils.deepAccess(bid, 'mediaTypes.video');
const videoContext = utils.deepAccess(bid, 'mediaTypes.video.context');

if (typeof bid.params !== 'object' || typeof bid.params.adid != 'string') {
return false;
}

if (isVideoMediaType && videoContext === 'outstream') {
utils.logWarn('Warning: outstream video is not supported yet');
return false;
}

return true;
},

/**
* @param {BidRequest[]} bidRequests
* @param {*} bidderRequest
* @return {ServerRequest}
*/
buildRequests: function(validBidRequests, bidderRequest) {
var bidRequests = [];
for (var i = 0; i < validBidRequests.length; i++) {
var bid = validBidRequests[i];

var ucfunnelUrlParams = buildUrlParams(bid, bidderRequest);

bidRequests.push({
buildRequests: function(bids, bidderRequest) {
return bids.map(bid => {
return {
method: 'GET',
url: BID_REQUEST_BASE_URL,
bidRequest: bid,
data: ucfunnelUrlParams
});
}
return bidRequests;
url: location.protocol + spec.ENDPOINT,
data: getRequestData(bid, bidderRequest),
bidRequest: bid
}
});
},

/**
Expand All @@ -46,55 +57,151 @@ export const spec = {
* @return {Bid[]} An array of formatted bids.
*/
interpretResponse: function (ucfunnelResponseObj, request) {
var bidResponses = [];
var bidRequest = request.bidRequest;
var responseBody = ucfunnelResponseObj ? ucfunnelResponseObj.body : {};
const bidRequest = request.bidRequest;
const ad = ucfunnelResponseObj ? ucfunnelResponseObj.body : {};
const videoPlayerSize = parseSizes(bidRequest);

bidResponses.push({
let bid = {
requestId: bidRequest.bidId,
cpm: responseBody.cpm || 0,
width: responseBody.width,
height: responseBody.height,
creativeId: responseBody.ad_id,
dealId: responseBody.deal || null,
cpm: ad.cpm || 0,
creativeId: ad.ad_id,
dealId: ad.deal || null,
currency: 'USD',
netRevenue: true,
ttl: 1000,
mediaType: BANNER,
ad: responseBody.adm
});
ttl: 1000
};

if (ad.creative_type) {
bid.mediaType = ad.creative_type;
}

switch (ad.creative_type) {
case NATIVE:
let nativeAd = ad.native;
Object.assign(bid, {
width: 1,
height: 1,
native: {
title: nativeAd.title,
body: nativeAd.desc,
cta: nativeAd.ctatext,
sponsoredBy: nativeAd.sponsored,
image: nativeAd.image || nativeAd.image.url,
icon: nativeAd.icon || nativeAd.icon.url,
clickUrl: nativeAd.clickUrl,
impressionTrackers: nativeAd.impressionTrackers,
}
});
break;
case VIDEO:
Object.assign(bid, {
vastUrl: ad.vastUrl,
vastXml: ad.vastXml
});

if (videoPlayerSize && videoPlayerSize.length === 2) {
Object.assign(bid, {
width: videoPlayerSize[0],
height: videoPlayerSize[1]
});
}
break;
case BANNER:
default:
Object.assign(bid, {
width: ad.width,
height: ad.height,
ad: ad.adm
});
}

return [bid];
},

return bidResponses;
getUserSyncs: function(syncOptions) {
if (syncOptions.iframeEnabled) {
return [{
type: 'iframe',
url: '//cdn.aralego.com/ucfad/cookie/sync.html'
}];
} else if (syncOptions.pixelEnabled) {
return [{
type: 'image',
url: '//sync.aralego.com/idSync'
}];
}
}
};
registerBidder(spec);

function buildUrlParams(bid, bidderRequest) {
const host = utils.getTopWindowLocation().host;
const page = utils.getTopWindowLocation().pathname;
const refer = document.referrer;
function transformSizes(requestSizes) {
if (utils.isArray(requestSizes) && requestSizes.length === 2 && !utils.isArray(requestSizes[0])) {
return [parseInt(requestSizes[0], 10), parseInt(requestSizes[1], 10)];
} else if (typeof requestSizes === 'object' && requestSizes.length) {
return requestSizes[0];
}
}

function parseSizes(bid) {
let params = bid.params;
if (bid.mediaType === VIDEO) {
let size = [];
if (params.video && params.video.playerWidth && params.video.playerHeight) {
size = [
params.video.playerWidth,
params.video.playerHeight
];
return size;
}
}

return transformSizes(bid.sizes);
}

function getRequestData(bid, bidderRequest) {
const size = parseSizes(bid);
const loc = utils.getTopWindowLocation();
const host = loc.host;
const page = loc.href;
const ref = utils.getTopWindowReferrer();
const language = navigator.language;
const dnt = (navigator.doNotTrack == 'yes' || navigator.doNotTrack == '1' || navigator.msDoNotTrack == '1') ? 1 : 0;
const videoContext = utils.deepAccess(bid, 'mediaTypes.video.context');
const videoMediaType = utils.deepAccess(bid, 'mediaTypes.video');

let queryString = [
'ifr', '0',
'bl', language,
'je', '1',
'dnt', dnt,
'host', host,
'u', page,
'ru', refer,
'adid', utils.getBidIdParameter('adid', bid.params),
'ver', VER
];
// general bid data
let bidData = {
ver: VER,
ifr: 0,
bl: language,
je: 1,
dnt: dnt,
host: host,
u: page,
ru: ref,
adid: utils.getBidIdParameter('adid', bid.params),
w: size[0],
h: size[1]
};

if (bid.mediaType === 'video' || videoMediaType) {
switch (videoContext) {
case 'outstream':
bidData.atype = VIDEO_CONTEXT.OUSTREAM;
break;
case 'instream':
default:
bidData.atype = VIDEO_CONTEXT.INSTREAM;
break;
}
}

if (bidderRequest && bidderRequest.gdprConsent) {
queryString.push('gdpr', bidderRequest.gdprConsent.gdprApplies ? 1 : 0);
queryString.push('euconsent', bidderRequest.gdprConsent.consentString);
Object.assign(bidData, {
gdpr: bidderRequest.gdprConsent.gdprApplies ? 1 : 0,
euconsent: bidderRequest.gdprConsent.consentString
});
}

return queryString.reduce(
(memo, curr, index) =>
index % 2 === 0 && queryString[index + 1] !== undefined ? memo + curr + '=' + encodeURIComponent(queryString[index + 1]) + '&' : memo, ''
).slice(0, -1);
return bidData;
}
Loading