Skip to content

Commit 355a6bf

Browse files
VaticSSPmatthewlane
authored andcommitted
Add FairTrade Bid Adapter (#2147)
1 parent ae341f9 commit 355a6bf

File tree

3 files changed

+467
-0
lines changed

3 files changed

+467
-0
lines changed

modules/fairtradeBidAdapter.js

Lines changed: 150 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,150 @@
1+
import * as utils from 'src/utils';
2+
import {registerBidder} from 'src/adapters/bidderFactory';
3+
const BIDDER_CODE = 'fairtrade';
4+
const ENDPOINT_URL = '//pool.fair-trademedia.com/hb';
5+
const TIME_TO_LIVE = 360;
6+
const ADAPTER_SYNC_URL = '//pool.fair-trademedia.com/push_sync';
7+
const LOG_ERROR_MESS = {
8+
noAuid: 'Bid from response has no auid parameter - ',
9+
noAdm: 'Bid from response has no adm parameter - ',
10+
noBid: 'Array of bid objects is empty',
11+
noPlacementCode: 'Can\'t find in requested bids the bid with auid - ',
12+
emptyUids: 'Uids should be not empty',
13+
emptySeatbid: 'Seatbid array from response has empty item',
14+
emptyResponse: 'Response is empty',
15+
hasEmptySeatbidArray: 'Response has empty seatbid array',
16+
hasNoArrayOfBids: 'Seatbid from response has no array of bid objects - '
17+
};
18+
export const spec = {
19+
code: BIDDER_CODE,
20+
/**
21+
* Determines whether or not the given bid request is valid.
22+
*
23+
* @param {BidRequest} bid The bid params to validate.
24+
* @return boolean True if this is a valid bid, and false otherwise.
25+
*/
26+
isBidRequestValid: function(bid) {
27+
return !!bid.params.uid;
28+
},
29+
/**
30+
* Make a server request from the list of BidRequests.
31+
*
32+
* @param {BidRequest[]} validBidRequests - an array of bids
33+
* @return ServerRequest Info describing the request to the server.
34+
*/
35+
buildRequests: function(validBidRequests) {
36+
const auids = [];
37+
const bidsMap = {};
38+
const bids = validBidRequests || [];
39+
let priceType = 'net';
40+
let reqId;
41+
42+
bids.forEach(bid => {
43+
if (bid.params.priceType === 'gross') {
44+
priceType = 'gross';
45+
}
46+
reqId = bid.bidderRequestId;
47+
if (!bidsMap[bid.params.uid]) {
48+
bidsMap[bid.params.uid] = [bid];
49+
auids.push(bid.params.uid);
50+
} else {
51+
bidsMap[bid.params.uid].push(bid);
52+
}
53+
});
54+
55+
const payload = {
56+
u: utils.getTopWindowUrl(),
57+
pt: priceType,
58+
auids: auids.join(','),
59+
r: reqId
60+
};
61+
62+
return {
63+
method: 'GET',
64+
url: ENDPOINT_URL,
65+
data: payload,
66+
bidsMap: bidsMap,
67+
};
68+
},
69+
/**
70+
* Unpack the response from the server into a list of bids.
71+
*
72+
* @param {*} serverResponse A successful response from the server.
73+
* @param {*} bidRequest
74+
* @return {Bid[]} An array of bids which were nested inside the server.
75+
*/
76+
interpretResponse: function(serverResponse, bidRequest) {
77+
serverResponse = serverResponse && serverResponse.body
78+
const bidResponses = [];
79+
const bidsMap = bidRequest.bidsMap;
80+
const priceType = bidRequest.data.pt;
81+
82+
let errorMessage;
83+
84+
if (!serverResponse) errorMessage = LOG_ERROR_MESS.emptyResponse;
85+
else if (serverResponse.seatbid && !serverResponse.seatbid.length) {
86+
errorMessage = LOG_ERROR_MESS.hasEmptySeatbidArray;
87+
}
88+
89+
if (!errorMessage && serverResponse.seatbid) {
90+
serverResponse.seatbid.forEach(respItem => {
91+
_addBidResponse(_getBidFromResponse(respItem), bidsMap, priceType, bidResponses);
92+
});
93+
}
94+
if (errorMessage) utils.logError(errorMessage);
95+
return bidResponses;
96+
},
97+
getUserSyncs: function(syncOptions) {
98+
if (syncOptions.pixelEnabled) {
99+
return [{
100+
type: 'image',
101+
url: ADAPTER_SYNC_URL
102+
}];
103+
}
104+
}
105+
}
106+
107+
function _getBidFromResponse(respItem) {
108+
if (!respItem) {
109+
utils.logError(LOG_ERROR_MESS.emptySeatbid);
110+
} else if (!respItem.bid) {
111+
utils.logError(LOG_ERROR_MESS.hasNoArrayOfBids + JSON.stringify(respItem));
112+
} else if (!respItem.bid[0]) {
113+
utils.logError(LOG_ERROR_MESS.noBid);
114+
}
115+
return respItem && respItem.bid && respItem.bid[0];
116+
}
117+
118+
function _addBidResponse(serverBid, bidsMap, priceType, bidResponses) {
119+
if (!serverBid) return;
120+
let errorMessage;
121+
if (!serverBid.auid) errorMessage = LOG_ERROR_MESS.noAuid + JSON.stringify(serverBid);
122+
if (!serverBid.adm) errorMessage = LOG_ERROR_MESS.noAdm + JSON.stringify(serverBid);
123+
else {
124+
const awaitingBids = bidsMap[serverBid.auid];
125+
if (awaitingBids) {
126+
awaitingBids.forEach(bid => {
127+
const bidResponse = {
128+
requestId: bid.bidId, // bid.bidderRequestId,
129+
cpm: serverBid.price,
130+
width: serverBid.w,
131+
height: serverBid.h,
132+
creativeId: serverBid.auid, // bid.bidId,
133+
currency: 'USD',
134+
netRevenue: priceType !== 'gross',
135+
ttl: TIME_TO_LIVE,
136+
ad: serverBid.adm,
137+
dealId: serverBid.dealid
138+
};
139+
bidResponses.push(bidResponse);
140+
});
141+
} else {
142+
errorMessage = LOG_ERROR_MESS.noPlacementCode + serverBid.auid;
143+
}
144+
}
145+
if (errorMessage) {
146+
utils.logError(errorMessage);
147+
}
148+
}
149+
150+
registerBidder(spec);

modules/fairtradeBidAdapter.md

Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,28 @@
1+
# Overview
2+
3+
Module Name: FairTrade Bidder Adapter
4+
Module Type: Bidder Adapter
5+
Maintainer: [email protected]
6+
7+
# Description
8+
9+
Module that connects to FairTrade demand source to fetch bids.
10+
11+
# Test Parameters
12+
```
13+
var adUnits = [
14+
{
15+
code: 'test-div',
16+
sizes: [[300, 250]],
17+
bids: [
18+
{
19+
bidder: "fairtrade",
20+
params: {
21+
uid: '166',
22+
priceType: 'gross' // by default is 'net'
23+
}
24+
}
25+
]
26+
}
27+
];
28+
```

0 commit comments

Comments
 (0)