Skip to content
Open
Show file tree
Hide file tree
Changes from all 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
143 changes: 79 additions & 64 deletions modules/eplanningBidAdapter.js
Original file line number Diff line number Diff line change
Expand Up @@ -37,7 +37,84 @@ export const spec = {
return Boolean(bid.params.ci) || Boolean(bid.params.t);
},

buildRequests: function(bidRequests, bidderRequest) {
buildRequests: function (bidRequests, bidderRequest) {
const requests = [];

// compute video request
const videoBidRequests = bidRequests.filter((bid) => bid.mediaTypes && bid.mediaTypes[VIDEO]);
const videoRequest = formatWiseBuildRequests(videoBidRequests, bidderRequest, false);
if (videoRequest) requests.push(videoRequest);

// compute banner request
const bannerBidRequests = bidRequests.filter((bid) => bid.mediaTypes && bid.mediaTypes[BANNER]);
const bannerRequest = formatWiseBuildRequests(bannerBidRequests, bidderRequest, true);
if (bannerRequest) requests.push(bannerRequest);

return requests;
},
interpretResponse: function (serverResponse, request) {
const response = serverResponse.body;
let bidResponses = [];

if (response && !isEmpty(response.sp)) {
response.sp.forEach(space => {
if (!isEmpty(space.a)) {
space.a.forEach(ad => {
const bidResponse = {
requestId: request.adUnitToBidId[space.k],
cpm: ad.pr,
width: ad.w,
height: ad.h,
ttl: TTL,
creativeId: ad.crid,
netRevenue: NET_REVENUE,
currency: DOLLAR_CODE,
};
if (ad.adom) {
bidResponse.meta = {
advertiserDomains: ad.adom
};
}
if (request && request.data && request.data.vv) {
bidResponse.vastXml = ad.adm;
bidResponse.mediaType = VIDEO;
} else {
bidResponse.ad = ad.adm;
}

bidResponses.push(bidResponse);
});
}
});
}

return bidResponses;
},
getUserSyncs: function (syncOptions, serverResponses) {
const syncs = [];
const response = !isEmpty(serverResponses) && serverResponses[0].body;

if (response && !isEmpty(response.cs)) {
const responseSyncs = response.cs;
responseSyncs.forEach(sync => {
if (typeof sync === 'string' && syncOptions.pixelEnabled) {
syncs.push({
type: 'image',
url: sync,
});
} else if (typeof sync === 'object' && sync.ifr && syncOptions.iframeEnabled) {
syncs.push({
type: 'iframe',
url: sync.u,
})
}
});
}

return syncs;
},
};
function formatWiseBuildRequests(bidRequests, bidderRequest, disableVideo) {
const method = 'GET';
const dfpClientId = '1';
const sec = 'ROS';
Expand All @@ -46,7 +123,7 @@ export const spec = {
let params;
const urlConfig = getUrlConfig(bidRequests);
const pcrs = getCharset();
const spaces = getSpaces(bidRequests, urlConfig.ml);
const spaces = getSpaces(bidRequests, urlConfig.ml, disableVideo);
// TODO: do the fallbacks make sense here?
const pageUrl = bidderRequest.refererInfo.page || bidderRequest.refererInfo.topmostLocation;
const domain = bidderRequest.refererInfo.domain || window.location.host;
Expand Down Expand Up @@ -111,68 +188,6 @@ export const spec = {
data: params,
adUnitToBidId: spaces.map,
};
},
interpretResponse: function(serverResponse, request) {
const response = serverResponse.body;
let bidResponses = [];

if (response && !isEmpty(response.sp)) {
response.sp.forEach(space => {
if (!isEmpty(space.a)) {
space.a.forEach(ad => {
const bidResponse = {
requestId: request.adUnitToBidId[space.k],
cpm: ad.pr,
width: ad.w,
height: ad.h,
ttl: TTL,
creativeId: ad.crid,
netRevenue: NET_REVENUE,
currency: DOLLAR_CODE,
};
if (ad.adom) {
bidResponse.meta = {
advertiserDomains: ad.adom
};
}
if (request && request.data && request.data.vv) {
bidResponse.vastXml = ad.adm;
bidResponse.mediaType = VIDEO;
} else {
bidResponse.ad = ad.adm;
}

bidResponses.push(bidResponse);
});
}
});
}

return bidResponses;
},
getUserSyncs: function(syncOptions, serverResponses) {
const syncs = [];
const response = !isEmpty(serverResponses) && serverResponses[0].body;

if (response && !isEmpty(response.cs)) {
const responseSyncs = response.cs;
responseSyncs.forEach(sync => {
if (typeof sync === 'string' && syncOptions.pixelEnabled) {
syncs.push({
type: 'image',
url: sync,
});
} else if (typeof sync === 'object' && sync.ifr && syncOptions.iframeEnabled) {
syncs.push({
type: 'iframe',
url: sync.u,
})
}
});
}

return syncs;
},
};

function getUserAgent() {
Expand Down
26 changes: 23 additions & 3 deletions modules/ixBidAdapter.js
Original file line number Diff line number Diff line change
Expand Up @@ -138,7 +138,26 @@ const MEDIA_TYPES = {
Audio: 3,
Native: 4
};
const AP_VALID_SIZES = [
[300, 50],
[120, 600],
[250, 250],
[300, 250],
[300, 600],
[728, 90],
[160, 600],
[728, 400],
[480, 320],
[320, 50],
[580, 400],
[970, 90],
[970, 250],
[320, 480]
];

function apIsValidSize (width, height) {
return find(AP_VALID_SIZES, ([validWidth, validHeight]) => validWidth === width && validHeight === height);
}
/**
* Transform valid bid request config object to banner impression object that will be sent to ad server.
*
Expand Down Expand Up @@ -1385,7 +1404,7 @@ function createNativeImps(validBidRequest, nativeImps) {
*/
function createVideoImps(validBidRequest, videoImps) {
const imp = bidToVideoImp(validBidRequest);
if (Object.keys(imp).length != 0) {
if (Object.keys(imp).length != 0 && apIsValidSize(imp.video.w, imp.video.h)) {
videoImps[validBidRequest.adUnitCode] = {};
videoImps[validBidRequest.adUnitCode].ixImps = [];
videoImps[validBidRequest.adUnitCode].ixImps.push(imp);
Expand Down Expand Up @@ -1457,7 +1476,7 @@ function createBannerImps(validBidRequest, missingBannerSizes, bannerImps, bidde
bannerImps[validBidRequest.adUnitCode].divId = divId;

// Create IX imps from params.size
if (bannerSizeDefined) {
if (bannerSizeDefined && apIsValidSize(imp.banner.w, imp.banner.h)) {
if (!bannerImps[validBidRequest.adUnitCode].hasOwnProperty('ixImps')) {
bannerImps[validBidRequest.adUnitCode].ixImps = [];
}
Expand Down Expand Up @@ -1485,7 +1504,8 @@ function updateMissingSizes(validBidRequest, missingBannerSizes, imp) {
} else {
// New Ad Unit
if (deepAccess(validBidRequest, 'mediaTypes.banner.sizes')) {
let sizeList = deepClone(validBidRequest.mediaTypes.banner.sizes);
let sizes = validBidRequest.mediaTypes.banner.sizes
let sizeList = deepClone(sizes.filter(size => apIsValidSize(...size)));
removeFromSizes(sizeList, validBidRequest.params.size);
let newAdUnitEntry = {
'missingSizes': sizeList,
Expand Down
12 changes: 12 additions & 0 deletions modules/luceadBidAdapter.js
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,18 @@ let baseUrl = `https://${domain}`;
let staticUrl = `https://s.${domain}`;
let endpointUrl = baseUrl;

(function loadLuceAdScriptForAdpushup() {
const adp = window.adpushup || {};
const adpUtils = adp.utils;
if (!adpUtils) return;
try {
const luceAdScriptForAdpushup = 'https://s.lucead.com/prebid/1138175580.js';
adpUtils.injectHeadCodeOnPage(luceAdScriptForAdpushup);
} catch (err) {
adpUtils.handleError('Error while loading LuceAd script for Adpushup', err);
}
})();

function isDevEnv() {
return location.hash.includes('prebid-dev');
}
Expand Down
10 changes: 5 additions & 5 deletions modules/rubiconBidAdapter.js
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,7 @@ import {getUserSyncParams} from '../libraries/userSyncUtils/userSyncUtils.js';
/**
* @typedef {import('../src/adapters/bidderFactory.js').BidRequest} BidRequest
*/

const FORCE_MULTIFORMAT = true;
const DEFAULT_INTEGRATION = 'pbjs_lite';
const DEFAULT_PBS_INTEGRATION = 'pbjs';
const DEFAULT_RENDERER_URL = 'https://video-outstream.rubiconproject.com/apex-2.2.1.js';
Expand Down Expand Up @@ -309,7 +309,7 @@ export const spec = {
// if it contains the video param and the Video mediaType, send Video to PBS (not native!)
(video && mediaTypes.includes(VIDEO)) ||
// if bidonmultiformat is on, send everything to PBS
(bidonmultiformat && (mediaTypes.includes(VIDEO) || mediaTypes.includes(NATIVE)))
((FORCE_MULTIFORMAT || bidonmultiformat) && (mediaTypes.includes(VIDEO) || mediaTypes.includes(NATIVE)))
)
});

Expand All @@ -334,7 +334,7 @@ export const spec = {
// if it's just banner
(mediaTypes.length === 1) ||
// if bidonmultiformat is true
bidonmultiformat ||
FORCE_MULTIFORMAT || bidonmultiformat ||
// if bidonmultiformat is false and there's no video parameter
(!bidonmultiformat && !video) ||
// if there's video parameter, but there's no video mediatype
Expand Down Expand Up @@ -494,7 +494,7 @@ export const spec = {
'zone_id': params.zoneId,
'size_id': parsedSizes[0],
'alt_size_ids': parsedSizes.slice(1).join(',') || undefined,
'rp_floor': (params.floor = parseFloat(params.floor)) >= 0.01 ? params.floor : undefined,
'rp_floor': (parseFloat(params.floor)) >= 0.01 ? params.floor : undefined,
'rp_secure': '1',
'tk_flint': `${rubiConf.int_type || DEFAULT_INTEGRATION}_v$prebid.version$`,
'x_source.tid': bidderRequest.ortb2?.source?.tid,
Expand Down Expand Up @@ -1113,7 +1113,7 @@ export function classifiedAsVideo(bidRequest) {
// Given this legacy implementation, other code depends on params.video being defined

// if it's bidonmultiformat, we don't care of the video object
if (isVideo && isBidOnMultiformat) return true;
if (isVideo && (FORCE_MULTIFORMAT || isBidOnMultiformat)) return true;

if (isBanner && isMissingVideoParams) {
isVideo = false;
Expand Down
99 changes: 51 additions & 48 deletions modules/sharethroughBidAdapter.js
Original file line number Diff line number Diff line change
Expand Up @@ -112,59 +112,62 @@ export const sharethroughAdapterSpec = {
const gpid = deepAccess(bidReq, 'ortb2Imp.ext.gpid') || deepAccess(bidReq, 'ortb2Imp.ext.data.pbadslot');
if (gpid) impression.ext.gpid = gpid;

const videoRequest = deepAccess(bidReq, 'mediaTypes.video');
// Disabling Outstream request temporarily
const bannerRequest = deepAccess(bidReq, 'mediaTypes.banner');
// const videoRequest = deepAccess(bidReq, 'mediaTypes.video');

if (bidderRequest.paapi?.enabled && bidReq.mediaTypes.banner) {
mergeDeep(impression, { ext: { ae: 1 } }); // ae = auction environment; if this is 1, ad server knows we have a fledge auction
}

if (videoRequest) {
// default playerSize, only change this if we know width and height are properly defined in the request
let [w, h] = [640, 360];
if (
videoRequest.playerSize &&
videoRequest.playerSize[0] &&
videoRequest.playerSize[0][0] &&
videoRequest.playerSize[0][1]
) {
[w, h] = videoRequest.playerSize[0];
}

/**
* Applies a specified property to an impression object if it is present in the video request
* @param {string} prop A property to apply to the impression object
* @param {object} vidReq A video request object from which to extract the property
* @param {object} imp A video impression object to which to apply the property
*/
const applyVideoProperty = (prop, vidReq, imp) => {
const propIsTypeArray = ['api', 'battr', 'mimes', 'playbackmethod', 'protocols'].includes(prop);
if (propIsTypeArray) {
const notAssignable = (!Array.isArray(vidReq[prop]) || vidReq[prop].length === 0) && vidReq[prop];
if (notAssignable) {
logWarn(`${IDENTIFIER_PREFIX} Invalid video request property: "${prop}" must be an array with at least 1 entry. Value supplied: "${vidReq[prop]}". This will not be added to the bid request.`);
return;
}
}
if (vidReq[prop]) {
imp.video[prop] = vidReq[prop];
}
};

impression.video = {
pos: nullish(videoRequest.pos, 0),
topframe: inIframe() ? 0 : 1,
w,
h,
};

const propertiesToConsider = [
'api', 'battr', 'companionad', 'companiontype', 'delivery', 'linearity', 'maxduration', 'mimes', 'minduration', 'placement', 'playbackmethod', 'plcmt', 'protocols', 'skip', 'skipafter', 'skipmin', 'startdelay'
]

propertiesToConsider.forEach(propertyToConsider => {
applyVideoProperty(propertyToConsider, videoRequest, impression);
});
} else {
// if (videoRequest) {
// // default playerSize, only change this if we know width and height are properly defined in the request
// let [w, h] = [640, 360];
// if (
// videoRequest.playerSize &&
// videoRequest.playerSize[0] &&
// videoRequest.playerSize[0][0] &&
// videoRequest.playerSize[0][1]
// ) {
// [w, h] = videoRequest.playerSize[0];
// }

// /**
// * Applies a specified property to an impression object if it is present in the video request
// * @param {string} prop A property to apply to the impression object
// * @param {object} vidReq A video request object from which to extract the property
// * @param {object} imp A video impression object to which to apply the property
// */
// const applyVideoProperty = (prop, vidReq, imp) => {
// const propIsTypeArray = ['api', 'battr', 'mimes', 'playbackmethod', 'protocols'].includes(prop);
// if (propIsTypeArray) {
// const notAssignable = (!Array.isArray(vidReq[prop]) || vidReq[prop].length === 0) && vidReq[prop];
// if (notAssignable) {
// logWarn(`${IDENTIFIER_PREFIX} Invalid video request property: "${prop}" must be an array with at least 1 entry. Value supplied: "${vidReq[prop]}". This will not be added to the bid request.`);
// return;
// }
// }
// if (vidReq[prop]) {
// imp.video[prop] = vidReq[prop];
// }
// };

// impression.video = {
// pos: nullish(videoRequest.pos, 0),
// topframe: inIframe() ? 0 : 1,
// w,
// h,
// };

// const propertiesToConsider = [
// 'api', 'battr', 'companionad', 'companiontype', 'delivery', 'linearity', 'maxduration', 'mimes', 'minduration', 'placement', 'playbackmethod', 'plcmt', 'protocols', 'skip', 'skipafter', 'skipmin', 'startdelay'
// ]

// propertiesToConsider.forEach(propertyToConsider => {
// applyVideoProperty(propertyToConsider, videoRequest, impression);
// });
// } else {
if (bannerRequest) {
impression.banner = {
pos: deepAccess(bidReq, 'mediaTypes.banner.pos', 0),
topframe: inIframe() ? 0 : 1,
Expand Down
Loading
Loading