Skip to content

Commit

Permalink
Merge pull request #23 from jwplayer/feat/AD-1556-legacy
Browse files Browse the repository at this point in the history
[AD-1556] Bid Impression Verification
  • Loading branch information
karimMourra authored Mar 9, 2022
2 parents ff9e71a + dab8186 commit c1249ec
Show file tree
Hide file tree
Showing 10 changed files with 515 additions and 156 deletions.
15 changes: 14 additions & 1 deletion modules/jwplayerVideoProvider.js
Original file line number Diff line number Diff line change
Expand Up @@ -72,7 +72,7 @@ export function JWPlayerProvider(config, jwplayer_, adState_, timeState_, callba
if (!player) {
return;
}
const config = player.getConfig();
const config = player.getConfig() || {};
const adConfig = config.advertising || {};
supportedMediaTypes = supportedMediaTypes || utils.getSupportedMediaTypes(MEDIA_TYPES);

Expand Down Expand Up @@ -923,7 +923,13 @@ export function adStateFactory() {
waterfallCount: event.wcount,
adPodCount: event.podcount,
adPodIndex: event.sequence,
wrapperAdIds: event.wrapperAdIds
};

if (event.client === 'googima' && !updates.wrapperAdIds) {
updates.wrapperAdIds = parseImaAdWrapperIds(event);
}

this.updateState(updates);
}

Expand All @@ -950,6 +956,13 @@ export function adStateFactory() {
}
}

function parseImaAdWrapperIds(adEvent) {
const ima = adEvent.ima;
const ad = ima && ima.ad;
const h = ad && ad.h;
return h && h.adWrapperIds;
}

return adState;
}

Expand Down
2 changes: 1 addition & 1 deletion modules/videoModule/adServer.js
Original file line number Diff line number Diff line change
Expand Up @@ -45,7 +45,7 @@ export function AdServerCore(parentModule_) {
const vendorCode = config.vendorCode;
try {
parentModule.registerSubmodule(vendorCode, vendorCode, config);
} catch(e) {}
} catch (e) {}
}

/**
Expand Down
6 changes: 6 additions & 0 deletions modules/videoModule/constants/events.js
Original file line number Diff line number Diff line change
Expand Up @@ -52,6 +52,12 @@ export const allVideoEvents = [
];

export const AUCTION_AD_LOAD_ATTEMPT = 'auctionAdLoadAttempt';
export const BID_VIDEO_IMPRESSION = 'bidVideoImpression';
export const BID_VIDEO_ERROR = 'bidVideoError';

export const allVideoAuctionEvents = [
AUCTION_AD_LOAD_ATTEMPT
];

// Param options
export const PLAYBACK_MODE = {
Expand Down
80 changes: 33 additions & 47 deletions modules/videoModule/index.js
Original file line number Diff line number Diff line change
@@ -1,30 +1,34 @@
import { config } from '../../src/config.js';
import events from '../../src/events.js';
import { allVideoEvents, AUCTION_AD_LOAD_ATTEMPT } from './constants/events.js';
import { allVideoEvents, AUCTION_AD_LOAD_ATTEMPT, allVideoAuctionEvents,
AD_IMPRESSION, AD_ERROR, BID_VIDEO_IMPRESSION, BID_VIDEO_ERROR } from './constants/events.js';
import CONSTANTS from '../../src/constants.json';
import { videoCoreFactory } from './coreVideo.js';
import { coreAdServerFactory } from './adServer.js';
import find from 'prebidjs-polyfill/find.js';
import { vastXmlEditorFactory } from './shared/vastXmlEditor.js';
import { videoImpressionVerifierFactory } from './videoImpressionVerifier.js';

/**
* This module adds User Video support to prebid.js
* @module modules/videoModule
*/

events.addEvents(allVideoEvents);
events.addEvents(allVideoAuctionEvents);

export function PbVideo(videoCore_, getConfig_, pbGlobal_, pbEvents_, videoEvents_, adServerCore_, vastXmlEditor_) {
export function PbVideo(videoCore_, getConfig_, pbGlobal_, pbEvents_, videoEvents_, adServerCore_, videoImpressionVerifierFactory_) {
const videoCore = videoCore_;
const getConfig = getConfig_;
const pbGlobal = pbGlobal_;
const requestBids = pbGlobal.requestBids;
const pbEvents = pbEvents_;
const videoEvents = videoEvents_;
const adServerCore = adServerCore_;
const vastXmlEditor = vastXmlEditor_;
const videoImpressionVerifierFactory = videoImpressionVerifierFactory_;
let videoImpressionVerifier;

function init() {
const cache = getConfig('cache');
videoImpressionVerifier = videoImpressionVerifierFactory(!!cache);
getConfig('video', ({ video }) => {
video.providers.forEach(provider => {
videoCore.registerProvider(provider);
Expand All @@ -49,18 +53,16 @@ export function PbVideo(videoCore_, getConfig_, pbGlobal_, pbEvents_, videoEvent
});
});

const cache = getConfig('cache');
if (!cache) {
return;
}

pbEvents.on(CONSTANTS.EVENTS.BID_ADJUSTMENT, function (bid) {
const adUnitCode = bid.adUnitCode;
const adUnit = find(pbGlobal.adUnits, adUnit => adUnitCode === adUnit.code);
const videoConfig = adUnit && adUnit.video;
const adServerConfig = videoConfig && videoConfig.adServer;
const trackingConfig = adServerConfig && adServerConfig.tracking;
addTrackingNodesToVastXml(bid, trackingConfig);
videoImpressionVerifier.trackBid(bid);
});

pbEvents.on(AD_IMPRESSION, function (payload) {
triggerVideoBidEvent(BID_VIDEO_IMPRESSION, payload);
});

pbEvents.on(AD_ERROR, function (payload) {
triggerVideoBidEvent(BID_VIDEO_ERROR, payload);
});
}

Expand All @@ -85,8 +87,11 @@ export function PbVideo(videoCore_, getConfig_, pbGlobal_, pbEvents_, videoEvent
}

function renderWinningBid(adUnit) {
const highestCpmBids = pbGlobal.getHighestCpmBids(adUnit.code);
const adUnitCode = adUnit.code;
const options = { adUnitCode };
const highestCpmBids = pbGlobal.getHighestCpmBids(adUnitCode);
if (!highestCpmBids.length) {
pbEvents.emit(AUCTION_AD_LOAD_ATTEMPT, options);
return;
}

Expand All @@ -98,8 +103,6 @@ export function PbVideo(videoCore_, getConfig_, pbGlobal_, pbEvents_, videoEvent
adUrl = adServerCore.getAdTagUrl(adServerConfig.vendorCode, adUnit, adServerConfig.baseAdTagUrl);
}

const adUnitCode = adUnit.code;
const options = { adUnitCode };
if (adUrl) {
loadAdTag(adUrl, divId, options);
return;
Expand All @@ -123,43 +126,26 @@ export function PbVideo(videoCore_, getConfig_, pbGlobal_, pbEvents_, videoEvent
videoCore.setAdTagUrl(adUrl, divId, options);
}

function addTrackingNodesToVastXml(bid, trackingConfig) {
if (!trackingConfig) {
function triggerVideoBidEvent(eventName, adEventPayload) {
const bid = getBid(adEventPayload);
if (!bid) {
return;
}
pbEvents.emit(eventName, { bid, adEvent: adEventPayload });
}

let { vastXml, vastUrl, adId } = bid;
let impressionUrl;
let impressionId;
let errorUrl;

const impressionTracking = trackingConfig.impression;
const errorTracking = trackingConfig.error;

if (impressionTracking) {
impressionUrl = impressionTracking.url;
impressionId = impressionTracking.id || adId + '-impression';
}

if (errorTracking) {
errorUrl = errorTracking.url;
}

if (vastXml) {
vastXml = vastXmlEditor.getVastXmlWithTrackingNodes(vastXml, impressionUrl, impressionId, errorUrl);
} else if (vastUrl) {
vastXml = vastXmlEditor.buildVastWrapper(adId, vastUrl, impressionUrl, impressionId, errorUrl);
}

bid.vastXml = vastXml;
function getBid(adPayload) {
const { adId, adTagUrl, wrapperAdIds } = adPayload;
const { bidAdId = adId, adUnitCode, requestId, auctionId } = videoImpressionVerifier.getBidIdentifiers(adId, adTagUrl, wrapperAdIds);
const { bids } = pbGlobal.getBidResponsesForAdUnitCode(adUnitCode);
return bids.find(bid => bid.adId === bidAdId && bid.requestId === requestId && bid.auctionId === auctionId);
}
}

export function pbVideoFactory() {
const videoCore = videoCoreFactory();
const adServerCore = coreAdServerFactory();
const vastXmlEditor = vastXmlEditorFactory();
const pbVideo = PbVideo(videoCore, config.getConfig, $$PREBID_GLOBAL$$, events, allVideoEvents, adServerCore, vastXmlEditor);
const pbVideo = PbVideo(videoCore, config.getConfig, $$PREBID_GLOBAL$$, events, allVideoEvents, adServerCore, videoImpressionVerifierFactory);
pbVideo.init();
return pbVideo;
}
Expand Down
25 changes: 21 additions & 4 deletions modules/videoModule/shared/vastXmlEditor.js
Original file line number Diff line number Diff line change
Expand Up @@ -5,14 +5,20 @@ export const XML_MIME_TYPE = 'application/xml';
export function VastXmlEditor(xmlUtil_) {
const xmlUtil = xmlUtil_;

function getVastXmlWithTrackingNodes(vastXml, impressionUrl, impressionId, errorUrl) {
function getVastXmlWithTracking(vastXml, adId, impressionUrl, impressionId, errorUrl) {
const impressionDoc = getImpressionDoc(impressionUrl, impressionId);
const errorDoc = getErrorDoc(errorUrl);
if (!impressionDoc && !errorDoc) {
if (!adId && !impressionDoc && !errorDoc) {
return vastXml;
}

const vastXmlDoc = xmlUtil.parse(vastXml);
appendTrackingNodes(vastXmlDoc, impressionDoc, errorDoc);
replaceAdId(vastXmlDoc, adId);
return xmlUtil.serialize(vastXmlDoc);
}

function appendTrackingNodes(vastXmlDoc, impressionDoc, errorDoc) {
const nodes = vastXmlDoc.querySelectorAll('InLine,Wrapper');
const nodeCount = nodes.length;
for (let i = 0; i < nodeCount; i++) {
Expand All @@ -22,12 +28,23 @@ export function VastXmlEditor(xmlUtil_) {
appendChild(node, impressionDoc, requiresCopy);
appendChild(node, errorDoc, requiresCopy);
}
}

return xmlUtil.serialize(vastXmlDoc);
function replaceAdId(vastXmlDoc, adId) {
if (!adId) {
return;
}

const adNode = vastXmlDoc.querySelector('Ad');
if (!adNode) {
return;
}

adNode.id = adId;
}

return {
getVastXmlWithTrackingNodes,
getVastXmlWithTracking,
buildVastWrapper
}

Expand Down
Loading

0 comments on commit c1249ec

Please sign in to comment.