Skip to content

Commit 58c49e5

Browse files
mbcrutejorgeluisrocha
authored andcommitted
Support VIDEO feature flag in AppNexus bid adapter (prebid#9653)
1 parent 5c561dc commit 58c49e5

File tree

4 files changed

+659
-617
lines changed

4 files changed

+659
-617
lines changed

modules/appnexusBidAdapter.js

Lines changed: 108 additions & 102 deletions
Original file line numberDiff line numberDiff line change
@@ -333,14 +333,16 @@ export const spec = {
333333
payload.referrer_detection = refererinfo;
334334
}
335335

336-
const hasAdPodBid = find(bidRequests, hasAdPod);
337-
if (hasAdPodBid) {
338-
bidRequests.filter(hasAdPod).forEach(adPodBid => {
339-
const adPodTags = createAdPodRequest(tags, adPodBid);
340-
// don't need the original adpod placement because it's in adPodTags
341-
const nonPodTags = payload.tags.filter(tag => tag.uuid !== adPodBid.bidId);
342-
payload.tags = [...nonPodTags, ...adPodTags];
343-
});
336+
if (FEATURES.VIDEO) {
337+
const hasAdPodBid = find(bidRequests, hasAdPod);
338+
if (hasAdPodBid) {
339+
bidRequests.filter(hasAdPod).forEach(adPodBid => {
340+
const adPodTags = createAdPodRequest(tags, adPodBid);
341+
// don't need the original adpod placement because it's in adPodTags
342+
const nonPodTags = payload.tags.filter(tag => tag.uuid !== adPodBid.bidId);
343+
payload.tags = [...nonPodTags, ...adPodTags];
344+
});
345+
}
344346
}
345347

346348
if (bidRequests[0].userId) {
@@ -653,7 +655,7 @@ function newBid(serverBid, rtbBid, bidderRequest) {
653655
bid.meta = Object.assign({}, bid.meta, { brandId: rtbBid.brand_id });
654656
}
655657

656-
if (rtbBid.rtb.video) {
658+
if (FEATURES.VIDEO && rtbBid.rtb.video) {
657659
// shared video properties used for all 3 contexts
658660
Object.assign(bid, {
659661
width: rtbBid.rtb.video.player_width,
@@ -865,107 +867,111 @@ function bidToTag(bid) {
865867
}
866868
}
867869

868-
const videoMediaType = deepAccess(bid, `mediaTypes.${VIDEO}`);
869-
const context = deepAccess(bid, 'mediaTypes.video.context');
870-
871-
if (videoMediaType && context === 'adpod') {
872-
tag.hb_source = 7;
873-
} else {
874-
tag.hb_source = 1;
875-
}
876-
if (bid.mediaType === VIDEO || videoMediaType) {
877-
tag.ad_types.push(VIDEO);
878-
}
879-
880-
// instream gets vastUrl, outstream gets vastXml
881-
if (bid.mediaType === VIDEO || (videoMediaType && context !== 'outstream')) {
882-
tag.require_asset_url = true;
883-
}
870+
if (FEATURES.VIDEO) {
871+
const videoMediaType = deepAccess(bid, `mediaTypes.${VIDEO}`);
872+
const context = deepAccess(bid, 'mediaTypes.video.context');
884873

885-
if (bid.params.video) {
886-
tag.video = {};
887-
// place any valid video params on the tag
888-
Object.keys(bid.params.video)
889-
.filter(param => includes(VIDEO_TARGETING, param))
890-
.forEach(param => {
891-
switch (param) {
892-
case 'context':
893-
case 'playback_method':
894-
let type = bid.params.video[param];
895-
type = (isArray(type)) ? type[0] : type;
896-
tag.video[param] = VIDEO_MAPPING[param][type];
897-
break;
898-
// Deprecating tags[].video.frameworks in favor of tags[].video_frameworks
899-
case 'frameworks':
900-
break;
901-
default:
902-
tag.video[param] = bid.params.video[param];
903-
}
904-
});
874+
if (videoMediaType && context === 'adpod') {
875+
tag.hb_source = 7;
876+
} else {
877+
tag.hb_source = 1;
878+
}
879+
if (bid.mediaType === VIDEO || videoMediaType) {
880+
tag.ad_types.push(VIDEO);
881+
}
905882

906-
if (bid.params.video.frameworks && isArray(bid.params.video.frameworks)) {
907-
tag['video_frameworks'] = bid.params.video.frameworks;
883+
// instream gets vastUrl, outstream gets vastXml
884+
if (bid.mediaType === VIDEO || (videoMediaType && context !== 'outstream')) {
885+
tag.require_asset_url = true;
908886
}
909-
}
910887

911-
// use IAB ORTB values if the corresponding values weren't already set by bid.params.video
912-
if (videoMediaType) {
913-
tag.video = tag.video || {};
914-
Object.keys(videoMediaType)
915-
.filter(param => includes(VIDEO_RTB_TARGETING, param))
916-
.forEach(param => {
917-
switch (param) {
918-
case 'minduration':
919-
case 'maxduration':
920-
if (typeof tag.video[param] !== 'number') tag.video[param] = videoMediaType[param];
921-
break;
922-
case 'skip':
923-
if (typeof tag.video['skippable'] !== 'boolean') tag.video['skippable'] = (videoMediaType[param] === 1);
924-
break;
925-
case 'skipafter':
926-
if (typeof tag.video['skipoffset'] !== 'number') tag.video['skippoffset'] = videoMediaType[param];
927-
break;
928-
case 'playbackmethod':
929-
if (typeof tag.video['playback_method'] !== 'number') {
930-
let type = videoMediaType[param];
888+
if (bid.params.video) {
889+
tag.video = {};
890+
// place any valid video params on the tag
891+
Object.keys(bid.params.video)
892+
.filter(param => includes(VIDEO_TARGETING, param))
893+
.forEach(param => {
894+
switch (param) {
895+
case 'context':
896+
case 'playback_method':
897+
let type = bid.params.video[param];
931898
type = (isArray(type)) ? type[0] : type;
899+
tag.video[param] = VIDEO_MAPPING[param][type];
900+
break;
901+
// Deprecating tags[].video.frameworks in favor of tags[].video_frameworks
902+
case 'frameworks':
903+
break;
904+
default:
905+
tag.video[param] = bid.params.video[param];
906+
}
907+
});
932908

933-
// we only support iab's options 1-4 at this time.
934-
if (type >= 1 && type <= 4) {
935-
tag.video['playback_method'] = type;
936-
}
937-
}
938-
break;
939-
case 'api':
940-
if (!tag['video_frameworks'] && isArray(videoMediaType[param])) {
941-
// need to read thru array; remove 6 (we don't support it), swap 4 <> 5 if found (to match our adserver mapping for these specific values)
942-
let apiTmp = videoMediaType[param].map(val => {
943-
let v = (val === 4) ? 5 : (val === 5) ? 4 : val;
944-
945-
if (v >= 1 && v <= 5) {
946-
return v;
909+
if (bid.params.video.frameworks && isArray(bid.params.video.frameworks)) {
910+
tag['video_frameworks'] = bid.params.video.frameworks;
911+
}
912+
}
913+
914+
// use IAB ORTB values if the corresponding values weren't already set by bid.params.video
915+
if (videoMediaType) {
916+
tag.video = tag.video || {};
917+
Object.keys(videoMediaType)
918+
.filter(param => includes(VIDEO_RTB_TARGETING, param))
919+
.forEach(param => {
920+
switch (param) {
921+
case 'minduration':
922+
case 'maxduration':
923+
if (typeof tag.video[param] !== 'number') tag.video[param] = videoMediaType[param];
924+
break;
925+
case 'skip':
926+
if (typeof tag.video['skippable'] !== 'boolean') tag.video['skippable'] = (videoMediaType[param] === 1);
927+
break;
928+
case 'skipafter':
929+
if (typeof tag.video['skipoffset'] !== 'number') tag.video['skippoffset'] = videoMediaType[param];
930+
break;
931+
case 'playbackmethod':
932+
if (typeof tag.video['playback_method'] !== 'number') {
933+
let type = videoMediaType[param];
934+
type = (isArray(type)) ? type[0] : type;
935+
936+
// we only support iab's options 1-4 at this time.
937+
if (type >= 1 && type <= 4) {
938+
tag.video['playback_method'] = type;
947939
}
948-
}).filter(v => v);
949-
tag['video_frameworks'] = apiTmp;
950-
}
951-
break;
952-
953-
case 'startdelay':
954-
case 'placement':
955-
const contextKey = 'context';
956-
if (typeof tag.video[contextKey] !== 'number') {
957-
const placement = videoMediaType['placement'];
958-
const startdelay = videoMediaType['startdelay'];
959-
const context = getContextFromPlacement(placement) || getContextFromStartDelay(startdelay);
960-
tag.video[contextKey] = VIDEO_MAPPING[contextKey][context];
961-
}
962-
break;
963-
}
964-
});
965-
}
940+
}
941+
break;
942+
case 'api':
943+
if (!tag['video_frameworks'] && isArray(videoMediaType[param])) {
944+
// need to read thru array; remove 6 (we don't support it), swap 4 <> 5 if found (to match our adserver mapping for these specific values)
945+
let apiTmp = videoMediaType[param].map(val => {
946+
let v = (val === 4) ? 5 : (val === 5) ? 4 : val;
947+
948+
if (v >= 1 && v <= 5) {
949+
return v;
950+
}
951+
}).filter(v => v);
952+
tag['video_frameworks'] = apiTmp;
953+
}
954+
break;
955+
956+
case 'startdelay':
957+
case 'placement':
958+
const contextKey = 'context';
959+
if (typeof tag.video[contextKey] !== 'number') {
960+
const placement = videoMediaType['placement'];
961+
const startdelay = videoMediaType['startdelay'];
962+
const context = getContextFromPlacement(placement) || getContextFromStartDelay(startdelay);
963+
tag.video[contextKey] = VIDEO_MAPPING[contextKey][context];
964+
}
965+
break;
966+
}
967+
});
968+
}
966969

967-
if (bid.renderer) {
968-
tag.video = Object.assign({}, tag.video, { custom_renderer_present: true });
970+
if (bid.renderer) {
971+
tag.video = Object.assign({}, tag.video, { custom_renderer_present: true });
972+
}
973+
} else {
974+
tag.hb_source = 1;
969975
}
970976

971977
if (bid.params.frameworks && isArray(bid.params.frameworks)) {

0 commit comments

Comments
 (0)