mk9-prebid
Version:
Header Bidding Management Library
214 lines (190 loc) • 6.33 kB
JavaScript
import * as utils from '../src/utils.js';
import { Renderer } from '../src/Renderer.js';
import { config } from '../src/config.js';
import { registerBidder } from '../src/adapters/bidderFactory.js';
import { BANNER, VIDEO } from '../src/mediaTypes.js';
export const spec = {
code: 'smilewanted',
aliases: ['smile', 'sw'],
supportedMediaTypes: [BANNER, VIDEO],
/**
* Determines whether or not the given bid request is valid.
*
* @param {object} bid The bid to validate.
* @return boolean True if this is a valid bid, and false otherwise.
*/
isBidRequestValid: function(bid) {
return !!(bid.params && bid.params.zoneId);
},
/**
* Make a server request from the list of BidRequests.
*
* @param {BidRequest[]} validBidRequests A non-empty list of valid bid requests that should be sent to the Server.
* @return ServerRequest Info describing the request to the server.
*/
buildRequests: function(validBidRequests, bidderRequest) {
return validBidRequests.map(bid => {
var payload = {
zoneId: bid.params.zoneId,
currencyCode: config.getConfig('currency.adServerCurrency') || 'EUR',
tagId: bid.adUnitCode,
sizes: bid.sizes.map(size => ({
w: size[0],
h: size[1]
})),
transactionId: bid.transactionId,
timeout: config.getConfig('bidderTimeout'),
bidId: bid.bidId,
positionType: bid.params.positionType || '',
prebidVersion: '$prebid.version$'
};
const floor = getBidFloor(bid);
if (floor) {
payload.bidfloor = floor;
}
if (bid.params.bidfloor) {
payload.bidfloor = bid.params.bidfloor;
}
if (bidderRequest && bidderRequest.refererInfo) {
payload.pageDomain = bidderRequest.refererInfo.referer || '';
}
if (bidderRequest && bidderRequest.gdprConsent) {
payload.gdpr_consent = bidderRequest.gdprConsent.consentString;
payload.gdpr = bidderRequest.gdprConsent.gdprApplies; // we're handling the undefined case server side
}
var payloadString = JSON.stringify(payload);
return {
method: 'POST',
url: 'https://prebid.smilewanted.com',
data: payloadString,
};
});
},
/**
* Unpack the response from the server into a list of bids.
*
* @param {*} serverResponse A successful response from the server.
* @return {Bid[]} An array of bids which were nested inside the server.
*/
interpretResponse: function(serverResponse, bidRequest) {
const bidResponses = [];
var response = serverResponse.body;
try {
if (response) {
const dealId = response.dealId || '';
const bidResponse = {
requestId: JSON.parse(bidRequest.data).bidId,
cpm: response.cpm,
width: response.width,
height: response.height,
creativeId: response.creativeId,
dealId: response.dealId,
currency: response.currency,
netRevenue: response.isNetCpm,
ttl: response.ttl,
ad: response.ad,
};
if (response.formatTypeSw == 'video_instream' || response.formatTypeSw == 'video_outstream') {
bidResponse['mediaType'] = 'video';
bidResponse['vastUrl'] = response.ad;
bidResponse['ad'] = null;
}
if (response.formatTypeSw == 'video_outstream') {
bidResponse['renderer'] = newRenderer(JSON.parse(bidRequest.data), response);
}
if (dealId.length > 0) {
bidResponse.dealId = dealId;
}
bidResponse.meta = {};
if (response.meta && response.meta.advertiserDomains && utils.isArray(response.meta.advertiserDomains)) {
bidResponse.meta.advertiserDomains = response.meta.advertiserDomains;
}
bidResponses.push(bidResponse);
}
} catch (error) {
utils.logError('Error while parsing smilewanted response', error);
}
return bidResponses;
},
/**
* User syncs.
*
* @param {*} syncOptions Publisher prebid configuration.
* @param {*} serverResponses A successful response from the server.
* @return {Syncs[]} An array of syncs that should be executed.
*/
getUserSyncs: function(syncOptions, responses, gdprConsent, uspConsent) {
let params = '';
if (gdprConsent && typeof gdprConsent.consentString === 'string') {
// add 'gdpr' only if 'gdprApplies' is defined
if (typeof gdprConsent.gdprApplies === 'boolean') {
params += `?gdpr=${Number(gdprConsent.gdprApplies)}&gdpr_consent=${gdprConsent.consentString}`;
} else {
params += `?gdpr_consent=${gdprConsent.consentString}`;
}
}
if (uspConsent) {
params += `${params ? '&' : '?'}us_privacy=${encodeURIComponent(uspConsent)}`;
}
const syncs = []
if (syncOptions.iframeEnabled) {
syncs.push({
type: 'iframe',
url: 'https://csync.smilewanted.com' + params
});
}
return syncs;
}
}
/**
* Create SmileWanted renderer
* @param requestId
* @returns {*}
*/
function newRenderer(bidRequest, bidResponse) {
const renderer = Renderer.install({
id: bidRequest.bidId,
url: bidResponse.OustreamTemplateUrl,
loaded: false
});
try {
renderer.setRender(outstreamRender);
} catch (err) {
utils.logWarn('Prebid Error calling setRender on newRenderer', err);
}
return renderer;
}
/**
* Initialise SmileWanted outstream
* @param bid
*/
function outstreamRender(bid) {
bid.renderer.push(() => {
window.SmileWantedOutStreamInit({
width: bid.width,
height: bid.height,
vastUrl: bid.vastUrl,
elId: bid.adUnitCode
});
});
}
/**
* Get the floor price from bid.params for backward compatibility.
* If not found, then check floor module.
* @param bid A valid bid object
* @returns {*|number} floor price
*/
function getBidFloor(bid) {
if (utils.isFn(bid.getFloor)) {
const floorInfo = bid.getFloor({
currency: 'USD',
mediaType: 'banner',
size: bid.sizes.map(size => ({ w: size[0], h: size[1] }))
});
if (utils.isPlainObject(floorInfo) && !isNaN(floorInfo.floor) && floorInfo.currency === 'USD') {
return parseFloat(floorInfo.floor);
}
}
return null;
}
registerBidder(spec);