Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
127 changes: 126 additions & 1 deletion libraries/equativUtils/equativUtils.js
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,32 @@ import { deepAccess, isFn } from '../../src/utils.js';

const DEFAULT_FLOOR = 0.0;

/**
* Assigns values to new properties, removes temporary ones from an object
* and remove temporary default bidfloor of -1
* @param {*} obj An object
* @param {string} key A name of the new property
* @param {string} tempKey A name of the temporary property to be removed
* @returns {*} An updated object
*/
function cleanObject(obj, key, tempKey) {
const newObj = {};

for (const prop in obj) {
if (prop === key) {
if (Object.prototype.hasOwnProperty.call(obj, tempKey)) {
newObj[key] = obj[tempKey];
}
} else if (prop !== tempKey) {
newObj[prop] = obj[prop];
}
}

newObj.bidfloor === -1 && delete newObj.bidfloor;

return newObj;
}

/**
* Get floors from Prebid Price Floors module
*
Expand All @@ -11,7 +37,7 @@ const DEFAULT_FLOOR = 0.0;
* @param {string} mediaType Bid media type
* @return {number} Floor price
*/
export function getBidFloor (bid, currency, mediaType) {
export function getBidFloor(bid, currency, mediaType) {
const floors = [];

if (isFn(bid.getFloor)) {
Expand All @@ -28,3 +54,102 @@ export function getBidFloor (bid, currency, mediaType) {

return floors.length ? Math.min(...floors) : DEFAULT_FLOOR;
}

/**
* Returns a floor price provided by the Price Floors module or the floor price set in the publisher parameters
* @param {*} bid
* @param {string} mediaType A media type
* @param {number} width A width of the ad
* @param {number} height A height of the ad
* @param {string} currency A floor price currency
* @returns {number} Floor price
*/
function getFloor(bid, mediaType, width, height, currency) {
return bid.getFloor?.({ currency, mediaType, size: [width, height] })
.floor || bid.params.bidfloor || -1;
}

/**
* Generates a 14-char string id
* @returns {string}
*/
function makeId() {
const length = 14;
const characters = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789';
let counter = 0;
let str = '';

while (counter++ < length) {
str += characters.charAt(Math.floor(Math.random() * characters.length));
}

return str;
}


/**
* Prepares impressions for the request
*
* @param {*} imps An imps array
* @param {*} bid A bid
* @param {string} currency A currency
* @param {*} impIdMap An impIdMap
* @param {string} adapter A type of adapter (may be 'stx' or 'eqtv')
* @return {*}
*/
export function prepareSplitImps(imps, bid, currency, impIdMap, adapter) {
const splitImps = [];

imps.forEach(item => {
const floorMap = {};

const updateFloorMap = (type, name, width = 0, height = 0) => {
const floor = getFloor(bid, type, width, height, currency);

if (!floorMap[floor]) {
floorMap[floor] = {
...item,
bidfloor: floor
};
}

if (!floorMap[floor][name]) {
floorMap[floor][name] = type === 'banner' ? { format: [] } : item[type];
}

if (type === 'banner') {
floorMap[floor][name].format.push({ w: width, h: height });
}
};

if (item.banner?.format?.length) {
item.banner.format.forEach(format => updateFloorMap('banner', 'bannerTemp', format?.w, format?.h));
}

updateFloorMap('native', 'nativeTemp');
updateFloorMap('video', 'videoTemp', item.video?.w, item.video?.h);

Object.values(floorMap).forEach(obj => {
[
['banner', 'bannerTemp'],
['native', 'nativeTemp'],
['video', 'videoTemp']
].forEach(([name, tempName]) => obj = cleanObject(obj, name, tempName));

if (obj.banner || obj.video || obj.native) {
const id = makeId();
impIdMap[id] = obj.id;
obj.id = id;

if (obj.banner && adapter === 'stx') {
obj.banner.pos = item.banner.pos;
obj.banner.topframe = item.banner.topframe;
}

splitImps.push(obj);
}
});
});

return splitImps;
}
109 changes: 4 additions & 105 deletions modules/equativBidAdapter.js
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
import { ortbConverter } from '../libraries/ortbConverter/converter.js';
import { prepareSplitImps } from '../libraries/equativUtils/equativUtils.js';
import { tryAppendQueryString } from '../libraries/urlUtils/urlUtils.js';
import { registerBidder } from '../src/adapters/bidderFactory.js';
import { config } from '../src/config.js';
Expand All @@ -23,46 +24,6 @@ let impIdMap = {};
let nwid = 0;
let tokens = {};

/**
* Assigns values to new properties, removes temporary ones from an object
* and remove temporary default bidfloor of -1
* @param {*} obj An object
* @param {string} key A name of the new property
* @param {string} tempKey A name of the temporary property to be removed
* @returns {*} An updated object
*/
function cleanObject(obj, key, tempKey) {
const newObj = {};

for (const prop in obj) {
if (prop === key) {
if (Object.prototype.hasOwnProperty.call(obj, tempKey)) {
newObj[key] = obj[tempKey];
}
} else if (prop !== tempKey) {
newObj[prop] = obj[prop];
}
}

newObj.bidfloor === -1 && delete newObj.bidfloor;

return newObj;
}

/**
* Returns a floor price provided by the Price Floors module or the floor price set in the publisher parameters
* @param {*} bid
* @param {string} mediaType A media type
* @param {number} width A width of the ad
* @param {number} height A height of the ad
* @param {string} currency A floor price currency
* @returns {number} Floor price
*/
function getFloor(bid, mediaType, width, height, currency) {
return bid.getFloor?.({ currency, mediaType, size: [width, height] })
.floor || bid.params.bidfloor || -1;
}

/**
* Gets value of the local variable impIdMap
* @returns {*} Value of impIdMap
Expand All @@ -82,23 +43,6 @@ function isValid(bidReq) {
return !(bidReq.mediaTypes.video && JSON.stringify(bidReq.mediaTypes.video) === '{}') && !(bidReq.mediaTypes.native && JSON.stringify(bidReq.mediaTypes.native) === '{}');
}

/**
* Generates a 14-char string id
* @returns {string}
*/
function makeId() {
const length = 14;
const characters = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789';
let counter = 0;
let str = '';

while (counter++ < length) {
str += characters.charAt(Math.floor(Math.random() * characters.length));
}

return str;
}

/**
* Updates bid request with data from previous auction
* @param {*} req A bid request object to be updated
Expand Down Expand Up @@ -154,7 +98,7 @@ export const spec = {
requests.push({
data,
method: 'POST',
url: 'https://ssb-global.smartadserver.com/api/bid?callerId=169'
url: 'https://ssb-global.smartadserver.com/api/bid?callerId=169',
})
});

Expand Down Expand Up @@ -229,7 +173,7 @@ export const spec = {
});

let url = tryAppendQueryString(COOKIE_SYNC_URL + '?', 'nwid', nwid);
url = tryAppendQueryString(url, 'gdpr', (gdprConsent.gdprApplies ? '1' : '0'));
url = tryAppendQueryString(url, 'gdpr', (gdprConsent?.gdprApplies ? '1' : '0'));

return [{ type: 'iframe', url }];
}
Expand Down Expand Up @@ -268,52 +212,7 @@ export const converter = ortbConverter({
request(buildRequest, imps, bidderRequest, context) {
const bid = context.bidRequests[0];
const currency = config.getConfig('currency.adServerCurrency') || 'USD';
const splitImps = [];

imps.forEach(item => {
const floorMap = {};

const updateFloorMap = (type, name, width = 0, height = 0) => {
const floor = getFloor(bid, type, width, height, currency);

if (!floorMap[floor]) {
floorMap[floor] = {
...item,
bidfloor: floor
};
}

if (!floorMap[floor][name]) {
floorMap[floor][name] = type === 'banner' ? { format: [] } : item[type];
}

if (type === 'banner') {
floorMap[floor][name].format.push({ w: width, h: height });
}
};

if (item.banner?.format?.length) {
item.banner.format.forEach(format => updateFloorMap('banner', 'bannerTemp', format?.w, format?.h));
}
updateFloorMap('native', 'nativeTemp');
updateFloorMap('video', 'videoTemp', item.video?.w, item.video?.h);

Object.values(floorMap).forEach(obj => {
[
['banner', 'bannerTemp'],
['native', 'nativeTemp'],
['video', 'videoTemp']
].forEach(([name, tempName]) => obj = cleanObject(obj, name, tempName));

if (obj.banner || obj.video || obj.native) {
const id = makeId();
impIdMap[id] = obj.id;
obj.id = id;

splitImps.push(obj);
}
});
});
const splitImps = prepareSplitImps(imps, bid, currency, impIdMap, 'eqtv');

let req = buildRequest(splitImps, bidderRequest, context);

Expand Down
Loading
Loading