Skip to content

Commit

Permalink
added fix and support for multibid module (#9602)
Browse files Browse the repository at this point in the history
Co-authored-by: adish <adish.r@media.net>
  • Loading branch information
adish1997 and adish-r authored Mar 27, 2023
1 parent 9045fa3 commit 0eb76d7
Show file tree
Hide file tree
Showing 2 changed files with 147 additions and 57 deletions.
176 changes: 120 additions & 56 deletions modules/medianetAnalyticsAdapter.js
Original file line number Diff line number Diff line change
Expand Up @@ -8,8 +8,7 @@ import {
logError,
logInfo,
triggerPixel,
uniques,
getHighestCpm
uniques
} from '../src/utils.js';
import adapter from '../libraries/analyticsAdapter/AnalyticsAdapter.js';
import adapterManager from '../src/adapterManager.js';
Expand Down Expand Up @@ -41,6 +40,7 @@ const PREBID_VERSION = $$PREBID_GLOBAL$$.version;
const ERROR_CONFIG_JSON_PARSE = 'analytics_config_parse_fail';
const ERROR_CONFIG_FETCH = 'analytics_config_ajax_fail';
const ERROR_WINNING_BID_ABSENT = 'winning_bid_absent';
const ERROR_WINNING_AUCTION_MISSING = 'winning_auction_missing';
const BID_SUCCESS = 1;
const BID_NOBID = 2;
const BID_TIMEOUT = 3;
Expand Down Expand Up @@ -72,7 +72,7 @@ class ErrorLogger {
this.evtid = 'projectevents';
this.project = 'prebidanalytics';
this.dn = pageDetails.domain || '';
this.requrl = pageDetails.requrl || '';
this.requrl = pageDetails.topmostLocation || '';
this.pbversion = PREBID_VERSION;
this.cid = config.cid || '';
this.rd = additionalData;
Expand Down Expand Up @@ -270,6 +270,52 @@ class AdSlot {
}
}

class BidWrapper {
constructor() {
this.bidReqs = [];
this.bidObjs = [];
}

findReqBid(bidId) {
return this.bidReqs.find(bid => {
return bid['bidId'] === bidId
});
}

findBidObj(key, value) {
return this.bidObjs.find(bid => {
return bid[key] === value
});
}

addBidReq(bidRequest) {
this.bidReqs.push(bidRequest)
}

addBidObj(bidObj) {
if (!(bidObj instanceof Bid)) {
bidObj = Bid.getInstance(bidObj);
}
const bidReq = this.findReqBid(bidObj.bidId);
if (bidReq instanceof Bid) {
bidReq.used = true;
}
this.bidObjs.push(bidObj);
}

getAdSlotBids(adSlot) {
const bidResponses = this.getAdSlotBidObjs(adSlot);
return bidResponses.map((bid) => bid.getLoggingData());
}

getAdSlotBidObjs(adSlot) {
const bidResponses = this.bidObjs
.filter((bid) => bid.adUnitCode === adSlot);
const remResponses = this.bidReqs.filter(bid => !bid.used && bid.adUnitCode === adSlot);
return [...bidResponses, ...remResponses];
}
}

class Bid {
constructor(bidId, bidder, src, start, adUnitCode, mediaType, allMediaTypeSizes) {
this.bidId = bidId;
Expand Down Expand Up @@ -299,6 +345,9 @@ class Bid {
this.floorPrice = undefined;
this.floorRule = undefined;
this.serverLatencyMillis = undefined;
this.used = false;
this.originalRequestId = bidId;
this.requestId = undefined;
}

get size() {
Expand All @@ -308,8 +357,15 @@ class Bid {
return this.width + 'x' + this.height;
}

static getInstance(bidProps) {
const bidObj = new Bid();
return bidProps && Object.assign(bidObj, bidProps);
}

getLoggingData() {
return {
reqId: this.requestId || this.bidId,
ogReqId: this.originalRequestId,
adid: this.adId,
pvnm: this.bidder,
src: this.src,
Expand Down Expand Up @@ -341,7 +397,7 @@ class Auction {
constructor(acid) {
this.acid = acid;
this.status = AUCTION_IN_PROGRESS;
this.bids = [];
this.bidWrapper = new BidWrapper();
this.adSlots = {};
this.auctionInitTime = undefined;
this.auctionStartTime = undefined;
Expand Down Expand Up @@ -378,24 +434,31 @@ class Auction {
addSlot({ adUnitCode, supplyAdCode, mediaTypes, allMediaTypeSizes, tmax, adext, context }) {
if (adUnitCode && this.adSlots[adUnitCode] === undefined) {
this.adSlots[adUnitCode] = new AdSlot(tmax, supplyAdCode, context, adext);
this.addBid(new Bid('-1', DUMMY_BIDDER, 'client', '-1', adUnitCode, mediaTypes, allMediaTypeSizes));
this.addBidObj(new Bid('-1', DUMMY_BIDDER, 'client', Date.now(), adUnitCode, mediaTypes, allMediaTypeSizes));
}
}

addBid(bid) {
this.bids.push(bid);
this.bidWrapper.addBidReq(bid);
}

findBid(key, value) {
return this.bids.filter(bid => {
return bid[key] === value
})[0];
addBidObj(bidObj) {
this.bidWrapper.addBidObj(bidObj)
}

getAdslotBids(adslot) {
return this.bids
.filter((bid) => bid.adUnitCode === adslot)
.map((bid) => bid.getLoggingData());
findReqBid(bidId) {
return this.bidWrapper.findReqBid(bidId)
}

findBidObj(key, value) {
return this.bidWrapper.findBidObj(key, value)
}

getAdSlotBids(adSlot) {
return this.bidWrapper.getAdSlotBids(adSlot);
}
getAdSlotBidObjs(adSlot) {
return this.bidWrapper.getAdSlotBidObjs(adSlot);
}

_mergeFieldsToLog(objParams) {
Expand Down Expand Up @@ -494,41 +557,26 @@ function _getSizes(mediaTypes, sizes) {
}
}

/*
- The code is used to determine if the current bid is higher than the previous bid.
- If it is, then the code will return true and if not, it will return false.
*/
function canSelectCurrentBid(previousBid, currentBid) {
if (!(previousBid instanceof Bid)) return false;

// For first bid response the previous bid will be containing bid request obj
// in which the cpm would be undefined so the current bid can directly be selected.
const isFirstBidResponse = previousBid.cpm === undefined && currentBid.cpm !== undefined;
if (isFirstBidResponse) return true;

// if there are 2 bids, get the highest bid
const selectedBid = getHighestCpm(previousBid, currentBid);

// Return true if selectedBid is currentBid,
// The timeToRespond field is used as an identifier for distinguishing
// between the current iterating bid and the previous bid.
return selectedBid.timeToRespond === currentBid.timeToRespond;
}

function bidResponseHandler(bid) {
const { width, height, mediaType, cpm, requestId, timeToRespond, auctionId, dealId } = bid;
const {originalCpm, bidderCode, creativeId, adId, currency} = bid;
const { width, height, mediaType, cpm, requestId, timeToRespond, auctionId, dealId, originalRequestId, bidder } = bid;
const {originalCpm, creativeId, adId, currency} = bid;

if (!(auctions[auctionId] instanceof Auction)) {
return;
}
let bidObj = auctions[auctionId].findBid('bidId', requestId);
if (!canSelectCurrentBid(bidObj, bid)) {
return;
const reqId = originalRequestId || requestId;
const bidReq = auctions[auctionId].findReqBid(reqId);

if (!(bidReq instanceof Bid)) return;

let bidObj = auctions[auctionId].findBidObj('bidId', requestId);
let isBidOverridden = true;
if (!bidObj || bidObj.status === BID_SUCCESS) {
bidObj = {};
isBidOverridden = false;
}
Object.assign(
bidObj,
{ cpm, width, height, mediaType, timeToRespond, dealId, creativeId },
Object.assign(bidObj, bidReq,
{ cpm, width, height, mediaType, timeToRespond, dealId, creativeId, originalRequestId, requestId },
{ adId, currency }
);
bidObj.floorPrice = deepAccess(bid, 'floorData.floorValue');
Expand All @@ -547,7 +595,7 @@ function bidResponseHandler(bid) {
bidObj.status = BID_SUCCESS;
}

if (bidderCode === MEDIANET_BIDDER_CODE && bid.ext instanceof Object) {
if (bidder === MEDIANET_BIDDER_CODE && bid.ext instanceof Object) {
Object.assign(
bidObj,
{ 'ext': bid.ext },
Expand All @@ -558,6 +606,7 @@ function bidResponseHandler(bid) {
if (typeof bid.serverResponseTimeMs !== 'undefined') {
bidObj.serverLatencyMillis = bid.serverResponseTimeMs;
}
!isBidOverridden && auctions[auctionId].addBidObj(bidObj);
}

function noBidResponseHandler({ auctionId, bidId }) {
Expand All @@ -567,23 +616,27 @@ function noBidResponseHandler({ auctionId, bidId }) {
if (auctions[auctionId].hasEnded()) {
return;
}
let bidObj = auctions[auctionId].findBid('bidId', bidId);
if (!(bidObj instanceof Bid)) {
const bidReq = auctions[auctionId].findReqBid(bidId);
if (!(bidReq instanceof Bid) || bidReq.used) {
return;
}
const bidObj = {...bidReq};
bidObj.status = BID_NOBID;
auctions[auctionId].addBidObj(bidObj);
}

function bidTimeoutHandler(timedOutBids) {
timedOutBids.map(({bidId, auctionId}) => {
if (!(auctions[auctionId] instanceof Auction)) {
return;
}
let bidObj = auctions[auctionId].findBid('bidId', bidId);
if (!(bidObj instanceof Bid)) {
const bidReq = auctions[auctionId].findReqBid('bidId', bidId);
if (!(bidReq instanceof Bid) || bidReq.used) {
return;
}
const bidObj = {...bidReq};
bidObj.status = BID_TIMEOUT;
auctions[auctionId].addBidObj(bidObj);
})
}

Expand Down Expand Up @@ -614,13 +667,13 @@ function setTargetingHandler(params) {
const winnerAdId = params[adunit][CONSTANTS.TARGETING_KEYS.AD_ID];
let winningBid;
let bidAdIds = Object.keys(targetingObj).map(k => targetingObj[k]);
auctionObj.bids.filter((bid) => bidAdIds.indexOf(bid.adId) !== -1).map(function(bid) {
auctionObj.bidWrapper.bidObjs.filter((bid) => bidAdIds.indexOf(bid.adId) !== -1).map(function(bid) {
bid.iwb = 1;
if (bid.adId === winnerAdId) {
winningBid = bid;
}
});
auctionObj.bids.forEach(bid => {
auctionObj.bidWrapper.bidObjs.forEach(bid => {
if (bid.bidder === DUMMY_BIDDER && bid.adUnitCode === adunit) {
bid.iwb = bidAdIds.length === 0 ? 0 : 1;
bid.width = deepAccess(winningBid, 'width');
Expand All @@ -633,16 +686,27 @@ function setTargetingHandler(params) {
}

function bidWonHandler(bid) {
const { auctionId, adUnitCode, adId } = bid;
const { auctionId, adUnitCode, adId, bidder, requestId, originalRequestId } = bid;
if (!(auctions[auctionId] instanceof Auction)) {
new ErrorLogger(ERROR_WINNING_AUCTION_MISSING, {
adId,
auctionId,
adUnitCode,
bidder,
requestId,
originalRequestId
}).send();
return;
}
let bidObj = auctions[auctionId].findBid('adId', adId);
let bidObj = auctions[auctionId].findBidObj('adId', adId);
if (!(bidObj instanceof Bid)) {
new ErrorLogger(ERROR_WINNING_BID_ABSENT, {
adId: adId,
acid: auctionId,
adId,
auctionId,
adUnitCode,
bidder,
requestId,
originalRequestId
}).send();
return;
}
Expand Down Expand Up @@ -696,13 +760,13 @@ function fireAuctionLog(acid, adtag, logType, adId) {
let bidParams;

if (logType === LOG_TYPE.RA) {
const winningBidObj = auctions[acid].findBid('adId', adId);
const winningBidObj = auctions[acid].findBidObj('adId', adId);
if (!winningBidObj) return;
const winLogData = winningBidObj.getLoggingData();
bidParams = [winLogData];
commonParams.lper = 1;
} else {
bidParams = auctions[acid].getAdslotBids(adtag).map(({winner, ...restParams}) => restParams);
bidParams = auctions[acid].getAdSlotBids(adtag).map(({winner, ...restParams}) => restParams);
delete commonParams.wts;
}
let mnetPresent = bidParams.filter(b => b.pvnm === MEDIANET_BIDDER_CODE).length > 0;
Expand Down
Loading

0 comments on commit 0eb76d7

Please sign in to comment.