Skip to content

Commit

Permalink
Merge branch 'prebid:master' into master
Browse files Browse the repository at this point in the history
  • Loading branch information
wyand-sp authored May 31, 2024
2 parents ae0b300 + 3f20fa3 commit db1a750
Show file tree
Hide file tree
Showing 19 changed files with 875 additions and 77 deletions.
4 changes: 2 additions & 2 deletions integrationExamples/gpt/cstg_example.html
Original file line number Diff line number Diff line change
Expand Up @@ -29,8 +29,8 @@
function updateUID2GuiElements() {
console.log('Updating displayed values.');
const uid2 = pbjs.getUserIds().uid2;
document.querySelector('#uid2TargetedAdvertisingReady').innerText = uid2 ? 'yes' : 'no';
document.querySelector('#uid2AdvertisingToken').innerText = uid2 ? String(uid2.id) : '';
document.querySelector('#uid2TargetedAdvertisingReady').innerText = uid2 && !uid2.optout ? 'yes' : 'no';
document.querySelector('#uid2AdvertisingToken').innerText = uid2 && !uid2.optout ? String(uid2.id) : uid2 && uid2.optout ? 'Optout' : '';
if (!uid2) {
document.querySelector('#uid2LoginForm').style['display'] = 'block';
document.querySelector('#uid2ClearStorageForm').style['display'] = 'none';;
Expand Down
1 change: 1 addition & 0 deletions libraries/autoplayDetection/autoplay.js
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
let autoplayEnabled = null;

/**
* DEVELOPER WARNING: IMPORTING THIS LIBRARY MAY MAKE YOUR ADAPTER NO LONGER COMPATIBLE WITH APP PUBLISHERS USING WKWEBVIEW
* Note: this function returns true if detection is not done yet. This is by design: if autoplay is not allowed,
* the call to video.play() will fail immediately, otherwise it may not terminate.
* @returns true if autoplay is not forbidden
Expand Down
2 changes: 2 additions & 0 deletions modules/adfBidAdapter.js
Original file line number Diff line number Diff line change
Expand Up @@ -78,13 +78,15 @@ export const spec = {
const bidfloor = floorInfo.floor;
const bidfloorcur = floorInfo.currency;
const { mid, inv, mname } = bid.params;
const impExtData = bid.ortb2Imp?.ext?.data;

const imp = {
id: id + 1,
tagid: mid,
bidfloor,
bidfloorcur,
ext: {
data: impExtData,
bidder: {
inv,
mname
Expand Down
18 changes: 1 addition & 17 deletions modules/luponmediaBidAdapter.js
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,6 @@ import {
import {registerBidder} from '../src/adapters/bidderFactory.js';
import {config} from '../src/config.js';
import {BANNER} from '../src/mediaTypes.js';
import {ajax} from '../src/ajax.js';

const BIDDER_CODE = 'luponmedia';
const ENDPOINT_URL = 'https://rtb.adxpremium.services/openrtb2/auction';
Expand Down Expand Up @@ -220,19 +219,6 @@ export const spec = {

hasSynced = true;
return allUserSyncs;
},
onBidWon: bid => {
const bidString = JSON.stringify(bid);
spec.sendWinningsToServer(bidString);
},
sendWinningsToServer: data => {
let mutation = `mutation {createWin(input: {win: {eventData: "${window.btoa(data)}"}}) {win {createTime } } }`;
let dataToSend = JSON.stringify({ query: mutation });

ajax('https://analytics.adxpremium.services/graphql', null, dataToSend, {
contentType: 'application/json',
method: 'POST'
});
}
};

Expand Down Expand Up @@ -469,9 +455,7 @@ function newOrtbBidRequest(bidRequest, bidderRequest, currentImps) {
deepSetValue(data, 'ext.prebid.bidderconfig.0', bidderData);
}

// TODO: bidRequest.fpd is not the right place for pbadslot - who's filling that in, if anyone?
// is this meant to be bidRequest.ortb2Imp.ext.data.pbadslot?
const pbAdSlot = deepAccess(bidRequest, 'fpd.context.pbAdSlot');
const pbAdSlot = deepAccess(bidRequest, 'ortb2Imp.ext.data.pbadslot');
if (typeof pbAdSlot === 'string' && pbAdSlot) {
deepSetValue(data.imp[0].ext, 'context.data.adslot', pbAdSlot);
}
Expand Down
2 changes: 1 addition & 1 deletion modules/outbrainBidAdapter.js
Original file line number Diff line number Diff line change
Expand Up @@ -354,7 +354,7 @@ function getVideoAsset(bid) {
minduration: bid.mediaTypes.video.minduration,
maxduration: bid.mediaTypes.video.maxduration,
startdelay: bid.mediaTypes.video.startdelay,
placement: bid.mediaTypes.video.placement,
placement: bid.mediaTypes.video.plcmt ?? bid.mediaTypes.video.placement,
linearity: bid.mediaTypes.video.linearity
};
}
Expand Down
6 changes: 3 additions & 3 deletions modules/pubmaticBidAdapter.js
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,7 @@ const DEFAULT_HEIGHT = 0;
const PREBID_NATIVE_HELP_LINK = 'http://prebid.org/dev-docs/show-native-ads.html';
const PUBLICATION = 'pubmatic'; // Your publication on Blue Billywig, potentially with environment (e.g. publication.bbvms.com or publication.test.bbvms.com)
const RENDERER_URL = 'https://pubmatic.bbvms.com/r/'.concat('$RENDERER', '.js'); // URL of the renderer application
const MSG_VIDEO_PLACEMENT_MISSING = 'Video.Placement param missing';
const MSG_VIDEO_PLCMT_MISSING = 'Video.plcmt param missing';

const CUSTOM_PARAMS = {
'kadpageurl': '', // Custom page url
Expand Down Expand Up @@ -560,8 +560,8 @@ function _createBannerRequest(bid) {

export function checkVideoPlacement(videoData, adUnitCode) {
// Check for video.placement property. If property is missing display log message.
if (FEATURES.VIDEO && !deepAccess(videoData, 'placement')) {
logWarn(MSG_VIDEO_PLACEMENT_MISSING + ' for ' + adUnitCode);
if (FEATURES.VIDEO && !deepAccess(videoData, 'plcmt')) {
logWarn(MSG_VIDEO_PLCMT_MISSING + ' for ' + adUnitCode);
};
}

Expand Down
239 changes: 239 additions & 0 deletions modules/qtBidAdapter.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,239 @@
import { logMessage, logError, deepAccess } from '../src/utils.js';
import { convertOrtbRequestToProprietaryNative } from '../src/native.js';
import { registerBidder } from '../src/adapters/bidderFactory.js';
import { BANNER, NATIVE, VIDEO } from '../src/mediaTypes.js';
import { config } from '../src/config.js';

const BIDDER_CODE = 'qt';
const AD_URL = 'https://endpoint1.qt.io/pbjs';
const SYNC_URL = 'https://cs.qt.io';

function isBidResponseValid(bid) {
if (!bid.requestId || !bid.cpm || !bid.creativeId || !bid.ttl || !bid.currency) {
return false;
}

switch (bid.mediaType) {
case BANNER:
return Boolean(bid.width && bid.height && bid.ad);
case VIDEO:
return Boolean(bid.vastUrl || bid.vastXml);
case NATIVE:
return Boolean(bid.native && bid.native.impressionTrackers && bid.native.impressionTrackers.length);
default:
return false;
}
}

function getPlacementReqData(bid) {
const { params, bidId, mediaTypes, transactionId, userIdAsEids } = bid;
const schain = bid.schain || {};
const { placementId, endpointId } = params;
const bidfloor = getBidFloor(bid);

const placement = {
bidId,
schain,
bidfloor
};

if (placementId) {
placement.placementId = placementId;
placement.type = 'publisher';
} else if (endpointId) {
placement.endpointId = endpointId;
placement.type = 'network';
}

if (mediaTypes && mediaTypes[BANNER]) {
placement.adFormat = BANNER;
placement.sizes = mediaTypes[BANNER].sizes;
} else if (mediaTypes && mediaTypes[VIDEO]) {
placement.adFormat = VIDEO;
placement.playerSize = mediaTypes[VIDEO].playerSize;
placement.minduration = mediaTypes[VIDEO].minduration;
placement.maxduration = mediaTypes[VIDEO].maxduration;
placement.mimes = mediaTypes[VIDEO].mimes;
placement.protocols = mediaTypes[VIDEO].protocols;
placement.startdelay = mediaTypes[VIDEO].startdelay;
placement.plcmt = mediaTypes[VIDEO].plcmt;
placement.skip = mediaTypes[VIDEO].skip;
placement.skipafter = mediaTypes[VIDEO].skipafter;
placement.minbitrate = mediaTypes[VIDEO].minbitrate;
placement.maxbitrate = mediaTypes[VIDEO].maxbitrate;
placement.delivery = mediaTypes[VIDEO].delivery;
placement.playbackmethod = mediaTypes[VIDEO].playbackmethod;
placement.api = mediaTypes[VIDEO].api;
placement.linearity = mediaTypes[VIDEO].linearity;
} else if (mediaTypes && mediaTypes[NATIVE]) {
placement.native = mediaTypes[NATIVE];
placement.adFormat = NATIVE;
}

if (transactionId) {
placement.ext = placement.ext || {};
placement.ext.tid = transactionId;
}

if (userIdAsEids && userIdAsEids.length) {
placement.eids = userIdAsEids;
}

return placement;
}

function getBidFloor(bid) {
try {
const bidFloor = bid.getFloor({
currency: 'USD',
mediaType: '*',
size: '*',
});
return bidFloor.floor;
} catch (err) {
logError(err);
return 0;
}
}

export const spec = {
code: BIDDER_CODE,
supportedMediaTypes: [BANNER, VIDEO, NATIVE],

isBidRequestValid: (bid = {}) => {
const { params, bidId, mediaTypes } = bid;
let valid = Boolean(bidId && params && (params.placementId || params.endpointId));

if (mediaTypes && mediaTypes[BANNER]) {
valid = valid && Boolean(mediaTypes[BANNER] && mediaTypes[BANNER].sizes);
} else if (mediaTypes && mediaTypes[VIDEO]) {
valid = valid && Boolean(mediaTypes[VIDEO] && mediaTypes[VIDEO].playerSize);
} else if (mediaTypes && mediaTypes[NATIVE]) {
valid = valid && Boolean(mediaTypes[NATIVE]);
} else {
valid = false;
}
return valid;
},

buildRequests: (validBidRequests = [], bidderRequest = {}) => {
// convert Native ORTB definition to old-style prebid native definition
validBidRequests = convertOrtbRequestToProprietaryNative(validBidRequests);

let deviceWidth = 0;
let deviceHeight = 0;

let winLocation;
try {
const winTop = window.top;
deviceWidth = winTop.screen.width;
deviceHeight = winTop.screen.height;
winLocation = winTop.location;
} catch (e) {
logMessage(e);
winLocation = window.location;
}

const refferUrl = bidderRequest.refererInfo && bidderRequest.refererInfo.page;
let refferLocation;
try {
refferLocation = refferUrl && new URL(refferUrl);
} catch (e) {
logMessage(e);
}

let location = refferLocation || winLocation;
const language = (navigator && navigator.language) ? navigator.language.split('-')[0] : '';
const host = location.host;
const page = location.pathname;
const secure = location.protocol === 'https:' ? 1 : 0;
const placements = [];
const request = {
deviceWidth,
deviceHeight,
language,
secure,
host,
page,
placements,
coppa: deepAccess(bidderRequest, 'ortb2.regs.coppa') ? 1 : 0,
tmax: bidderRequest.timeout
};

if (bidderRequest.uspConsent) {
request.ccpa = bidderRequest.uspConsent;
}

if (bidderRequest.gdprConsent) {
request.gdpr = {
consentString: bidderRequest.gdprConsent.consentString
};
}

if (bidderRequest.gppConsent) {
request.gpp = bidderRequest.gppConsent.gppString;
request.gpp_sid = bidderRequest.gppConsent.applicableSections;
} else if (bidderRequest.ortb2?.regs?.gpp) {
request.gpp = bidderRequest.ortb2.regs.gpp;
request.gpp_sid = bidderRequest.ortb2.regs.gpp_sid;
}

const len = validBidRequests.length;
for (let i = 0; i < len; i++) {
const bid = validBidRequests[i];
placements.push(getPlacementReqData(bid));
}

return {
method: 'POST',
url: AD_URL,
data: request
};
},

interpretResponse: (serverResponse) => {
let response = [];
for (let i = 0; i < serverResponse.body.length; i++) {
let resItem = serverResponse.body[i];
if (isBidResponseValid(resItem)) {
const advertiserDomains = resItem.adomain && resItem.adomain.length ? resItem.adomain : [];
resItem.meta = { ...resItem.meta, advertiserDomains };

response.push(resItem);
}
}
return response;
},

getUserSyncs: (syncOptions, serverResponses, gdprConsent, uspConsent, gppConsent) => {
let syncType = syncOptions.iframeEnabled ? 'iframe' : 'image';
let syncUrl = SYNC_URL + `/${syncType}?pbjs=1`;

if (gdprConsent && gdprConsent.consentString) {
if (typeof gdprConsent.gdprApplies === 'boolean') {
syncUrl += `&gdpr=${Number(gdprConsent.gdprApplies)}&gdpr_consent=${gdprConsent.consentString}`;
} else {
syncUrl += `&gdpr=0&gdpr_consent=${gdprConsent.consentString}`;
}
}

if (uspConsent && uspConsent.consentString) {
syncUrl += `&ccpa_consent=${uspConsent.consentString}`;
}

if (gppConsent?.gppString && gppConsent?.applicableSections?.length) {
syncUrl += '&gpp=' + gppConsent.gppString;
syncUrl += '&gpp_sid=' + gppConsent.applicableSections.join(',');
}

const coppa = config.getConfig('coppa') ? 1 : 0;
syncUrl += `&coppa=${coppa}`;

return [{
type: syncType,
url: syncUrl
}];
}
};

registerBidder(spec);
Loading

0 comments on commit db1a750

Please sign in to comment.