Skip to content

Commit

Permalink
Merge pull request #977 from PubMatic-OpenWrap/test_br_b2_20241203141724
Browse files Browse the repository at this point in the history
Prebid upgarde automate- test pull request created through git api please ignore it
  • Loading branch information
pm-nitin-shirsat authored Dec 5, 2024
2 parents 87a400f + 681a02f commit 2919423
Show file tree
Hide file tree
Showing 106 changed files with 12,370 additions and 2,637 deletions.
1 change: 1 addition & 0 deletions .github/CODEOWNERS
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
@azhar.mulla
4 changes: 4 additions & 0 deletions gulpHelpers.js
Original file line number Diff line number Diff line change
Expand Up @@ -121,6 +121,10 @@ module.exports = {
return this.getBuiltPath(dev, 'prebid-core.js')
},

getBuiltPrebidIHCoreFile: function(dev) {
return path.join(__dirname, dev ? DEV_PATH : BUILD_PATH, 'prebid-core-idhub' + '.js');
},

getModulePaths: function(externalModules) {
var modules = this.getModules(externalModules);
return Object.keys(modules);
Expand Down
5 changes: 4 additions & 1 deletion gulpfile.js
Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@
/* eslint-disable no-console */
'use strict';

console.time('Loading Plugins in Prebid');

var _ = require('lodash');
var argv = require('yargs').argv;
var gulp = require('gulp');
Expand Down Expand Up @@ -35,6 +37,7 @@ const INTEG_SERVER_HOST = argv.host ? argv.host : 'localhost';
const INTEG_SERVER_PORT = 4444;
const { spawn, fork } = require('child_process');
const TerserPlugin = require('terser-webpack-plugin');
console.timeEnd('Loading Plugins in Prebid');

// these modules must be explicitly listed in --modules to be included in the build, won't be part of "all" modules
var explicitModules = [
Expand Down Expand Up @@ -563,4 +566,4 @@ gulp.task('bundle', gulpBundle.bind(null, false)); // used for just concatenatin
gulp.task(viewReview);
gulp.task('review-start', gulp.series(clean, lint, gulp.parallel('build-bundle-dev', watch, testCoverage), viewReview));

module.exports = nodeBundle;
module.exports = nodeBundle;
72 changes: 72 additions & 0 deletions libraries/detectBrowserUtils/detectBrowserUtils.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,72 @@
import { logError } from '../../src/utils.js';

/**
* Detects the browser using either userAgent or userAgentData
* @return {string} The name of the detected browser or 'unknown' if unable to detect
*/
export function detectBrowser() {
try {
if (navigator.userAgent) {
return detectBrowserFromUserAgent(navigator.userAgent);
} else if (navigator.userAgentData) {
return detectBrowserFromUserAgentData(navigator.userAgentData);
}
} catch (error) {
logError('Error detecting browser:', error);
}
return 'unknown';
}

/**
* Detects the browser from the user agent string
* @param {string} userAgent - The user agent string from the browser
* @return {string} The name of the detected browser or 'unknown' if unable to detect
*/
export function detectBrowserFromUserAgent(userAgent) {
const browserRegexPatterns = {
opera: /Opera|OPR/,
edge: /Edg/,
chrome: /Chrome|CriOS/,
safari: /Safari/,
firefox: /Firefox/,
ie: /MSIE|Trident/,
};

// Check for Chrome first to avoid confusion with Safari
if (browserRegexPatterns.chrome.test(userAgent)) {
return 'chrome';
}

// Now we can safely check for Safari
if (browserRegexPatterns.safari.test(userAgent) && !browserRegexPatterns.chrome.test(userAgent)) {
return 'safari';
}

// Check other browsers
for (const browser in browserRegexPatterns) {
if (browserRegexPatterns[browser].test(userAgent)) {
return browser;
}
}

return 'unknown';
}

/**
* Detects the browser from the NavigatorUAData object
* @param {NavigatorUAData} userAgentData - The user agent data object from the browser
* @return {string} The name of the detected browser or 'unknown' if unable to detect
*/
export function detectBrowserFromUserAgentData(userAgentData) {
const brandNames = userAgentData.brands.map(brand => brand.brand);

if (brandNames.includes('Microsoft Edge')) {
return 'edge';
} else if (brandNames.includes('Opera')) {
return 'opera';
} else if (brandNames.some(brand => brand === 'Chromium' || brand === 'Google Chrome')) {
return 'chrome';
}

return 'unknown';
}
92 changes: 88 additions & 4 deletions libraries/ortbConverter/converter.js
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import {compose} from './lib/composer.js';
import {logError, memoize} from '../../src/utils.js';
import {deepClone, logError, memoize, timestamp} from '../../src/utils.js';
import {DEFAULT_PROCESSORS} from './processors/default.js';
import {BID_RESPONSE, DEFAULT, getProcessors, IMP, REQUEST, RESPONSE} from '../../src/pbjsORTB.js';
import {mergeProcessors} from './lib/mergeProcessors.js';
Expand All @@ -14,6 +14,10 @@ export function ortbConverter({
response,
} = {}) {
const REQ_CTX = new WeakMap();
let impressionReqIdMap = {};
let firstBidRequest;
window.partnersWithoutErrorAndBids = {};
window.matchedimpressions = {};

function builder(slot, wrapperFn, builderFn, errorHandler) {
let build;
Expand Down Expand Up @@ -52,6 +56,18 @@ export function ortbConverter({
function (process, imps, bidderRequest, context) {
const ortbRequest = {imp: imps};
process(ortbRequest, bidderRequest, context);

// PM: Stop overwriting page, domain and ref as mentioned in UOE-8675 for s2s partners
const page = bidderRequest?.refererInfo?.page || '';
const domain = bidderRequest?.refererInfo?.domain || '';
const ref = window?.document?.referrer;
if (bidderRequest?.src === 's2s' && ortbRequest.site) {
ortbRequest.site = Object.assign(ortbRequest.site, { page, domain });
if (ref.length) {
ortbRequest.site.ref = ref;
}
}

return ortbRequest;
},
function (error, imps, bidderRequest, context) {
Expand Down Expand Up @@ -83,6 +99,29 @@ export function ortbConverter({
}
);

function createLatencyMap(impressionID, id) {
impressionReqIdMap[id] = impressionID;
window.pbsLatency[impressionID] = {
'startTime': timestamp()
};
}

// Get list of all errored partners
function getErroredPartners(responseExt) {
if (responseExt && responseExt.errors) {
return Object.keys(responseExt.errors);
}
}

function findPartnersWithoutErrorsAndBids(erroredPartners, listofPartnersWithmi, responseExt, impValue) {
window.partnersWithoutErrorAndBids[impValue] = listofPartnersWithmi.filter(partner => !erroredPartners.includes(partner));
erroredPartners.forEach(partner => {
if (responseExt.errors[partner] && responseExt.errors[partner][0].code == 1) {
window.partnersWithoutErrorAndBids[impValue].push(partner);
}
})
}

return {
toORTB({bidderRequest, bidRequests, context = {}}) {
bidRequests = bidRequests || bidderRequest.bids;
Expand All @@ -94,13 +133,20 @@ export function ortbConverter({
const imps = bidRequests.map(bidRequest => {
const impContext = Object.assign({bidderRequest, reqContext: ctx.req}, defaultContext, context);
const result = buildImp(bidRequest, impContext);
let resultCopy = deepClone(result);
if (resultCopy?.ext?.prebid?.bidder) {
for (let bidderCode in resultCopy.ext.prebid.bidder) {
let bid = resultCopy.ext.prebid.bidder[bidderCode];
delete bid?.kgpv;
}
}
if (result != null) {
if (result.hasOwnProperty('id')) {
Object.assign(impContext, {bidRequest, imp: result});
ctx.imp[result.id] = impContext;
return result;
}
logError('Converted ORTB imp does not specify an id, ignoring bid request', bidRequest, result);
logError('Converted ORTB imp does not specify an id, ignoring bid request', bidRequest, resultCopy);
}
}).filter(Boolean);

Expand All @@ -109,9 +155,24 @@ export function ortbConverter({
if (request != null) {
REQ_CTX.set(request, ctx);
}

firstBidRequest = ctx.req?.actualBidderRequests?.[0];
// check if isPrebidPubMaticAnalyticsEnabled in s2sConfig and if it is then get auctionId from adUnit
const s2sConfig = ctx.req?.s2sBidRequest?.s2sConfig;
let isAnalyticsEnabled = s2sConfig?.extPrebid?.isPrebidPubMaticAnalyticsEnabled;
if (firstBidRequest) {
const iidValue = isAnalyticsEnabled ? firstBidRequest.auctionId : firstBidRequest?.bids[0]?.params?.wiid;
createLatencyMap(iidValue, firstBidRequest.auctionId);
}
return request;
},
fromORTB({request, response}) {
// Get impressionID from impressionReqIdMap to check response belongs to same request
let impValue = impressionReqIdMap[response.id];
if (impValue && window.pbsLatency[impValue]) {
window.pbsLatency[impValue]['endTime'] = timestamp();
}

const ctx = REQ_CTX.get(request);
if (ctx == null) {
throw new Error('ortbRequest passed to `fromORTB` must be the same object returned by `toORTB`')
Expand All @@ -120,13 +181,36 @@ export function ortbConverter({
return Object.assign(ctx, {ortbRequest: request}, extraParams);
}
const impsById = Object.fromEntries((request.imp || []).map(imp => [imp.id, imp]));
const bidResponses = (response.seatbid || []).flatMap(seatbid =>
(seatbid.bid || []).map((bid) => {
let impForSlots, partnerBidsForslots;
if (firstBidRequest && firstBidRequest.hasOwnProperty('adUnitsS2SCopy')) {
impForSlots = firstBidRequest.adUnitsS2SCopy.length;
}

let extObj = response.ext || {};
let miObj = extObj.matchedimpression || {};
window.matchedimpressions = {...window.matchedimpressions, ...miObj};

const listofPartnersWithmi = window.partnersWithoutErrorAndBids[impValue] = Object.keys(miObj);
const erroredPartners = getErroredPartners(extObj);
if (erroredPartners) {
findPartnersWithoutErrorsAndBids(erroredPartners, listofPartnersWithmi, extObj, impValue);
}

const bidResponses = (response.seatbid || []).flatMap(seatbid => {
if (seatbid.hasOwnProperty('bid')) {
partnerBidsForslots = seatbid.bid.length;
}
window.partnersWithoutErrorAndBids[impValue] = window.partnersWithoutErrorAndBids[impValue].filter((partner) => {
return ((partner !== seatbid.seat) || (impForSlots !== partnerBidsForslots));
});

return (seatbid.bid || []).map((bid) => {
if (impsById.hasOwnProperty(bid.impid) && ctx.imp.hasOwnProperty(bid.impid)) {
return buildBidResponse(bid, augmentContext(ctx.imp[bid.impid], {imp: impsById[bid.impid], seatbid, ortbResponse: response}));
}
logError('ORTB response seatbid[].bid[].impid does not match any imp in request; ignoring bid', bid);
})
}
).filter(Boolean);
return buildResponse(bidResponses, response, augmentContext(ctx.req));
}
Expand Down
28 changes: 27 additions & 1 deletion libraries/ortbConverter/processors/default.js
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import {generateUUID, mergeDeep} from '../../../src/utils.js';
import {generateUUID, mergeDeep, logWarn} from '../../../src/utils.js';
import {bannerResponseProcessor, fillBannerImp} from './banner.js';
import {fillVideoImp, fillVideoResponse} from './video.js';
import {setResponseMediaType} from './mediaType.js';
Expand Down Expand Up @@ -139,3 +139,29 @@ if (FEATURES.VIDEO) {
fn: fillVideoResponse
}
}

export function onlyOneClientSection(ortbRequest, bidderRequest) {
['dooh', 'app', 'site'].reduce((found, section) => {
if (ortbRequest[section] != null && Object.keys(ortbRequest[section]).length > 0) {
if (found != null) {
logWarn(`ORTB request specifies both '${found}' and '${section}'; dropping the latter.`)
delete ortbRequest[section];
} else {
found = section;
}
}
return found;
}, null);

// PM: We will be overwriting page, domain and ref as mentioned in UOE-8675 for s2s partners
// const { page, domain } = bidderRequest.refererInfo;
const page = bidderRequest?.refererInfo?.page || '';
const domain = bidderRequest?.refererInfo?.domain || '';
const ref = window?.document?.referrer;
if (bidderRequest?.src === 's2s' && ortbRequest.site) {
ortbRequest.site = Object.assign(ortbRequest.site, { page, domain });
if (ref.length) {
ortbRequest.site.ref = ref;
}
}
}
Loading

0 comments on commit 2919423

Please sign in to comment.