Skip to content

Commit a361ae7

Browse files
EmpowerBidAdapter: initial release (#13943)
* EmpowerBidAdapter: initial release * EmpowerBidAdapter: initial release * some code changes after lint check * test bannerServerRequest changes from local url to server url * some fixes and improvements * unceswsary line removed --------- Co-authored-by: Monis Qadri <monis0395@users.noreply.github.com>
1 parent 3f16865 commit a361ae7

File tree

3 files changed

+1096
-0
lines changed

3 files changed

+1096
-0
lines changed

modules/empowerBidAdapter.js

Lines changed: 262 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,262 @@
1+
import {
2+
deepAccess,
3+
mergeDeep,
4+
logError,
5+
replaceMacros,
6+
triggerPixel,
7+
deepSetValue,
8+
isStr,
9+
isArray,
10+
getWinDimensions,
11+
} from "../src/utils.js";
12+
import { registerBidder } from "../src/adapters/bidderFactory.js";
13+
import { config } from "../src/config.js";
14+
import { VIDEO, BANNER } from "../src/mediaTypes.js";
15+
import { getConnectionType } from "../libraries/connectionInfo/connectionUtils.js";
16+
17+
export const ENDPOINT = "https://bid.virgul.com/prebid";
18+
19+
const BIDDER_CODE = "empower";
20+
const GVLID = 1248;
21+
22+
export const spec = {
23+
code: BIDDER_CODE,
24+
gvlid: GVLID,
25+
supportedMediaTypes: [VIDEO, BANNER],
26+
27+
isBidRequestValid: (bid) =>
28+
!!(bid && bid.params && bid.params.zone && bid.bidder === BIDDER_CODE),
29+
30+
buildRequests: (bidRequests, bidderRequest) => {
31+
const currencyObj = config.getConfig("currency");
32+
const currency = (currencyObj && currencyObj.adServerCurrency) || "USD";
33+
34+
const request = {
35+
id: bidRequests[0].bidderRequestId,
36+
at: 1,
37+
imp: bidRequests.map((slot) => impression(slot, currency)),
38+
site: {
39+
page: bidderRequest.refererInfo.page,
40+
domain: bidderRequest.refererInfo.domain,
41+
ref: bidderRequest.refererInfo.ref,
42+
publisher: { domain: bidderRequest.refererInfo.domain },
43+
},
44+
device: {
45+
ua: navigator.userAgent,
46+
js: 1,
47+
dnt:
48+
navigator.doNotTrack === "yes" ||
49+
navigator.doNotTrack === "1" ||
50+
navigator.msDoNotTrack === "1"
51+
? 1
52+
: 0,
53+
h: screen.height,
54+
w: screen.width,
55+
language: navigator.language,
56+
connectiontype: getConnectionType(),
57+
},
58+
cur: [currency],
59+
source: {
60+
fd: 1,
61+
tid: bidderRequest.ortb2?.source?.tid,
62+
ext: {
63+
prebid: "$prebid.version$",
64+
},
65+
},
66+
user: {},
67+
regs: {},
68+
ext: {},
69+
};
70+
71+
if (bidderRequest.gdprConsent) {
72+
request.user = {
73+
ext: {
74+
consent: bidderRequest.gdprConsent.consentString || "",
75+
},
76+
};
77+
request.regs = {
78+
ext: {
79+
gdpr:
80+
bidderRequest.gdprConsent.gdprApplies !== undefined
81+
? bidderRequest.gdprConsent.gdprApplies
82+
: true,
83+
},
84+
};
85+
}
86+
87+
if (bidderRequest.ortb2?.source?.ext?.schain) {
88+
request.schain = bidderRequest.ortb2.source.ext.schain;
89+
}
90+
91+
let bidUserIdAsEids = deepAccess(bidRequests, "0.userIdAsEids");
92+
if (isArray(bidUserIdAsEids) && bidUserIdAsEids.length > 0) {
93+
deepSetValue(request, "user.eids", bidUserIdAsEids);
94+
}
95+
96+
const commonFpd = bidderRequest.ortb2 || {};
97+
const { user, device, site, bcat, badv } = commonFpd;
98+
if (site) {
99+
mergeDeep(request, { site: site });
100+
}
101+
if (user) {
102+
mergeDeep(request, { user: user });
103+
}
104+
if (badv) {
105+
mergeDeep(request, { badv: badv });
106+
}
107+
if (bcat) {
108+
mergeDeep(request, { bcat: bcat });
109+
}
110+
111+
if (user?.geo && device?.geo) {
112+
request.device.geo = { ...request.device.geo, ...device.geo };
113+
request.user.geo = { ...request.user.geo, ...user.geo };
114+
} else {
115+
if (user?.geo || device?.geo) {
116+
request.user.geo = request.device.geo = user?.geo
117+
? { ...request.user.geo, ...user.geo }
118+
: { ...request.user.geo, ...device.geo };
119+
}
120+
}
121+
122+
if (bidderRequest.ortb2?.device) {
123+
mergeDeep(request.device, bidderRequest.ortb2.device);
124+
}
125+
126+
return {
127+
method: "POST",
128+
url: ENDPOINT,
129+
data: JSON.stringify(request),
130+
};
131+
},
132+
133+
interpretResponse: (bidResponse, bidRequest) => {
134+
const idToImpMap = {};
135+
const idToBidMap = {};
136+
137+
if (!bidResponse["body"]) {
138+
return [];
139+
}
140+
if (!bidRequest.data) {
141+
return [];
142+
}
143+
const requestImps = parse(bidRequest.data);
144+
if (!requestImps) {
145+
return [];
146+
}
147+
requestImps.imp.forEach((imp) => {
148+
idToImpMap[imp.id] = imp;
149+
});
150+
bidResponse = bidResponse.body;
151+
if (bidResponse) {
152+
bidResponse.seatbid.forEach((seatBid) =>
153+
seatBid.bid.forEach((bid) => {
154+
idToBidMap[bid.impid] = bid;
155+
})
156+
);
157+
}
158+
const bids = [];
159+
Object.keys(idToImpMap).forEach((id) => {
160+
const imp = idToImpMap[id];
161+
const result = idToBidMap[id];
162+
163+
if (result) {
164+
const bid = {
165+
requestId: id,
166+
cpm: result.price,
167+
creativeId: result.crid,
168+
ttl: 300,
169+
netRevenue: true,
170+
mediaType: imp.video ? VIDEO : BANNER,
171+
currency: bidResponse.cur,
172+
};
173+
if (imp.video) {
174+
bid.vastXml = result.adm;
175+
} else if (imp.banner) {
176+
bid.ad = result.adm;
177+
}
178+
bid.width = result.w;
179+
bid.height = result.h;
180+
if (result.burl) bid.burl = result.burl;
181+
if (result.nurl) bid.nurl = result.nurl;
182+
if (result.adomain) {
183+
bid.meta = {
184+
advertiserDomains: result.adomain,
185+
};
186+
}
187+
bids.push(bid);
188+
}
189+
});
190+
return bids;
191+
},
192+
193+
onBidWon: (bid) => {
194+
if (bid.nurl && isStr(bid.nurl)) {
195+
bid.nurl = replaceMacros(bid.nurl, {
196+
AUCTION_PRICE: bid.cpm,
197+
AUCTION_CURRENCY: bid.cur,
198+
});
199+
triggerPixel(bid.nurl);
200+
}
201+
},
202+
};
203+
204+
function impression(slot, currency) {
205+
let bidFloorFromModule;
206+
if (typeof slot.getFloor === "function") {
207+
const floorInfo = slot.getFloor({
208+
currency: "USD",
209+
mediaType: "*",
210+
size: "*",
211+
});
212+
bidFloorFromModule =
213+
floorInfo?.currency === "USD" ? floorInfo?.floor : undefined;
214+
}
215+
const imp = {
216+
id: slot.bidId,
217+
bidfloor: bidFloorFromModule || slot.params.bidfloor || 0,
218+
bidfloorcur:
219+
(bidFloorFromModule && "USD") ||
220+
slot.params.bidfloorcur ||
221+
currency ||
222+
"USD",
223+
tagid: "" + (slot.params.zone || ""),
224+
};
225+
226+
if (slot.mediaTypes.banner) {
227+
imp.banner = bannerImpression(slot);
228+
} else if (slot.mediaTypes.video) {
229+
imp.video = deepAccess(slot, "mediaTypes.video");
230+
}
231+
imp.ext = slot.params || {};
232+
const { innerWidth, innerHeight } = getWinDimensions();
233+
imp.ext.ww = innerWidth || "";
234+
imp.ext.wh = innerHeight || "";
235+
return imp;
236+
}
237+
238+
function bannerImpression(slot) {
239+
const sizes = slot.mediaTypes.banner.sizes || slot.sizes;
240+
return {
241+
format: sizes.map((s) => ({ w: s[0], h: s[1] })),
242+
w: sizes[0][0],
243+
h: sizes[0][1],
244+
};
245+
}
246+
247+
function parse(rawResponse) {
248+
try {
249+
if (rawResponse) {
250+
if (typeof rawResponse === "object") {
251+
return rawResponse;
252+
} else {
253+
return JSON.parse(rawResponse);
254+
}
255+
}
256+
} catch (ex) {
257+
logError("empowerBidAdapter", "ERROR", ex);
258+
}
259+
return null;
260+
}
261+
262+
registerBidder(spec);

modules/empowerBidAdapter.md

Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,36 @@
1+
# Overview
2+
3+
Module Name: Empower Bid Adapter
4+
5+
Module Type: Bidder Adapter
6+
7+
Maintainer: prebid@empower.net
8+
9+
# Description
10+
11+
Module that connects to Empower's demand sources
12+
13+
This adapter requires setup and approval from Empower.net.
14+
Please reach out to your account team or info@empower.net for more information.
15+
16+
# Test Parameters
17+
```javascript
18+
var adUnits = [
19+
{
20+
code: '/19968336/prebid_banner_example_1',
21+
mediaTypes: {
22+
banner: {
23+
sizes: [[970, 250], [300, 250]],
24+
}
25+
},
26+
bids: [{
27+
bidder: 'empower',
28+
params: {
29+
bidfloor: 0.50,
30+
zone: 123456,
31+
site: 'example'
32+
},
33+
}]
34+
}
35+
];
36+
```

0 commit comments

Comments
 (0)