Skip to content

AIDEM Bidder Adapter: changed required params and win notice payload #9457

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

Merged
merged 26 commits into from
Feb 5, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
26 commits
Select commit Hold shift + click to select a range
c55d01a
AIDEM Bid Adapter
gsollazzo Nov 9, 2022
c4b2f0d
Merge branch 'prebid:master' into master
gsollazzo Nov 9, 2022
6a443d2
Merge branch 'prebid:master' into master
gsollazzo Nov 10, 2022
fc359c1
Added _spec.js
gsollazzo Nov 10, 2022
61c803e
update
gsollazzo Nov 11, 2022
b36e93f
Merge branch 'prebid:master' into master
gsollazzo Nov 11, 2022
3c36ef2
Fix Navigator in _spec.js
gsollazzo Nov 14, 2022
4222cca
Merge branch 'prebid:master' into master
gsollazzo Nov 15, 2022
502397e
Removed timeout handler.
Nov 16, 2022
a87853d
Merge branch 'prebid:master' into master
gsollazzo Nov 16, 2022
9277d1e
Added publisherId as required bidder params
Nov 18, 2022
a42e2cf
Merge remote-tracking branch 'origin/master'
Nov 18, 2022
31d6b22
moved publisherId into site publisher object
Nov 18, 2022
705f255
Added wpar to environment
gsollazzo Dec 26, 2022
c2e0dee
Merge remote-tracking branch 'upstream/master'
gsollazzo Dec 26, 2022
ace8d4a
Merge branch 'prebid:master' into master
gsollazzo Dec 28, 2022
3a319ee
Added placementId parameter
gsollazzo Dec 28, 2022
48e57f2
Merge branch 'prebid:master' into master
gsollazzo Dec 28, 2022
9e804e5
Merge branch 'prebid:master' into master
darkstarac Jan 2, 2023
f704255
added unit tests for the wpar environment object
Jan 2, 2023
b99b274
Merge branch 'prebid:master' into master
gsollazzo Jan 3, 2023
5cf7879
Merge branch 'prebid:master' into master
darkstarac Jan 24, 2023
f077631
PlacementId is now a required parameter
Jan 24, 2023
6837c05
Merge branch 'prebid:master' into master
darkstarac Jan 30, 2023
4d67382
Revert to optional placementId parameter
Jan 30, 2023
8a68d01
Merge remote-tracking branch 'origin/master'
Jan 30, 2023
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
155 changes: 90 additions & 65 deletions modules/aidemBidAdapter.js
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import {_each, contains, deepAccess, deepSetValue, getDNT, isBoolean, isStr, logError, logInfo} from '../src/utils.js';
import {_each, contains, deepAccess, deepSetValue, getDNT, isBoolean, isStr, isNumber, logError, logInfo} from '../src/utils.js';
import {config} from '../src/config.js';
import {BANNER, VIDEO} from '../src/mediaTypes.js';
import {registerBidder} from '../src/adapters/bidderFactory.js';
Expand All @@ -21,6 +21,8 @@ export const ERROR_CODES = {
SITE_ID_INVALID_VALUE: 4,
MEDIA_TYPE_NOT_SUPPORTED: 5,
PUBLISHER_ID_INVALID_VALUE: 6,
INVALID_RATELIMIT: 7,
PLACEMENT_ID_INVALID_VALUE: 8,
};

const endpoints = {
Expand All @@ -30,29 +32,29 @@ const endpoints = {
timeout: `${BASE_URL}/notice/timeout`,
error: `${BASE_URL}/notice/error`,
}
}
};

export function setEndPoints(env = null, path = '', mediaType = BANNER) {
switch (env) {
case 'local':
endpoints.request = mediaType === BANNER ? `${LOCAL_BASE_URL}${path}/bid/request` : `${LOCAL_BASE_URL}${path}/bid/videorequest`
endpoints.notice.win = `${LOCAL_BASE_URL}${path}/notice/win`
endpoints.notice.error = `${LOCAL_BASE_URL}${path}/notice/error`
endpoints.notice.timeout = `${LOCAL_BASE_URL}${path}/notice/timeout`
endpoints.request = mediaType === BANNER ? `${LOCAL_BASE_URL}${path}/bid/request` : `${LOCAL_BASE_URL}${path}/bid/videorequest`;
endpoints.notice.win = `${LOCAL_BASE_URL}${path}/notice/win`;
endpoints.notice.error = `${LOCAL_BASE_URL}${path}/notice/error`;
endpoints.notice.timeout = `${LOCAL_BASE_URL}${path}/notice/timeout`;
break;
case 'main':
endpoints.request = mediaType === BANNER ? `${BASE_URL}${path}/bid/request` : `${BASE_URL}${path}/bid/videorequest`
endpoints.notice.win = `${BASE_URL}${path}/notice/win`
endpoints.notice.error = `${BASE_URL}${path}/notice/error`
endpoints.notice.timeout = `${BASE_URL}${path}/notice/timeout`
endpoints.request = mediaType === BANNER ? `${BASE_URL}${path}/bid/request` : `${BASE_URL}${path}/bid/videorequest`;
endpoints.notice.win = `${BASE_URL}${path}/notice/win`;
endpoints.notice.error = `${BASE_URL}${path}/notice/error`;
endpoints.notice.timeout = `${BASE_URL}${path}/notice/timeout`;
break;
}
return endpoints
return endpoints;
}

config.getConfig('aidem', function (config) {
if (config.aidem.env) { setEndPoints(config.aidem.env, config.aidem.path, config.aidem.mediaType) }
})
if (config.aidem.env) { setEndPoints(config.aidem.env, config.aidem.path, config.aidem.mediaType); }
});

// AIDEM Custom FN
function recur(obj) {
Expand Down Expand Up @@ -121,8 +123,8 @@ function getDevice() {

function getRegs() {
let regs = {};
const consentManagement = config.getConfig('consentManagement')
const coppa = config.getConfig('coppa')
const consentManagement = config.getConfig('consentManagement');
const coppa = config.getConfig('coppa');
if (consentManagement && !!(consentManagement.gdpr)) {
deepSetValue(regs, 'gdpr_applies', !!consentManagement.gdpr);
} else {
Expand All @@ -145,11 +147,15 @@ function getRegs() {
}

function getPageUrl(bidderRequest) {
return bidderRequest?.refererInfo?.page
return bidderRequest?.refererInfo?.page;
}

function buildWinNotice(bid) {
const params = bid.params[0];
return {
publisherId: params.publisherId,
siteId: params.siteId,
placementId: params.placementId,
burl: deepAccess(bid, 'meta.burl'),
cpm: bid.cpm,
currency: bid.currency,
Expand All @@ -161,7 +167,7 @@ function buildWinNotice(bid) {
ttl: bid.ttl,
requestTimestamp: bid.requestTimestamp,
responseTimestamp: bid.responseTimestamp,
}
};
}

function buildErrorNotice(prebidErrorResponse) {
Expand All @@ -171,29 +177,29 @@ function buildErrorNotice(prebidErrorResponse) {
auctionId: prebidErrorResponse.auctionId,
bidderRequestId: prebidErrorResponse.bidderRequestId,
metrics: {}
}
};
}

function hasValidFloor(obj) {
if (!obj) return false
const hasValue = !isNaN(Number(obj.value))
const hasCurrency = contains(AVAILABLE_CURRENCIES, obj.currency)
return hasValue && hasCurrency
if (!obj) return false;
const hasValue = !isNaN(Number(obj.value));
const hasCurrency = contains(AVAILABLE_CURRENCIES, obj.currency);
return hasValue && hasCurrency;
}

function getMediaType(bidRequest) {
if ((bidRequest.mediaTypes && bidRequest.mediaTypes.hasOwnProperty('video')) || bidRequest.params.hasOwnProperty('video')) { return VIDEO }
return BANNER
if ((bidRequest.mediaTypes && bidRequest.mediaTypes.hasOwnProperty('video')) || bidRequest.params.hasOwnProperty('video')) { return VIDEO; }
return BANNER;
}

function getPrebidRequestFields(bidderRequest, bidRequests) {
const payload = {}
const payload = {};
// Base Payload Data
deepSetValue(payload, 'id', bidderRequest.auctionId);
// Impressions
setPrebidImpressionObject(bidRequests, payload)
setPrebidImpressionObject(bidRequests, payload);
// Device
deepSetValue(payload, 'device', getDevice())
deepSetValue(payload, 'device', getDevice());
// Timeout
deepSetValue(payload, 'tmax', bidderRequest.timeout);
// Currency
Expand All @@ -203,13 +209,13 @@ function getPrebidRequestFields(bidderRequest, bidRequests) {
// Privacy Regs
deepSetValue(payload, 'regs', getRegs());
// Site
setPrebidSiteObject(bidderRequest, payload)
setPrebidSiteObject(bidderRequest, payload);
// Environment
setPrebidRequestEnvironment(payload)
setPrebidRequestEnvironment(payload);
// AT auction type
deepSetValue(payload, 'at', 1);

return payload
return payload;
}

function setPrebidImpressionObject(bidRequests, payload) {
Expand All @@ -220,24 +226,24 @@ function setPrebidImpressionObject(bidRequests, payload) {
deepSetValue(impressionObject, 'id', bidRequest.bidId);
// Transaction id
deepSetValue(impressionObject, 'tid', deepAccess(bidRequest, 'transactionId'));
// Placement id
// placement id
deepSetValue(impressionObject, 'tagid', deepAccess(bidRequest, 'params.placementId', null));
// Publisher id
deepSetValue(payload, 'site.publisher.id', deepAccess(bidRequest, 'params.publisherId'));
// Site id
deepSetValue(payload, 'site.id', deepAccess(bidRequest, 'params.siteId'));
const mediaType = getMediaType(bidRequest)
const mediaType = getMediaType(bidRequest);
switch (mediaType) {
case 'banner':
setPrebidImpressionObjectBanner(bidRequest, impressionObject)
setPrebidImpressionObjectBanner(bidRequest, impressionObject);
break;
case 'video':
setPrebidImpressionObjectVideo(bidRequest, impressionObject)
setPrebidImpressionObjectVideo(bidRequest, impressionObject);
break;
}

// Floor (optional)
setPrebidImpressionObjectFloor(bidRequest, impressionObject)
setPrebidImpressionObjectFloor(bidRequest, impressionObject);

impressionObject.imp_ext = {};

Expand Down Expand Up @@ -272,10 +278,10 @@ function setPrebidRequestEnvironment(payload) {
}

function setPrebidImpressionObjectFloor(bidRequest, impressionObject) {
const floor = deepAccess(bidRequest, 'params.floor')
const floor = deepAccess(bidRequest, 'params.floor');
if (hasValidFloor(floor)) {
deepSetValue(impressionObject, 'floor.value', floor.value)
deepSetValue(impressionObject, 'floor.currency', floor.currency)
deepSetValue(impressionObject, 'floor.value', floor.value);
deepSetValue(impressionObject, 'floor.currency', floor.currency);
}
}

Expand Down Expand Up @@ -322,7 +328,7 @@ function getPrebidResponseBidObject(openRTBResponseBidObject) {
deepSetValue(prebidResponseBidObject, 'currency', openRTBResponseBidObject.cur ? openRTBResponseBidObject.cur.toUpperCase() : DEFAULT_CURRENCY);
deepSetValue(prebidResponseBidObject, 'width', openRTBResponseBidObject.w);
deepSetValue(prebidResponseBidObject, 'height', openRTBResponseBidObject.h);
deepSetValue(prebidResponseBidObject, 'dealId', openRTBResponseBidObject.dealid)
deepSetValue(prebidResponseBidObject, 'dealId', openRTBResponseBidObject.dealid);
deepSetValue(prebidResponseBidObject, 'netRevenue', true);
deepSetValue(prebidResponseBidObject, 'ttl', 60000);

Expand All @@ -335,13 +341,13 @@ function getPrebidResponseBidObject(openRTBResponseBidObject) {
deepSetValue(prebidResponseBidObject, 'mediaType', BANNER);
deepSetValue(prebidResponseBidObject, 'ad', openRTBResponseBidObject.adm);
}
setPrebidResponseBidObjectMeta(prebidResponseBidObject, openRTBResponseBidObject)
return prebidResponseBidObject
setPrebidResponseBidObjectMeta(prebidResponseBidObject, openRTBResponseBidObject);
return prebidResponseBidObject;
}

function setPrebidResponseBidObjectMeta(prebidResponseBidObject, openRTBResponseBidObject) {
logInfo('AIDEM Bid Adapter meta', openRTBResponseBidObject);
deepSetValue(prebidResponseBidObject, 'meta.advertiserDomains', openRTBResponseBidObject.adomain);
deepSetValue(prebidResponseBidObject, 'meta.advertiserDomains', deepAccess(openRTBResponseBidObject, 'meta.advertiserDomains'));
if (openRTBResponseBidObject.cat && Array.isArray(openRTBResponseBidObject.cat)) {
const primaryCatId = openRTBResponseBidObject.cat.shift();
deepSetValue(prebidResponseBidObject, 'meta.primaryCatId', primaryCatId);
Expand All @@ -357,28 +363,28 @@ function setPrebidResponseBidObjectMeta(prebidResponseBidObject, openRTBResponse
}

function hasValidMediaType(bidRequest) {
const supported = hasBannerMediaType(bidRequest) || hasVideoMediaType(bidRequest)
const supported = hasBannerMediaType(bidRequest) || hasVideoMediaType(bidRequest);
if (!supported) {
logError('AIDEM Bid Adapter: media type not supported', { bidder: BIDDER_CODE, code: ERROR_CODES.MEDIA_TYPE_NOT_SUPPORTED });
}
return supported
return supported;
}

function hasBannerMediaType(bidRequest) {
return !!deepAccess(bidRequest, 'mediaTypes.banner')
return !!deepAccess(bidRequest, 'mediaTypes.banner');
}

function hasVideoMediaType(bidRequest) {
return !!deepAccess(bidRequest, 'mediaTypes.video')
return !!deepAccess(bidRequest, 'mediaTypes.video');
}

function hasValidBannerMediaType(bidRequest) {
const sizes = deepAccess(bidRequest, 'mediaTypes.banner.sizes')
const sizes = deepAccess(bidRequest, 'mediaTypes.banner.sizes');
if (!sizes) {
logError('AIDEM Bid Adapter: media type sizes missing', { bidder: BIDDER_CODE, code: ERROR_CODES.PROPERTY_NOT_INCLUDED });
return false;
}
return true
return true;
}

function hasValidVideoMediaType(bidRequest) {
Expand All @@ -387,23 +393,38 @@ function hasValidVideoMediaType(bidRequest) {
logError('AIDEM Bid Adapter: media type playerSize missing', { bidder: BIDDER_CODE, code: ERROR_CODES.PROPERTY_NOT_INCLUDED });
return false;
}
return true
return true;
}

function hasValidVideoParameters(bidRequest) {
let valid = true
let valid = true;
const adUnitsParameters = deepAccess(bidRequest, 'mediaTypes.video');
const bidderParameter = deepAccess(bidRequest, 'params.video');
for (let property of REQUIRED_VIDEO_PARAMS) {
const hasAdUnitParameter = adUnitsParameters.hasOwnProperty(property)
const hasBidderParameter = bidderParameter && bidderParameter.hasOwnProperty(property)
const hasAdUnitParameter = adUnitsParameters.hasOwnProperty(property);
const hasBidderParameter = bidderParameter && bidderParameter.hasOwnProperty(property);
if (!hasAdUnitParameter && !hasBidderParameter) {
logError(`AIDEM Bid Adapter: ${property} is not included in either the adunit or params level`, { bidder: BIDDER_CODE, code: ERROR_CODES.PROPERTY_NOT_INCLUDED });
valid = false
valid = false;
}
}

return valid
return valid;
}

function passesRateLimit(bidRequest) {
const rateLimit = deepAccess(bidRequest, 'params.rateLimit', 1);
if (!isNumber(rateLimit) || rateLimit > 1 || rateLimit < 0) {
logError('AIDEM Bid Adapter: invalid rateLimit (must be a number between 0 and 1)', { bidder: BIDDER_CODE, code: ERROR_CODES.INVALID_RATELIMIT });
return false;
}
if (rateLimit !== 1) {
const randomRateValue = Math.random();
if (randomRateValue > rateLimit) {
return false;
}
}
return true;
}

function hasValidParameters(bidRequest) {
Expand All @@ -421,7 +442,7 @@ function hasValidParameters(bidRequest) {
return false;
}

return true
return true;
}

export const spec = {
Expand All @@ -431,28 +452,32 @@ export const spec = {
logInfo('bid: ', bidRequest);

// check if request has valid mediaTypes
if (!hasValidMediaType(bidRequest)) return false
if (!hasValidMediaType(bidRequest)) return false;

// check if request has valid media type parameters at adUnit level
if (hasBannerMediaType(bidRequest) && !hasValidBannerMediaType(bidRequest)) {
return false
return false;
}

if (hasVideoMediaType(bidRequest) && !hasValidVideoMediaType(bidRequest)) {
return false
return false;
}

if (hasVideoMediaType(bidRequest) && !hasValidVideoParameters(bidRequest)) {
return false
return false;
}

return hasValidParameters(bidRequest)
if (!hasValidParameters(bidRequest)) {
return false;
}

return passesRateLimit(bidRequest);
},

buildRequests: function(validBidRequests, bidderRequest) {
logInfo('validBidRequests: ', validBidRequests);
logInfo('bidderRequest: ', bidderRequest);
const prebidRequest = getPrebidRequestFields(bidderRequest, validBidRequests)
const prebidRequest = getPrebidRequestFields(bidderRequest, validBidRequests);
const payloadString = JSON.stringify(prebidRequest);

return {
Expand All @@ -474,7 +499,7 @@ export const spec = {
return;
}
logInfo('CPM OK');
const bid = getPrebidResponseBidObject(bidObject)
const bid = getPrebidResponseBidObject(bidObject);
bids.push(bid);
});
return bids;
Expand All @@ -483,14 +508,14 @@ export const spec = {
onBidWon: function(bid) {
// Bidder specific code
logInfo('onBidWon bid: ', bid);
const notice = buildWinNotice(bid)
const notice = buildWinNotice(bid);
ajax(endpoints.notice.win, null, JSON.stringify(notice), { method: 'POST', withCredentials: true });
},

onBidderError: function({ bidderRequest }) {
// Bidder specific code
const notice = buildErrorNotice(bidderRequest)
const notice = buildErrorNotice(bidderRequest);
ajax(endpoints.notice.error, null, JSON.stringify(notice), { method: 'POST', withCredentials: true });
},
}
};
registerBidder(spec);
Loading