Skip to content

Commit

Permalink
Merge branch 'prebid:master' into master
Browse files Browse the repository at this point in the history
  • Loading branch information
MartinGumGum committed Apr 5, 2024
2 parents 12e0f4e + 0aed5ce commit fb0b3cc
Show file tree
Hide file tree
Showing 29 changed files with 1,848 additions and 643 deletions.
3 changes: 1 addition & 2 deletions gulpfile.js
Original file line number Diff line number Diff line change
Expand Up @@ -295,8 +295,7 @@ function bundle(dev, moduleArr) {
[coreFile].concat(moduleFiles).map(name => path.basename(name)).forEach((file) => {
(depGraph[file] || []).forEach((dep) => dependencies.add(helpers.getBuiltPath(dev, dep)));
});

const entries = [coreFile].concat(Array.from(dependencies), moduleFiles);
const entries = _.uniq([coreFile].concat(Array.from(dependencies), moduleFiles));

var outputFileName = argv.bundleName ? argv.bundleName : 'prebid.js';

Expand Down
3 changes: 1 addition & 2 deletions karma.conf.maker.js
Original file line number Diff line number Diff line change
Expand Up @@ -15,8 +15,7 @@ function newWebpackConfig(codeCoverage, disableFeatures) {
mode: 'development',
devtool: 'inline-source-map',
});

delete webpackConfig.entry;
['entry', 'optimization'].forEach(prop => delete webpackConfig[prop]);

webpackConfig.module.rules
.flatMap((r) => r.use)
Expand Down
213 changes: 213 additions & 0 deletions modules/anyclipBidAdapter.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,213 @@
import {registerBidder} from '../src/adapters/bidderFactory.js';
import {BANNER} from '../src/mediaTypes.js';
import {deepAccess, isArray, isFn, logError, logInfo} from '../src/utils.js';
import {config} from '../src/config.js';

/**
* @typedef {import('../src/adapters/bidderFactory.js').BidRequest} BidRequest
* @typedef {import('../src/adapters/bidderFactory.js').Bid} Bid
* @typedef {import('../src/adapters/bidderFactory.js').ServerRequest} ServerRequest
* @typedef {import('../src/adapters/bidderFactory.js').BidderSpec} BidderSpec
*/

const BIDDER_CODE = 'anyclip';
const ENDPOINT_URL = 'https://prebid.anyclip.com';
const DEFAULT_CURRENCY = 'USD';
const NET_REVENUE = false;

/*
* Get the bid floor value from the bidRequest object, either using the getFloor function or by accessing the 'params.floor' property.
* If the bid floor cannot be determined, return 0 as a fallback value.
*/
function getBidFloor(bidRequest) {
if (!isFn(bidRequest.getFloor)) {
return deepAccess(bidRequest, 'params.floor', 0);
}

try {
const bidFloor = bidRequest.getFloor({
currency: DEFAULT_CURRENCY,
mediaType: '*',
size: '*',
});
return bidFloor.floor;
} catch (err) {
logError(err);
return 0;
}
}

/** @type {BidderSpec} */
export const spec = {
code: BIDDER_CODE,
supportedMediaTypes: [BANNER],

/**
* @param {object} bid
* @return {boolean}
*/
isBidRequestValid: (bid = {}) => {
const bidder = deepAccess(bid, 'bidder');
const params = deepAccess(bid, 'params', {});
const mediaTypes = deepAccess(bid, 'mediaTypes', {});
const banner = deepAccess(mediaTypes, BANNER, {});

const isValidBidder = (bidder === BIDDER_CODE);
const isValidSize = (Boolean(banner.sizes) && isArray(mediaTypes[BANNER].sizes) && mediaTypes[BANNER].sizes.length > 0);
const hasSizes = mediaTypes[BANNER] ? isValidSize : false;
const hasRequiredBidParams = Boolean(params.publisherId && params.supplyTagId);

const isValid = isValidBidder && hasSizes && hasRequiredBidParams;
if (!isValid) {
logError(`Invalid bid request: isValidBidder: ${isValidBidder}, hasSizes: ${hasSizes}, hasRequiredBidParams: ${hasRequiredBidParams}`);
}
return isValid;
},

/**
* @param {BidRequest[]} validBidRequests
* @param {*} bidderRequest
* @return {ServerRequest}
*/
buildRequests: (validBidRequests, bidderRequest) => {
const bidRequest = validBidRequests[0];

let refererInfo;
if (bidderRequest && bidderRequest.refererInfo) {
refererInfo = bidderRequest.refererInfo;
}

const timeout = bidderRequest.timeout;
const timeoutAdjustment = timeout - ((20 / 100) * timeout); // timeout adjustment - 20%

if (isPubTagAvailable()) {
// Options
const options = {
publisherId: bidRequest.params.publisherId,
supplyTagId: bidRequest.params.supplyTagId,
url: refererInfo.page,
domain: refererInfo.domain,
prebidTimeout: timeoutAdjustment,
gpid: bidRequest.adUnitCode,
ext: {
transactionId: bidRequest.transactionId
},
sizes: bidRequest.sizes.map((size) => {
return {width: size[0], height: size[1]}
})
}
// Floor
const floor = parseFloat(getBidFloor(bidRequest));
if (!isNaN(floor)) {
options.ext.floor = floor;
}
// Supply Chain (Schain)
if (bidRequest?.schain) {
options.schain = bidRequest.schain
}
// GDPR & Consent (EU)
if (bidderRequest?.gdprConsent) {
options.gdpr = (bidderRequest.gdprConsent.gdprApplies ? 1 : 0);
options.consent = bidderRequest.gdprConsent.consentString;
}
// GPP
if (bidderRequest?.gppConsent?.gppString) {
options.gpp = {
gppVersion: bidderRequest.gppConsent.gppVersion,
sectionList: bidderRequest.gppConsent.sectionList,
applicableSections: bidderRequest.gppConsent.applicableSections,
gppString: bidderRequest.gppConsent.gppString
}
}
// CCPA (US Privacy)
if (bidderRequest?.uspConsent) {
options.usPrivacy = bidderRequest.uspConsent;
}
// COPPA
if (config.getConfig('coppa') === true) {
options.coppa = 1;
}
// Eids
if (bidRequest?.userIdAsEids) {
const eids = bidRequest.userIdAsEids;
if (eids && eids.length) {
options.eids = eids;
}
}

// Request bids
const requestBidsPromise = window._anyclip.pubTag.requestBids(options);
if (requestBidsPromise !== undefined) {
requestBidsPromise
.then(() => {
logInfo('PubTag requestBids done');
})
.catch((err) => {
logError('PubTag requestBids error', err);
});
}

// Request
const payload = {
tmax: timeoutAdjustment
}

return {
method: 'GET',
url: ENDPOINT_URL,
data: payload,
bidRequest
}
}
},

/**
* @param {*} serverResponse
* @param {ServerRequest} bidRequest
* @return {Bid[]}
*/
interpretResponse: (serverResponse, { bidRequest }) => {
const bids = [];

if (bidRequest && isPubTagAvailable()) {
const bidResponse = window._anyclip.pubTag.getBids(bidRequest.transactionId);
if (bidResponse) {
const { adServer } = bidResponse;
if (adServer) {
bids.push({
requestId: bidRequest.bidId,
creativeId: adServer.bid.creativeId,
cpm: bidResponse.cpm,
width: adServer.bid.width,
height: adServer.bid.height,
currency: adServer.bid.currency || DEFAULT_CURRENCY,
netRevenue: NET_REVENUE,
ttl: adServer.bid.ttl,
ad: adServer.bid.ad,
meta: adServer.bid.meta
});
}
}
}

return bids;
},

/**
* @param {Bid} bid
*/
onBidWon: (bid) => {
if (isPubTagAvailable()) {
window._anyclip.pubTag.bidWon(bid);
}
}
}

/**
* @return {boolean}
*/
const isPubTagAvailable = () => {
return !!(window._anyclip && window._anyclip.pubTag);
}

registerBidder(spec);
52 changes: 52 additions & 0 deletions modules/anyclipBidAdapter.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,52 @@
# Overview

```
Module Name: AnyClip Bidder Adapter
Module Type: Bidder Adapter
Maintainer: support@anyclip.com
```

# Description

Connects to AnyClip Marketplace for bids.

For more information about [AnyClip](https://anyclip.com), please contact [support@anyclip.com](support@anyclip.com).

AnyClip bid adapter supports Banner currently*.

Use `anyclip` as bidder.

# Bid Parameters

| Key | Required | Example | Description |
|---------------|----------|--------------------------|---------------------------------------|
| `publisherId` | Yes | `'12345'` | The publisher ID provided by AnyClip |
| `supplyTagId` | Yes | `'-mptNo0BycUG4oCDgGrU'` | The supply tag ID provided by AnyClip |
| `floor` | No | `0.5` | Floor price |


# Sample Ad Unit: For Publishers
## Sample Banner only Ad Unit
```js
var adUnits = [{
code: 'adunit1', // ad slot HTML element ID
mediaTypes: {
banner: {
sizes: [
[300, 250],
[728, 90]
]
}
},
bids: [{
bidder: 'anyclip',
params: {
publisherId: '12345', // required, string
supplyTagId: '-mptNo0BycUG4oCDgGrU', // required, string
floor: 0.5 // optional, floor
}
}]
}]
```


48 changes: 40 additions & 8 deletions modules/appnexusBidAdapter.js
Original file line number Diff line number Diff line change
Expand Up @@ -48,7 +48,7 @@ const URL = 'https://ib.adnxs.com/ut/v3/prebid';
const URL_SIMPLE = 'https://ib.adnxs-simple.com/ut/v3/prebid';
const VIDEO_TARGETING = ['id', 'minduration', 'maxduration',
'skippable', 'playback_method', 'frameworks', 'context', 'skipoffset'];
const VIDEO_RTB_TARGETING = ['minduration', 'maxduration', 'skip', 'skipafter', 'playbackmethod', 'api', 'startdelay'];
const VIDEO_RTB_TARGETING = ['minduration', 'maxduration', 'skip', 'skipafter', 'playbackmethod', 'api', 'startdelay', 'placement', 'plcmt'];
const USER_PARAMS = ['age', 'externalUid', 'external_uid', 'segments', 'gender', 'dnt', 'language'];
const APP_DEVICE_PARAMS = ['geo', 'device_id']; // appid is collected separately
const DEBUG_PARAMS = ['enabled', 'dongle', 'member_id', 'debug_timeout'];
Expand All @@ -72,7 +72,12 @@ const VIDEO_MAPPING = {
'mid_roll': 2,
'post_roll': 3,
'outstream': 4,
'in-banner': 5
'in-banner': 5,
'in-feed': 6,
'interstitial': 7,
'accompanying_content_pre_roll': 8,
'accompanying_content_mid_roll': 9,
'accompanying_content_post_roll': 10
}
};
const NATIVE_MAPPING = {
Expand Down Expand Up @@ -916,15 +921,15 @@ function bidToTag(bid) {
tag['video_frameworks'] = apiTmp;
}
break;

case 'startdelay':
case 'plcmt':
case 'placement':
const contextKey = 'context';
if (typeof tag.video[contextKey] !== 'number') {
if (typeof tag.video.context !== 'number') {
const plcmt = videoMediaType['plcmt'];
const placement = videoMediaType['placement'];
const startdelay = videoMediaType['startdelay'];
const context = getContextFromPlacement(placement) || getContextFromStartDelay(startdelay);
tag.video[contextKey] = VIDEO_MAPPING[contextKey][context];
const contextVal = getContextFromPlcmt(plcmt, startdelay) || getContextFromPlacement(placement) || getContextFromStartDelay(startdelay);
tag.video.context = VIDEO_MAPPING.context[contextVal];
}
break;
}
Expand Down Expand Up @@ -983,8 +988,12 @@ function getContextFromPlacement(ortbPlacement) {

if (ortbPlacement === 2) {
return 'in-banner';
} else if (ortbPlacement > 2) {
} else if (ortbPlacement === 3) {
return 'outstream';
} else if (ortbPlacement === 4) {
return 'in-feed';
} else if (ortbPlacement === 5) {
return 'intersitial';
}
}

Expand All @@ -1002,6 +1011,29 @@ function getContextFromStartDelay(ortbStartDelay) {
}
}

function getContextFromPlcmt(ortbPlcmt, ortbStartDelay) {
if (!ortbPlcmt) {
return;
}

if (ortbPlcmt === 2) {
if (!ortbStartDelay) {
return;
}
if (ortbStartDelay === 0) {
return 'accompanying_content_pre_roll';
} else if (ortbStartDelay === -1) {
return 'accompanying_content_mid_roll';
} else if (ortbStartDelay === -2) {
return 'accompanying_content_post_roll';
}
} else if (ortbPlcmt === 3) {
return 'interstitial';
} else if (ortbPlcmt === 4) {
return 'outstream';
}
}

function hasUserInfo(bid) {
return !!bid.params.user;
}
Expand Down
2 changes: 2 additions & 0 deletions modules/e_volutionBidAdapter.js
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ import { isFn, deepAccess, logMessage } from '../src/utils.js';
import { convertOrtbRequestToProprietaryNative } from '../src/native.js';

const BIDDER_CODE = 'e_volution';
const GVLID = 957;
const AD_URL = 'https://service.e-volution.ai/?c=o&m=multi';
const URL_SYNC = 'https://service.e-volution.ai/?c=o&m=sync';
const NO_SYNC = true;
Expand Down Expand Up @@ -57,6 +58,7 @@ function getUserId(eids, id, source, uidExt) {

export const spec = {
code: BIDDER_CODE,
gvlid: GVLID,
supportedMediaTypes: [BANNER, VIDEO, NATIVE],
noSync: NO_SYNC,

Expand Down
Loading

0 comments on commit fb0b3cc

Please sign in to comment.