Skip to content

Commit

Permalink
ShowHeroes Bid Adapter: add new endpoint (prebid#8816)
Browse files Browse the repository at this point in the history
* add ShowHeroes Adapter

* ShowHeroes adapter - expanded outstream support

* Revert "ShowHeroes adapter - expanded outstream support"

This reverts commit bfcdb91.

* ShowHeroes adapter - expanded outstream support

* ShowHeroes adapter - fixes (prebid#4222)

* ShowHeroes adapter - banner and outstream fixes (prebid#4222)

* ShowHeroes adapter - description and outstream changes (prebid#4222)

* ShowHeroes adapter - increase test coverage and small fix

* ShowHeroes Adapter - naming convention issue

* Mixed AdUnits declaration support

* ITDEV-4723 PrebidJS adapter support with SupplyChain module object

* ITDEV-4723 Fix tests

* ITDEV-4723 New entry point

* showheroes-bsBidAdapter: Add support for advertiserDomains

* showheroes-bsBidAdapter: hotfix for outstream render

* showheroes-bsBidAdapter: update renderer url

* showheroes-bsBidAdapter: use only the necessary fields from the gdprConsent

* ShowHeroes adapter - added a new endpoint

* ShowHeroes adapter - unit tests

* Update showheroes-bsBidAdapter.md

* kick off tests

Co-authored-by: Eldengrof <vadim.mazzherin@gmail.com>
Co-authored-by: veranevera <vera.yukhina@showheroes.com>
Co-authored-by: Elizaveta Voziyanova <44549195+h2p4x8@users.noreply.github.com>
  • Loading branch information
4 people authored and JacobKlein26 committed Feb 8, 2023
1 parent d5247e6 commit 6a4b80d
Show file tree
Hide file tree
Showing 3 changed files with 352 additions and 50 deletions.
178 changes: 130 additions & 48 deletions modules/showheroes-bsBidAdapter.js
Original file line number Diff line number Diff line change
@@ -1,4 +1,11 @@
import { deepAccess, getBidIdParameter, getWindowTop, logError } from '../src/utils.js';
import {
deepAccess,
getBidIdParameter,
getWindowTop,
triggerPixel,
logInfo,
logError
} from '../src/utils.js';
import { config } from '../src/config.js';
import { Renderer } from '../src/Renderer.js';
import { registerBidder } from '../src/adapters/bidderFactory.js';
Expand All @@ -7,6 +14,7 @@ import { loadExternalScript } from '../src/adloader.js';

const PROD_ENDPOINT = 'https://bs.showheroes.com/api/v1/bid';
const STAGE_ENDPOINT = 'https://bid-service.stage.showheroes.com/api/v1/bid';
const VIRALIZE_ENDPOINT = 'https://ads.viralize.tv/prebid-sh/';
const PROD_PUBLISHER_TAG = 'https://static.showheroes.com/publishertag.js';
const STAGE_PUBLISHER_TAG = 'https://pubtag.stage.showheroes.com/publishertag.js';
const PROD_VL = 'https://video-library.showheroes.com';
Expand All @@ -26,12 +34,13 @@ export const spec = {
aliases: ['showheroesBs'],
supportedMediaTypes: [VIDEO, BANNER],
isBidRequestValid: function(bid) {
return !!bid.params.playerId;
return !!bid.params.playerId || !!bid.params.unitId;
},
buildRequests: function(validBidRequests, bidderRequest) {
let adUnits = [];
const pageURL = validBidRequests[0].params.contentPageUrl || bidderRequest.refererInfo.page;
const pageURL = validBidRequests[0].params.contentPageUrl || bidderRequest.refererInfo.referer;
const isStage = !!validBidRequests[0].params.stage;
const isViralize = !!validBidRequests[0].params.unitId;
const isOutstream = deepAccess(validBidRequests[0], 'mediaTypes.video.context') === 'outstream';
const isCustomRender = deepAccess(validBidRequests[0], 'params.outstreamOptions.customRender');
const isNodeRender = deepAccess(validBidRequests[0], 'params.outstreamOptions.slot') || deepAccess(validBidRequests[0], 'params.outstreamOptions.iframe');
Expand All @@ -40,12 +49,19 @@ export const spec = {
const isBanner = !!validBidRequests[0].mediaTypes.banner || (isOutstream && !(isCustomRender || isNativeRender || isNodeRender));
const defaultSchain = validBidRequests[0].schain || {};

const consentData = bidderRequest.gdprConsent || {};
const gdprConsent = {
apiVersion: consentData.apiVersion || 2,
gdprApplies: consentData.gdprApplies || 0,
consentString: consentData.consentString || '',
}

validBidRequests.forEach((bid) => {
const videoSizes = getVideoSizes(bid);
const bannerSizes = getBannerSizes(bid);
const vpaidMode = getBidIdParameter('vpaidMode', bid.params);

const makeBids = (type, size) => {
const makeBids = (type, size, isViralize) => {
let context = '';
let streamType = 2;

Expand All @@ -61,53 +77,79 @@ export const spec = {
}
}

const consentData = bidderRequest.gdprConsent || {};

const gdprConsent = {
apiVersion: consentData.apiVersion || 2,
gdprApplies: consentData.gdprApplies || 0,
consentString: consentData.consentString || '',
}

return {
let rBid = {
type: streamType,
adUnitCode: bid.adUnitCode,
bidId: bid.bidId,
mediaType: type,
context: context,
playerId: getBidIdParameter('playerId', bid.params),
auctionId: bidderRequest.auctionId,
bidderCode: BIDDER_CODE,
gdprConsent: gdprConsent,
start: +new Date(),
timeout: 3000,
size: {
width: size[0],
height: size[1]
},
params: bid.params,
schain: bid.schain || defaultSchain,
schain: bid.schain || defaultSchain
};

if (isViralize) {
rBid.unitId = getBidIdParameter('unitId', bid.params);
rBid.sizes = size;
rBid.mediaTypes = {
[type]: {'context': context}
};
} else {
rBid.playerId = getBidIdParameter('playerId', bid.params);
rBid.mediaType = type;
rBid.size = {
width: size[0],
height: size[1]
};
rBid.gdprConsent = gdprConsent;
}

return rBid;
};

videoSizes.forEach((size) => {
adUnits.push(makeBids(VIDEO, size));
});
if (isViralize) {
if (videoSizes && videoSizes[0]) {
adUnits.push(makeBids(VIDEO, videoSizes, isViralize));
}
if (bannerSizes && bannerSizes[0]) {
adUnits.push(makeBids(BANNER, bannerSizes, isViralize));
}
} else {
videoSizes.forEach((size) => {
adUnits.push(makeBids(VIDEO, size));
});

bannerSizes.forEach((size) => {
adUnits.push(makeBids(BANNER, size));
});
bannerSizes.forEach((size) => {
adUnits.push(makeBids(BANNER, size));
});
}
});

return {
url: isStage ? STAGE_ENDPOINT : PROD_ENDPOINT,
method: 'POST',
options: {contentType: 'application/json', accept: 'application/json'},
data: {
let endpointUrl;
let data;

const QA = validBidRequests[0].params.qa || {};

if (isViralize) {
endpointUrl = VIRALIZE_ENDPOINT;
data = {
'bidRequests': adUnits,
'context': {
'gdprConsent': gdprConsent,
'schain': defaultSchain,
'pageURL': QA.pageURL || encodeURIComponent(pageURL)
}
}
} else {
endpointUrl = isStage ? STAGE_ENDPOINT : PROD_ENDPOINT;

data = {
'user': [],
'meta': {
'adapterVersion': 2,
'pageURL': encodeURIComponent(pageURL),
'pageURL': QA.pageURL || encodeURIComponent(pageURL),
'vastCacheEnabled': (!!config.getConfig('cache') && !isBanner && !outstreamOptions) || false,
'isDesktop': getWindowTop().document.documentElement.clientWidth > 700,
'xmlAndTag': !!(isOutstream && isCustomRender) || false,
Expand All @@ -116,6 +158,13 @@ export const spec = {
'requests': adUnits,
'debug': validBidRequests[0].params.debug || false,
}
}

return {
url: QA.endpoint || endpointUrl,
method: 'POST',
options: {contentType: 'application/json', accept: 'application/json'},
data: data
};
},
interpretResponse: function(response, request) {
Expand Down Expand Up @@ -149,33 +198,53 @@ export const spec = {
}
return syncs;
},

onBidWon(bid) {
if (bid.callbacks) {
triggerPixel(bid.callbacks.won);
}
logInfo(
`Showheroes adapter won the auction. Bid id: ${bid.bidId || bid.requestId}`
);
},
};

function createBids(bidRes, reqData) {
if (bidRes && (!Array.isArray(bidRes.bids) || bidRes.bids.length < 1)) {
if (!bidRes) {
return [];
}
const responseBids = bidRes.bids || bidRes.bidResponses;
if (!Array.isArray(responseBids) || responseBids.length < 1) {
return [];
}

const bids = [];
const bidMap = {};
(reqData.requests || []).forEach((bid) => {
(reqData.requests || reqData.bidRequests || []).forEach((bid) => {
bidMap[bid.bidId] = bid;
});

bidRes.bids.forEach(function (bid) {
const reqBid = bidMap[bid.bidId];
responseBids.forEach(function (bid) {
const requestId = bid.bidId || bid.requestId;
const reqBid = bidMap[requestId];
const currentBidParams = reqBid.params;
const isViralize = !!reqBid.params.unitId;
const size = {
width: bid.width || bid.size.width,
height: bid.height || bid.size.height
};

let bidUnit = {};
bidUnit.cpm = bid.cpm;
bidUnit.requestId = bid.bidId;
bidUnit.requestId = requestId;
bidUnit.adUnitCode = reqBid.adUnitCode;
bidUnit.currency = bid.currency;
bidUnit.mediaType = bid.mediaType || VIDEO;
bidUnit.ttl = TTL;
bidUnit.creativeId = 'c_' + bid.bidId;
bidUnit.creativeId = 'c_' + requestId;
bidUnit.netRevenue = true;
bidUnit.width = bid.size.width;
bidUnit.height = bid.size.height;
bidUnit.width = size.width;
bidUnit.height = size.height;
bidUnit.meta = {
advertiserDomains: bid.adomain || []
};
Expand All @@ -185,24 +254,26 @@ function createBids(bidRes, reqData) {
content: bid.vastXml,
};
}
if (bid.vastTag) {
bidUnit.vastUrl = bid.vastTag;
if (bid.vastTag || bid.vastUrl) {
bidUnit.vastUrl = bid.vastTag || bid.vastUrl;
}
if (bid.mediaType === BANNER) {
bidUnit.ad = getBannerHtml(bid, reqBid, reqData);
} else if (bid.context === 'outstream') {
const renderer = Renderer.install({
id: bid.bidId,
id: requestId,
url: 'https://static.showheroes.com/renderer.js',
adUnitCode: reqBid.adUnitCode,
config: {
playerId: reqBid.playerId,
width: bid.size.width,
height: bid.size.height,
width: size.width,
height: size.height,
vastUrl: bid.vastTag,
vastXml: bid.vastXml,
ad: bid.ad,
debug: reqData.debug,
isStage: !!reqData.meta.stage,
isStage: reqData.meta && !!reqData.meta.stage,
isViralize: isViralize,
customRender: getBidIdParameter('customRender', currentBidParams.outstreamOptions),
slot: getBidIdParameter('slot', currentBidParams.outstreamOptions),
iframe: getBidIdParameter('iframe', currentBidParams.outstreamOptions),
Expand All @@ -218,7 +289,12 @@ function createBids(bidRes, reqData) {
}

function outstreamRender(bid) {
const embedCode = createOutstreamEmbedCode(bid);
let embedCode;
if (bid.renderer.config.isViralize) {
embedCode = createOutstreamEmbedCodeV2(bid);
} else {
embedCode = createOutstreamEmbedCode(bid);
}
if (typeof bid.renderer.config.customRender === 'function') {
bid.renderer.config.customRender(bid, embedCode);
} else {
Expand Down Expand Up @@ -266,6 +342,12 @@ function createOutstreamEmbedCode(bid) {
return fragment;
}

function createOutstreamEmbedCodeV2(bid) {
const range = document.createRange();
range.selectNode(document.getElementsByTagName('body')[0]);
return range.createContextualFragment(getBidIdParameter('ad', bid.renderer.config));
}

function getBannerHtml (bid, reqBid, reqData) {
const isStage = !!reqData.meta.stage;
const urls = getEnvURLs(isStage);
Expand Down
49 changes: 49 additions & 0 deletions modules/showheroes-bsBidAdapter.md
Original file line number Diff line number Diff line change
Expand Up @@ -125,3 +125,52 @@ Module that connects to ShowHeroes demand source to fetch bids.
}
];
```

# Test Parameters (V2)
```
var adUnits = [
{
code: 'video',
mediaTypes: {
video: {
playerSize: [640, 480],
context: 'instream',
}
},
bids: [
{
bidder: "showheroes-bs",
params: {
unitId: 'AACBWAcof-611K4U',
vpaidMode: true // by default is 'false'
}
}
]
},
{
code: 'video',
mediaTypes: {
video: {
playerSize: [640, 480],
context: 'outstream',
}
},
bids: [
{
bidder: "showheroes-bs",
params: {
unitId: 'AACBTwsZVANd9NlB',
outstreamOptions: {
// Required for the outstream renderer to exact node, one of
iframe: 'iframe_id',
// or
slot: 'slot_id'
}
}
}
]
}
];
```

Loading

0 comments on commit 6a4b80d

Please sign in to comment.