-
Notifications
You must be signed in to change notification settings - Fork 2.1k
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Adtelligent bid adapter updated to v3.0 (#4703)
* Adtelligent bid adapter updated to v3.0 with tests * Remove bidrequest.sizes usage * Force https Replace find-index with find * Add CCPA support * Fix test endpoint * lint * lint * deep access * spec https endpoint fix
- Loading branch information
1 parent
c760ca5
commit 5a1863e
Showing
2 changed files
with
574 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,250 @@ | ||
import * as utils from '../src/utils'; | ||
import {registerBidder} from '../src/adapters/bidderFactory'; | ||
import {VIDEO, BANNER} from '../src/mediaTypes'; | ||
import {Renderer} from '../src/Renderer'; | ||
import find from 'core-js/library/fn/array/find'; | ||
|
||
const URL = 'https://ghb.adtelligent.com/auction/'; | ||
const OUTSTREAM_SRC = 'https://player.adtelligent.com/outstream-unit/2.01/outstream.min.js'; | ||
const BIDDER_CODE = 'adtelligent'; | ||
const OUTSTREAM = 'outstream'; | ||
const DISPLAY = 'display'; | ||
const syncsCache = {}; | ||
|
||
export const spec = { | ||
code: BIDDER_CODE, | ||
aliases: ['onefiftytwomedia'], | ||
supportedMediaTypes: [VIDEO, BANNER], | ||
isBidRequestValid: function (bid) { | ||
return !!utils.deepAccess(bid, 'params.aid'); | ||
}, | ||
getUserSyncs: function (syncOptions, serverResponses) { | ||
const syncs = []; | ||
|
||
function addSyncs(bid) { | ||
const uris = bid.cookieURLs; | ||
const types = bid.cookieURLSTypes || []; | ||
|
||
if (Array.isArray(uris)) { | ||
uris.forEach((uri, i) => { | ||
const type = types[i] || 'image'; | ||
|
||
if ((!syncOptions.pixelEnabled && type == 'image') || | ||
(!syncOptions.iframeEnabled && type == 'iframe') || | ||
syncsCache[uri]) { | ||
return; | ||
} | ||
|
||
syncsCache[uri] = true; | ||
syncs.push({ | ||
type: type, | ||
url: uri | ||
}) | ||
}) | ||
} | ||
} | ||
|
||
if (syncOptions.pixelEnabled || syncOptions.iframeEnabled) { | ||
utils.isArray(serverResponses) && serverResponses.forEach((response) => { | ||
if (response.body) { | ||
if (utils.isArray(response.body)) { | ||
response.body.forEach(b => { | ||
addSyncs(b); | ||
}) | ||
} else { | ||
addSyncs(response.body) | ||
} | ||
} | ||
}) | ||
} | ||
return syncs; | ||
}, | ||
/** | ||
* Make a server request from the list of BidRequests | ||
* @param bidRequests | ||
* @param bidderRequest | ||
*/ | ||
buildRequests: function (bidRequests, bidderRequest) { | ||
return { | ||
data: bidToTag(bidRequests, bidderRequest), | ||
bidderRequest, | ||
method: 'GET', | ||
url: URL | ||
}; | ||
}, | ||
|
||
/** | ||
* Unpack the response from the server into a list of bids | ||
* @param serverResponse | ||
* @param bidderRequest | ||
* @return {Bid[]} An array of bids which were nested inside the server | ||
*/ | ||
interpretResponse: function (serverResponse, {bidderRequest}) { | ||
serverResponse = serverResponse.body; | ||
let bids = []; | ||
|
||
if (!utils.isArray(serverResponse)) { | ||
return parseRTBResponse(serverResponse, bidderRequest); | ||
} | ||
|
||
serverResponse.forEach(serverBidResponse => { | ||
bids = utils.flatten(bids, parseRTBResponse(serverBidResponse, bidderRequest)); | ||
}); | ||
|
||
return bids; | ||
} | ||
}; | ||
|
||
function parseRTBResponse(serverResponse, bidderRequest) { | ||
const isInvalidValidResp = !serverResponse || !utils.isArray(serverResponse.bids); | ||
|
||
const bids = []; | ||
|
||
if (isInvalidValidResp) { | ||
const extMessage = serverResponse && serverResponse.ext && serverResponse.ext.message ? `: ${serverResponse.ext.message}` : ''; | ||
const errorMessage = `in response for ${bidderRequest.bidderCode} adapter ${extMessage}`; | ||
|
||
utils.logError(errorMessage); | ||
|
||
return bids; | ||
} | ||
|
||
serverResponse.bids.forEach(serverBid => { | ||
const request = find(bidderRequest.bids, (bidRequest) => { | ||
return bidRequest.bidId === serverBid.requestId; | ||
}); | ||
|
||
if (serverBid.cpm !== 0 && request !== undefined) { | ||
const bid = createBid(serverBid, getMediaType(request)); | ||
|
||
bids.push(bid); | ||
} | ||
}); | ||
|
||
return bids; | ||
} | ||
|
||
function bidToTag(bidRequests, bidderRequest) { | ||
const tag = { | ||
domain: utils.deepAccess(bidderRequest, 'refererInfo.referer') | ||
}; | ||
|
||
if (utils.deepAccess(bidderRequest, 'gdprConsent.gdprApplies')) { | ||
tag.gdpr = 1; | ||
tag.gdpr_consent = utils.deepAccess(bidderRequest, 'gdprConsent.consentString'); | ||
} | ||
|
||
if (utils.deepAccess(bidderRequest, 'bidderRequest.uspConsent')) { | ||
tag.us_privacy = bidderRequest.uspConsent; | ||
} | ||
|
||
for (let i = 0, length = bidRequests.length; i < length; i++) { | ||
Object.assign(tag, prepareRTBRequestParams(i, bidRequests[i])); | ||
} | ||
|
||
return tag; | ||
} | ||
|
||
/** | ||
* Parse mediaType | ||
* @param _index {number} | ||
* @param bid {object} | ||
* @returns {object} | ||
*/ | ||
function prepareRTBRequestParams(_index, bid) { | ||
const mediaType = utils.deepAccess(bid, 'mediaTypes.video') ? VIDEO : DISPLAY; | ||
const index = !_index ? '' : `${_index + 1}`; | ||
const sizes = mediaType === VIDEO ? utils.deepAccess(bid, 'mediaTypes.video.playerSize') : utils.deepAccess(bid, 'mediaTypes.banner.sizes'); | ||
return { | ||
['callbackId' + index]: bid.bidId, | ||
['aid' + index]: bid.params.aid, | ||
['ad_type' + index]: mediaType, | ||
['sizes' + index]: utils.parseSizesInput(sizes).join() | ||
}; | ||
} | ||
|
||
/** | ||
* Prepare all parameters for request | ||
* @param bidderRequest {object} | ||
* @returns {object} | ||
*/ | ||
function getMediaType(bidderRequest) { | ||
const videoMediaType = utils.deepAccess(bidderRequest, 'mediaTypes.video'); | ||
const context = utils.deepAccess(bidderRequest, 'mediaTypes.video.context'); | ||
|
||
return !videoMediaType ? DISPLAY : context === OUTSTREAM ? OUTSTREAM : VIDEO; | ||
} | ||
|
||
/** | ||
* Configure new bid by response | ||
* @param bidResponse {object} | ||
* @param mediaType {Object} | ||
* @returns {object} | ||
*/ | ||
function createBid(bidResponse, mediaType) { | ||
const bid = { | ||
requestId: bidResponse.requestId, | ||
creativeId: bidResponse.cmpId, | ||
height: bidResponse.height, | ||
currency: bidResponse.cur, | ||
width: bidResponse.width, | ||
cpm: bidResponse.cpm, | ||
netRevenue: true, | ||
mediaType, | ||
ttl: 3600 | ||
}; | ||
|
||
if (mediaType === DISPLAY) { | ||
return Object.assign(bid, { | ||
ad: bidResponse.ad | ||
}); | ||
} | ||
|
||
Object.assign(bid, { | ||
vastUrl: bidResponse.vastUrl | ||
}); | ||
|
||
if (mediaType === OUTSTREAM) { | ||
Object.assign(bid, { | ||
mediaType: 'video', | ||
adResponse: bidResponse, | ||
renderer: newRenderer(bidResponse.requestId) | ||
}); | ||
} | ||
|
||
return bid; | ||
} | ||
|
||
/** | ||
* Create Adtelligent renderer | ||
* @param requestId | ||
* @returns {*} | ||
*/ | ||
function newRenderer(requestId) { | ||
const renderer = Renderer.install({ | ||
id: requestId, | ||
url: OUTSTREAM_SRC, | ||
loaded: false | ||
}); | ||
|
||
renderer.setRender(outstreamRender); | ||
|
||
return renderer; | ||
} | ||
|
||
/** | ||
* Initialise Adtelligent outstream | ||
* @param bid | ||
*/ | ||
function outstreamRender(bid) { | ||
bid.renderer.push(() => { | ||
window.VOutstreamAPI.initOutstreams([{ | ||
width: bid.width, | ||
height: bid.height, | ||
vastUrl: bid.vastUrl, | ||
elId: bid.adUnitCode | ||
}]); | ||
}); | ||
} | ||
|
||
registerBidder(spec); |
Oops, something went wrong.