Skip to content

Commit

Permalink
add support instream video ads for medianetAnalyticsAdapter
Browse files Browse the repository at this point in the history
  • Loading branch information
monisq committed Jul 13, 2020
1 parent 656b352 commit 3fb7ffb
Show file tree
Hide file tree
Showing 2 changed files with 69 additions and 3 deletions.
6 changes: 5 additions & 1 deletion modules/dfpAdServerVideo.js
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,8 @@ import { deepAccess, isEmpty, logError, parseSizesInput, formatQS, parseUrl, bui
import { config } from '../src/config.js';
import { getHook, submodule } from '../src/hook.js';
import { auctionManager } from '../src/auctionManager.js';
import events from '../src/events.js';
import CONSTANTS from '../src/constants.json';

/**
* @typedef {Object} DfpVideoParams
Expand Down Expand Up @@ -253,8 +255,10 @@ function getCustParams(bid, options) {
{ hb_cache_id: bid && bid.videoCacheKey },
allTargetingData,
adserverTargeting,
optCustParams,
);

events.emit(CONSTANTS.EVENTS.SET_TARGETING, {[adUnit.code]: customParams});
customParams = Object.assign(customParams, optCustParams)
return encodeURIComponent(formatQS(customParams));
}

Expand Down
66 changes: 64 additions & 2 deletions modules/medianetAnalyticsAdapter.js
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,8 @@ import adapter from '../src/AnalyticsAdapter.js';
import adapterManager from '../src/adapterManager.js';
import CONSTANTS from '../src/constants.json';
import * as utils from '../src/utils.js';
import { OUTSTREAM } from '../src/video.js';
import { VIDEO } from '../src/mediaTypes.js';
import { ajax } from '../src/ajax.js';
import { getRefererInfo } from '../src/refererDetection.js';
import { getPriceGranularity, AUCTION_IN_PROGRESS, AUCTION_COMPLETED } from '../src/auction.js'
Expand Down Expand Up @@ -353,6 +355,64 @@ class Auction {
}
}

/**
* Here the idea is
* find all network entries via performance.getEntriesByType()
* filter it by video cache key in the url
* and exclude the ad server urls so that we dont match twice
* eg:
* dfp ads call: https://securepubads.g.doubleclick.net/gampad/ads?...hb_cache_id%3D55e85cd3-6ea4-4469-b890-84241816b131%26...
* prebid cache url: https://prebid.adnxs.com/pbc/v1/cache?uuid=55e85cd3-6ea4-4469-b890-84241816b131
*
* if the entry exists, emit the BID_WON
*/
function findRenderedVideoImpressions(auction) {
// filter for video bids
const videoBids = auction.bids.filter(bid => bid.mediaType === VIDEO && bid.context !== OUTSTREAM && bid.videoCacheKey)
// check if performance api is available
if (!videoBids.length || !window.performance || !window.performance.getEntriesByType) {
return;
}
const timeLimit = 15 * 1000 * 60;
const start = Date.now();
const bidWonMap = {};

let lastRead = 0;

function poll() {
// get network entries using the last read offset
const entries = window.performance.getEntriesByType('resource').splice(lastRead);
for (const res of entries) {
const url = res.name;
videoBids.forEach((bid) => {
// match the video cache key excluding ad server call
const matches = !url.includes(CONSTANTS.TARGETING_KEYS.CACHE_ID) && url.includes(bid.videoCacheKey);
if (matches && !bidWonMap[bid.bidId]) {
// video found
bidWonMap[bid.bidId] = bid;
bid.requestId = bid.bidId;
bid.auctionId = auction.acid;
bid.adUnitCode = bid.supplyAdCode;
// log BID_WON
bidWonHandler(bid);
}
});
}
// update offset
lastRead += entries.length;

const lastCheckedDiff = Date.now() - start;
if (lastCheckedDiff < timeLimit && Object.keys(bidWonMap).length < auction.adSlots.length) {
setTimeout(poll, 2e3);
}
}

// start polling for network entries
setTimeout(poll, 2e3);
}

// --------------------- event handlers ---------------------

function auctionInitHandler({auctionId, timestamp}) {
if (auctionId && auctions[auctionId] === undefined) {
auctions[auctionId] = new Auction(auctionId);
Expand Down Expand Up @@ -386,6 +446,7 @@ function bidRequestedHandler({ auctionId, auctionStart, bids, start, timeout, us
);
}
let bidObj = new Bid(bidId, bidder, src, start, adUnitCode);
bidObj.context = utils.deepAccess(mediaTypes, `${VIDEO}.context`)
auctions[auctionId].addBid(bidObj);
if (bidder === MEDIANET_BIDDER_CODE) {
bidObj.crid = utils.deepAccess(bid, 'params.crid');
Expand All @@ -397,7 +458,7 @@ function bidRequestedHandler({ auctionId, auctionStart, bids, start, timeout, us

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

if (!(auctions[auctionId] instanceof Auction)) {
return;
Expand All @@ -409,7 +470,7 @@ function bidResponseHandler(bid) {
Object.assign(
bidObj,
{ cpm, width, height, mediaType, timeToRespond, dealId, creativeId },
{ adId, currency }
{ adId, currency, videoCacheKey }
);
bidObj.originalCpm = originalCpm || cpm;
let dfpbd = utils.deepAccess(bid, 'adserverTargeting.hb_pb');
Expand Down Expand Up @@ -464,6 +525,7 @@ function auctionEndHandler({ auctionId, auctionEnd }) {
}
auctions[auctionId].status = AUCTION_COMPLETED;
auctions[auctionId].auctionEndTime = auctionEnd;
findRenderedVideoImpressions(auctions[auctionId]);
}

function setTargetingHandler(params) {
Expand Down

0 comments on commit 3fb7ffb

Please sign in to comment.