-
Notifications
You must be signed in to change notification settings - Fork 2.1k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
PBjs Core : add ability to inject tracking in video #10191
Changes from 18 commits
e407ca2
14d1d3b
643c74a
e70f141
2019c74
53f94b3
e182c18
2587ba6
4f8086f
94bbe1f
1934a1b
4a1eeaf
1138443
a7d72f5
2c18305
ecd61fe
641c597
cb593d5
b74c5c6
8083d25
98f5d80
84d039c
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -4,6 +4,9 @@ import { config } from '../src/config.js'; | |
import {includes} from './polyfill.js'; | ||
import { hook } from './hook.js'; | ||
import {auctionManager} from './auctionManager.js'; | ||
import {isActivityAllowed} from './activities/rules.js'; | ||
import {activityParams} from './activities/activityParams.js'; | ||
import {ACTIVITY_REPORT_ANALYTICS} from './activities/activities.js'; | ||
|
||
const VIDEO_MEDIA_TYPE = 'video'; | ||
export const OUTSTREAM = 'outstream'; | ||
|
@@ -21,6 +24,8 @@ export const videoBidder = bid => includes(adapterManager.videoAdapters, bid.bid | |
export const hasNonVideoBidder = adUnit => | ||
adUnit.bids.filter(bid => !videoBidder(bid)).length; | ||
|
||
let vastTrackers = []; | ||
|
||
/** | ||
* @typedef {object} VideoBid | ||
* @property {string} adId id of the bid | ||
|
@@ -64,3 +69,66 @@ export const checkVideoBidSetup = hook('sync', function(bid, adUnit, videoMediaT | |
|
||
return true; | ||
}, 'checkVideoBidSetup'); | ||
|
||
export function registerVastTrackers(moduleType, moduleName, trackerFn) { | ||
if (typeof trackerFn === 'function') { | ||
vastTrackers.push({'moduleType': moduleType, 'moduleName': moduleName, 'trackerFn': trackerFn}); | ||
} | ||
} | ||
|
||
export function insertVastTrackers(trackers, vastXml) { | ||
const doc = new DOMParser().parseFromString(vastXml, 'text/xml'); | ||
karimMourra marked this conversation as resolved.
Show resolved
Hide resolved
|
||
const wrappers = doc.querySelectorAll('VAST Ad Wrapper, VAST Ad InLine'); | ||
try { | ||
if (wrappers.length) { | ||
wrappers.forEach(wrapper => { | ||
if (trackers.get('impressions')) { | ||
trackers.get('impressions').forEach(trackingUrl => { | ||
const impression = doc.createElement('Impression'); | ||
impression.appendChild(doc.createCDATASection(trackingUrl)); | ||
wrapper.appendChild(impression) | ||
}); | ||
} | ||
}); | ||
vastXml = new XMLSerializer().serializeToString(doc); | ||
karimMourra marked this conversation as resolved.
Show resolved
Hide resolved
|
||
} | ||
} catch (error) { | ||
logError('an error happened trying to insert trackers in vastXml'); | ||
} | ||
return vastXml; | ||
} | ||
|
||
export function getVastTrackers(bid) { | ||
let trackers = []; | ||
vastTrackers.filter( | ||
({moduleType, moduleName, trackerFn}) => isActivityAllowed(ACTIVITY_REPORT_ANALYTICS, activityParams(moduleType, moduleName)) | ||
).forEach(({trackerFn}) => { | ||
let trackersToAdd = trackerFn(bid); | ||
trackersToAdd.forEach(trackerToAdd => { | ||
if (isValidVastTracker(trackers, trackerToAdd)) { trackers.push(trackerToAdd); } | ||
}); | ||
}); | ||
const trackersMap = trackersToMap(trackers); | ||
return (trackersMap.size ? trackersMap : null); | ||
}; | ||
|
||
function isValidVastTracker(trackers, trackerToAdd) { | ||
return trackerToAdd.hasOwnProperty('event') && trackerToAdd.hasOwnProperty('url'); | ||
} | ||
|
||
function trackersToMap(trackers) { | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. this could be simplified as something like function trackersToMap(trackers) {
return trackers.reduce((map, {url, event}) => {
!map.has(event) && map.set(event, new Set())
map.get(event).add(url);
return map;
}, new Map())
} which would also get rid of There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Done |
||
return trackers.reduce((map, {url, event}) => { | ||
!map.has(event) && map.set(event, new Set()) | ||
map.get(event).add(url); | ||
return map; | ||
}, new Map()) | ||
} | ||
|
||
export function addImpUrlToTrackers(bid, trackersMap) { | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. this could be replaced by a single line in // ... just before calling trackersToMap
bid.vastImpUrl && trackers.push({event: 'impression', url: bid.vastImpUrl});
const trackersMap = trackersToMap(trackers);
// ... There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Adding |
||
if (bid.vastImpUrl) { | ||
if (!trackersMap) { trackersMap = new Map(); } | ||
if (!trackersMap.get('impressions')) { trackersMap.set('impressions', new Set()); } | ||
trackersMap.get('impressions').add(bid.vastImpUrl); | ||
} | ||
return trackersMap; | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
this logic already exists in the Video Module Library. Why not reuse existing code ?
See
getVastXmlWithTracking
https://github.com/prebid/Prebid.js/blob/master/libraries/video/shared/vastXmlEditor.js#L8There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I wasn't aware of this library. I would say not reuse this existing code avoids to run
querySelectorAll
and loop on it for each tracker to insert.