Skip to content

Commit

Permalink
GothamAds prebid adapter (prebid#6180)
Browse files Browse the repository at this point in the history
* init new pull request with GothamAds prebid adapter

* new optional params (prebid#6148)

* Add the root domain check method as a util method added for use mod… (prebid#6124)

* Add the root domain check method as a global method added for use modules

* Add a date suffix to keep the test cookie random

* Per review, moved the findRootDomain method to utils out of the userId modules

* More the domain method back the user module but attach it to the submodule so that userId modules can have access to it

* Remove the storageManager as it is no longer used in utils

* fix includes and find references in various files (prebid#6183)

* Fix typo in mediaforce bid adapter (prebid#6181)

* add mediaforce bid adapter

* make use of unused variable language

* Added native support for Mediaforce Bid Adapter

* Fix test endpoint url for Mediaforce Bid Adapter

* cleanup

* Added the ability to send multiple bids in one ad request for mediaforce bid adapter

* Fixes after review for mediaforce bid adapter

* Fix typo in mediaforce bid adapter

Co-authored-by: ksanksana <little.grey.goblin@gmail.com>

* Prebid JS Native Phase 2 update: (prebid#5411)

* Prebid JS Native Phase 2 update:

1) Key Suppression for Native keys with sendTargetingKeys set to false at nativeParams.sendTargetingKeys or within asset i.e. nativeParams.image.sendTargetingKeys. Logic as follows:
   - If nativeParams.sendTargetingKeys set to false but asset has sendTargetingKeys set to true then add the KV
   - Else if nativeParams.sendTargetingKeys is set to true and asset does not have sendTargetingKeys defined or it is set to true then add KV
   - Else if nativeParams.sendTargetingKeys is not defined and asset does not have sendTargetingKeys defined or it is set
 to true then add KV
   If no conditions met then key is suppressed
2) Adds rendererUrl or adTemplate to the bid object for easy retrieval if assets requested from creative
3) Adds new logic to receiveMessage function in secureCreatives.js to answer data.action of 'allAssetRequest' with all available assets on the bid that have a value
4) Adds new native keys to constants.json

* Update to simplify send asset logic

* Fixed asset location typo

* Update to include message listener for native resize and update adObject for auction to include creative height and trigger resize

Co-authored-by: Michael Moschovas <mmoschovas@NY-Moschovas.local>

* Improve __uspapi behavior in iframe (prebid#6072)

* align locator + fix remove listener

* update comment

Co-authored-by: Reinout Stevens <reinout@crazygames.com>

* Prebid 4.22.0 Release

* Increment pre version

* Sovrn: Add Support for Floor Module (prebid#6155)

* EX-2549 Pass segments parameter as imp.ext.dealids array

* EX-2549 Address Jon's feedback

* EX-2549 Reworked the solution

* EX-2549 Blackbird compatibility

* EX-2549 Address Jon's comments

* EX-2549 Addressed upstream PR comments

* added floor module support

* added function check

* rerun test

Co-authored-by: Egor Gordeev <egordeev@lineate.com>
Co-authored-by: Egor Gordeev <48566506+egsgordeev@users.noreply.github.com>

* Lotame panorama id glv (prebid#6185)

* Add the root domain check method as a global method added for use modules

* Add a date suffix to keep the test cookie random

* Per review, moved the findRootDomain method to utils out of the userId modules

* More the domain method back the user module but attach it to the submodule so that userId modules can have access to it

* Remove the storageManager as it is no longer used in utils

* Add the GVLID to the lotamePanoramaIdSystem

* Use the GVL ID in the storage manager as well

* Admixer bid adapter: add fpd (prebid#6190)

* Migrating to Prebid 1.0

* Migrating to Prebid 1.0

* Fix spec

* add gdpr and usp

* remove changes in gdpr_hello_world.html

* Update gdpr_hello_world.html

add spaces

* add user syncs

* remove comments

* tests

* add fpd to request

Co-authored-by: atkachov <atkachov91@admixer.ua>

* Add Adomain Targeting Key and Default Targeting Keys (prebid#6116)

* Add Adomain Targeting Key

* add default targeting key

Co-authored-by: Veronica Kim <vkim@vkim-mac.lan>

* Adkernel: torchad alias (prebid#6191)

* New feature: PBS anti alias (prebid#6150)

* PBS anti alias

* lint

* lint

* update test

* update test

* Unit tests + dynamic aliasing

* test bidder factory

* Waardex Bid Adapter: Add video support, refactor code (prebid#6149)

* Add video support, refactor code

* Add zoneId, refactor

Co-authored-by: yegorheiz <yegorheiz@gmail.com>

* init new pull request with GothamAds prebid adapter

Co-authored-by: Drilon Kastrati <drilon@gjirafa.com>
Co-authored-by: Mark <markaconrad@users.noreply.github.com>
Co-authored-by: jsnellbaker <31102355+jsnellbaker@users.noreply.github.com>
Co-authored-by: Niksok <belnamtar@mail.ru>
Co-authored-by: ksanksana <little.grey.goblin@gmail.com>
Co-authored-by: mmoschovas <63253416+mmoschovas@users.noreply.github.com>
Co-authored-by: Michael Moschovas <mmoschovas@NY-Moschovas.local>
Co-authored-by: Reinout Stevens <reinout@reinoutstevens.be>
Co-authored-by: Reinout Stevens <reinout@crazygames.com>
Co-authored-by: Scott Menzer <scott@id5.io>
Co-authored-by: John Rosendahl <jrosendahl@gmail.com>
Co-authored-by: Egor Gordeev <egordeev@lineate.com>
Co-authored-by: Egor Gordeev <48566506+egsgordeev@users.noreply.github.com>
Co-authored-by: Galphimbl <sashatkachov91@gmail.com>
Co-authored-by: atkachov <atkachov91@admixer.ua>
Co-authored-by: Veronica Kim <43146383+vkimcm@users.noreply.github.com>
Co-authored-by: Veronica Kim <vkim@vkim-mac.lan>
Co-authored-by: Denis Logachov <denis@adkernel.com>
Co-authored-by: Gena <wertixvost@gmail.com>
Co-authored-by: yegorWaardex <59033363+yegorWaardex@users.noreply.github.com>
Co-authored-by: yegorheiz <yegorheiz@gmail.com>
  • Loading branch information
22 people authored and stsepelin committed May 28, 2021
1 parent 766ccf8 commit 8456768
Show file tree
Hide file tree
Showing 3 changed files with 780 additions and 0 deletions.
307 changes: 307 additions & 0 deletions modules/gothamadsBidAdapter.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,307 @@
import { registerBidder } from '../src/adapters/bidderFactory.js';
import { BANNER, NATIVE, VIDEO } from '../src/mediaTypes.js';
import * as utils from '../src/utils.js';
import {config} from '../src/config.js';

const BIDDER_CODE = 'gothamads';
const ACCOUNTID_MACROS = '[account_id]';
const URL_ENDPOINT = `https://us-e-node1.gothamads.com/bid?pass=${ACCOUNTID_MACROS}&integration=prebidjs`;
const NATIVE_ASSET_IDS = { 0: 'title', 2: 'icon', 3: 'image', 5: 'sponsoredBy', 4: 'body', 1: 'cta' };
const NATIVE_PARAMS = {
title: {
id: 0,
name: 'title'
},
icon: {
id: 2,
type: 1,
name: 'img'
},
image: {
id: 3,
type: 3,
name: 'img'
},
sponsoredBy: {
id: 5,
name: 'data',
type: 1
},
body: {
id: 4,
name: 'data',
type: 2
},
cta: {
id: 1,
type: 12,
name: 'data'
}
};
const NATIVE_VERSION = '1.2';

export const spec = {
code: BIDDER_CODE,
supportedMediaTypes: [BANNER, VIDEO, NATIVE],

/**
* 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: (bid) => {
return Boolean(bid.params.accountId) && Boolean(bid.params.placementId)
},

/**
* 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: (validBidRequests, bidderRequest) => {
if (validBidRequests && validBidRequests.length === 0) return []
let accuontId = validBidRequests[0].params.accountId;
const endpointURL = URL_ENDPOINT.replace(ACCOUNTID_MACROS, accuontId);

let winTop = window;
let location;
try {
location = new URL(bidderRequest.refererInfo.referer)
winTop = window.top;
} catch (e) {
location = winTop.location;
utils.logMessage(e);
};

let bids = [];
for (let bidRequest of validBidRequests) {
let impObject = prepareImpObject(bidRequest);
let data = {
id: bidRequest.bidId,
test: config.getConfig('debug') ? 1 : 0,
cur: ['USD'],
device: {
w: winTop.screen.width,
h: winTop.screen.height,
language: (navigator && navigator.language) ? navigator.language.indexOf('-') != -1 ? navigator.language.split('-')[0] : navigator.language : '',
},
site: {
page: location.pathname,
host: location.host
},
source: {
tid: bidRequest.transactionId
},
tmax: bidRequest.timeout,
imp: [impObject],
};
bids.push(data)
}
return {
method: 'POST',
url: endpointURL,
data: bids
};
},

/**
* 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: (serverResponse) => {
if (!serverResponse || !serverResponse.body) return []
let GothamAdskResponse = serverResponse.body;

let bids = [];
for (let response of GothamAdskResponse) {
let mediaType = response.seatbid[0].bid[0].ext && response.seatbid[0].bid[0].ext.mediaType ? response.seatbid[0].bid[0].ext.mediaType : BANNER;

let bid = {
requestId: response.id,
cpm: response.seatbid[0].bid[0].price,
width: response.seatbid[0].bid[0].w,
height: response.seatbid[0].bid[0].h,
ttl: response.ttl || 1200,
currency: response.cur || 'USD',
netRevenue: true,
creativeId: response.seatbid[0].bid[0].crid,
dealId: response.seatbid[0].bid[0].dealid,
mediaType: mediaType
};

switch (mediaType) {
case VIDEO:
bid.vastXml = response.seatbid[0].bid[0].adm
bid.vastUrl = response.seatbid[0].bid[0].ext.vastUrl
break
case NATIVE:
bid.native = parseNative(response.seatbid[0].bid[0].adm)
break
default:
bid.ad = response.seatbid[0].bid[0].adm
}

bids.push(bid);
}

return bids;
},
};

/**
* Determine type of request
*
* @param bidRequest
* @param type
* @returns {boolean}
*/
const checkRequestType = (bidRequest, type) => {
return (typeof utils.deepAccess(bidRequest, `mediaTypes.${type}`) !== 'undefined');
}

const parseNative = admObject => {
const { assets, link, imptrackers, jstracker } = admObject.native;
const result = {
clickUrl: link.url,
clickTrackers: link.clicktrackers || undefined,
impressionTrackers: imptrackers || undefined,
javascriptTrackers: jstracker ? [ jstracker ] : undefined
};
assets.forEach(asset => {
const kind = NATIVE_ASSET_IDS[asset.id];
const content = kind && asset[NATIVE_PARAMS[kind].name];
if (content) {
result[kind] = content.text || content.value || { url: content.url, width: content.w, height: content.h };
}
});

return result;
}

const prepareImpObject = (bidRequest) => {
let impObject = {
id: bidRequest.transactionId,
secure: 1,
ext: {
placementId: bidRequest.params.placementId
}
};
if (checkRequestType(bidRequest, BANNER)) {
impObject.banner = addBannerParameters(bidRequest);
}
if (checkRequestType(bidRequest, VIDEO)) {
impObject.video = addVideoParameters(bidRequest);
}
if (checkRequestType(bidRequest, NATIVE)) {
impObject.native = {
ver: NATIVE_VERSION,
request: addNativeParameters(bidRequest)
};
}
return impObject
};

const addNativeParameters = bidRequest => {
let impObject = {
id: bidRequest.transactionId,
ver: NATIVE_VERSION,
};

const assets = utils._map(bidRequest.mediaTypes.native, (bidParams, key) => {
const props = NATIVE_PARAMS[key];
const asset = {
required: bidParams.required & 1,
};
if (props) {
asset.id = props.id;
let wmin, hmin;
let aRatios = bidParams.aspect_ratios;

if (aRatios && aRatios[0]) {
aRatios = aRatios[0];
wmin = aRatios.min_width || 0;
hmin = aRatios.ratio_height * wmin / aRatios.ratio_width | 0;
}

if (bidParams.sizes) {
const sizes = flatten(bidParams.sizes);
wmin = sizes[0];
hmin = sizes[1];
}

asset[props.name] = {}

if (bidParams.len) asset[props.name]['len'] = bidParams.len;
if (props.type) asset[props.name]['type'] = props.type;
if (wmin) asset[props.name]['wmin'] = wmin;
if (hmin) asset[props.name]['hmin'] = hmin;

return asset;
}
}).filter(Boolean);

impObject.assets = assets;
return impObject
}

const addBannerParameters = (bidRequest) => {
let bannerObject = {};
const size = parseSizes(bidRequest, 'banner');
bannerObject.w = size[0];
bannerObject.h = size[1];
return bannerObject;
};

const parseSizes = (bid, mediaType) => {
let mediaTypes = bid.mediaTypes;
if (mediaType === 'video') {
let size = [];
if (mediaTypes.video && mediaTypes.video.w && mediaTypes.video.h) {
size = [
mediaTypes.video.w,
mediaTypes.video.h
];
} else if (Array.isArray(utils.deepAccess(bid, 'mediaTypes.video.playerSize')) && bid.mediaTypes.video.playerSize.length === 1) {
size = bid.mediaTypes.video.playerSize[0];
} else if (Array.isArray(bid.sizes) && bid.sizes.length > 0 && Array.isArray(bid.sizes[0]) && bid.sizes[0].length > 1) {
size = bid.sizes[0];
}
return size;
}
let sizes = [];
if (Array.isArray(mediaTypes.banner.sizes)) {
sizes = mediaTypes.banner.sizes[0];
} else if (Array.isArray(bid.sizes) && bid.sizes.length > 0) {
sizes = bid.sizes
} else {
utils.logWarn('no sizes are setup or found');
}

return sizes
}

const addVideoParameters = (bidRequest) => {
let videoObj = {};
let supportParamsList = ['mimes', 'minduration', 'maxduration', 'protocols', 'startdelay', 'placement', 'skip', 'skipafter', 'minbitrate', 'maxbitrate', 'delivery', 'playbackmethod', 'api', 'linearity']

for (let param of supportParamsList) {
if (bidRequest.mediaTypes.video[param] !== undefined) {
videoObj[param] = bidRequest.mediaTypes.video[param];
}
}

const size = parseSizes(bidRequest, 'video');
videoObj.w = size[0];
videoObj.h = size[1];
return videoObj;
}

const flatten = arr => {
return [].concat(...arr);
}

registerBidder(spec);
Loading

0 comments on commit 8456768

Please sign in to comment.