Skip to content

Commit d81dfd2

Browse files
nfoidettman
authored andcommitted
Add Adagio bidder and analytics adapters (prebid#3069)
* Add Adagio bidder and analytics adapters * Adagio - removed the superfluous argument passed to `_getDevice()` * Adagio - IE11 fix - replaced Array.prototype.find by its core-js equivalent * Adagio - linting. * Adagio - Renamed the property 'gdpr_consent' to 'gdpr' in our adRequest. * Adagio - Send one HTTP request per siteId - add the suffix `Id` to most params - add `dealId` and `timeout` to the payload of the analytics adapter - move `siteId` at the top-level of the ad request - remov the param `Publisher` * Removed the analytics adapters, they are not ready from prime time. * Removed the analytics adapter, it's not ready from prime time. * Added adagioAnalyticsAdapter as a 'bundle'.
1 parent 29e9b13 commit d81dfd2

File tree

5 files changed

+551
-0
lines changed

5 files changed

+551
-0
lines changed

modules/adagioAnalyticsAdapter.js

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
1+
/**
2+
* Analytics Adapter for Adagio
3+
*/
4+
5+
import adapter from 'src/AnalyticsAdapter';
6+
import adaptermanager from 'src/adaptermanager';
7+
8+
// This config makes Prebid.js call this function on each event:
9+
// `window['AdagioPrebidAnalytics']('on', eventType, args)`
10+
// If it is missing, then Prebid.js will immediately log an error,
11+
// instead of queueing the events until the function appears.
12+
var adagioAdapter = adapter({
13+
global: 'AdagioPrebidAnalytics',
14+
handler: 'on',
15+
analyticsType: 'bundle'
16+
});
17+
18+
adaptermanager.registerAnalyticsAdapter({
19+
adapter: adagioAdapter,
20+
code: 'adagio'
21+
});
22+
23+
export default adagioAdapter;

modules/adagioAnalyticsAdapter.md

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
# Overview
2+
3+
Module Name: Adagio Analytics Adapter
4+
Module Type: Adagio Adapter
5+
Maintainer: [email protected]
6+
7+
# Description
8+
9+
Analytics adapter for Adagio
10+
11+
# Test Parameters
12+
13+
```
14+
{
15+
provider: 'adagio'
16+
}
17+
```

modules/adagioBidAdapter.js

Lines changed: 178 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,178 @@
1+
import find from 'core-js/library/fn/array/find';
2+
import * as utils from 'src/utils';
3+
import { registerBidder } from 'src/adapters/bidderFactory';
4+
5+
const BIDDER_CODE = 'adagio';
6+
const VERSION = '1.0.0';
7+
const ENDPOINT = 'https://mp.4dex.io/prebid';
8+
const SUPPORTED_MEDIA_TYPES = ['banner'];
9+
10+
/**
11+
* Based on https://github.com/ua-parser/uap-cpp/blob/master/UaParser.cpp#L331, with the following updates:
12+
* - replaced `mobile` by `mobi` in the table regexp, so Opera Mobile on phones is not detected as a tablet.
13+
*/
14+
function _getDeviceType() {
15+
let ua = navigator.userAgent;
16+
17+
// Tablets must be checked before phones.
18+
if ((/(tablet|ipad|playbook|silk)|(android(?!.*mobi))/i).test(ua)) {
19+
return 5; // "tablet"
20+
}
21+
if ((/Mobile|iP(hone|od|ad)|Android|BlackBerry|IEMobile|Kindle|NetFront|Silk-Accelerated|(hpw|web)OS|Fennec|Minimo|Opera M(obi|ini)|Blazer|Dolfin|Dolphin|Skyfire|Zune/).test(ua)) {
22+
return 4; // "phone"
23+
}
24+
// Consider that all other devices are personal computers
25+
return 2;
26+
};
27+
28+
function _getDevice() {
29+
const language = navigator.language ? 'language' : 'userLanguage';
30+
return {
31+
userAgent: navigator.userAgent,
32+
language: navigator[language],
33+
deviceType: _getDeviceType(),
34+
dnt: utils.getDNT() ? 1 : 0,
35+
geo: {},
36+
js: 1
37+
};
38+
};
39+
40+
function _getSite() {
41+
const topLocation = utils.getTopWindowLocation();
42+
return {
43+
domain: topLocation.hostname,
44+
page: topLocation.href,
45+
referrer: utils.getTopWindowReferrer()
46+
};
47+
};
48+
49+
function _getPageviewId() {
50+
return (!window.top.ADAGIO || !window.top.ADAGIO.pageviewId) ? '_' : window.top.ADAGIO.pageviewId;
51+
};
52+
53+
function _getFeatures(bidRequest) {
54+
if (!window.top._ADAGIO || !window.top._ADAGIO.features) {
55+
return {};
56+
}
57+
58+
const rawFeatures = window.top._ADAGIO.features.getFeatures(
59+
document.getElementById(bidRequest.adUnitCode),
60+
function(features) {
61+
return {
62+
site_id: bidRequest.params.siteId,
63+
placement: bidRequest.params.placementId,
64+
pagetype: bidRequest.params.pagetypeId,
65+
categories: bidRequest.params.categories
66+
};
67+
}
68+
);
69+
return rawFeatures;
70+
}
71+
72+
function _getGdprConsent(bidderRequest) {
73+
const consent = {};
74+
if (utils.deepAccess(bidderRequest, 'gdprConsent')) {
75+
if (bidderRequest.gdprConsent.consentString !== undefined) {
76+
consent.consentString = bidderRequest.gdprConsent.consentString;
77+
}
78+
if (bidderRequest.gdprConsent.gdprApplies !== undefined) {
79+
consent.consentRequired = bidderRequest.gdprConsent.gdprApplies ? 1 : 0;
80+
}
81+
if (bidderRequest.gdprConsent.allowAuctionWithoutConsent !== undefined) {
82+
consent.allowAuctionWithoutConsent = bidderRequest.gdprConsent.allowAuctionWithoutConsent ? 1 : 0;
83+
}
84+
}
85+
return consent;
86+
}
87+
88+
export const spec = {
89+
code: BIDDER_CODE,
90+
91+
supportedMediaType: SUPPORTED_MEDIA_TYPES,
92+
93+
isBidRequestValid: function(bid) {
94+
return !!(bid.params.siteId && bid.params.placementId);
95+
},
96+
97+
buildRequests: function(validBidRequests, bidderRequest) {
98+
const secure = (location.protocol === 'https:') ? 1 : 0;
99+
const device = _getDevice();
100+
const site = _getSite();
101+
const pageviewId = _getPageviewId();
102+
const gdprConsent = _getGdprConsent(bidderRequest);
103+
const adUnits = utils._map(validBidRequests, (bidRequest) => {
104+
bidRequest.params.features = _getFeatures(bidRequest);
105+
const categories = bidRequest.params.categories;
106+
if (typeof categories !== 'undefined' && !Array.isArray(categories)) {
107+
bidRequest.params.categories = [categories];
108+
}
109+
return bidRequest;
110+
});
111+
112+
// Regroug ad units by siteId
113+
const groupedAdUnits = adUnits.reduce((groupedAdUnits, adUnit) => {
114+
(groupedAdUnits[adUnit.params.siteId] = groupedAdUnits[adUnit.params.siteId] || []).push(adUnit);
115+
return groupedAdUnits;
116+
}, {});
117+
118+
// Build one request per siteId
119+
const requests = utils._map(Object.keys(groupedAdUnits), (siteId) => {
120+
return {
121+
method: 'POST',
122+
url: ENDPOINT,
123+
data: {
124+
id: utils.generateUUID(),
125+
secure: secure,
126+
device: device,
127+
site: site,
128+
siteId: siteId,
129+
pageviewId: pageviewId,
130+
adUnits: groupedAdUnits[siteId],
131+
gdpr: gdprConsent,
132+
adapterVersion: VERSION
133+
},
134+
options: {
135+
contentType: 'application/json'
136+
}
137+
}
138+
});
139+
140+
return requests;
141+
},
142+
143+
interpretResponse: function(serverResponse, bidRequest) {
144+
let bidResponses = [];
145+
try {
146+
const response = serverResponse.body;
147+
if (response) {
148+
response.bids.forEach(bidObj => {
149+
const bidReq = (find(bidRequest.data.adUnits, bid => bid.bidId === bidObj.requestId));
150+
if (bidReq) {
151+
bidObj.placementId = bidReq.params.placementId;
152+
bidObj.pagetypeId = bidReq.params.pagetypeId;
153+
bidObj.categories = (bidReq.params.features && bidReq.params.features.categories) ? bidReq.params.features.categories : [];
154+
}
155+
bidResponses.push(bidObj);
156+
});
157+
}
158+
} catch (err) {
159+
utils.logError(err);
160+
}
161+
return bidResponses;
162+
},
163+
164+
getUserSyncs: function(syncOptions, serverResponses) {
165+
if (!serverResponses.length || serverResponses[0].body === '' || !serverResponses[0].body.userSyncs) {
166+
return false;
167+
}
168+
const syncs = serverResponses[0].body.userSyncs.map((sync) => {
169+
return {
170+
type: sync.t === 'p' ? 'image' : 'iframe',
171+
url: sync.u
172+
}
173+
})
174+
return syncs;
175+
}
176+
}
177+
178+
registerBidder(spec);

modules/adagioBidAdapter.md

Lines changed: 60 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,60 @@
1+
# Overview
2+
3+
Module Name: Adagio Bid Adapter
4+
Module Type: Adagio Adapter
5+
Maintainer: [email protected]
6+
7+
## Description
8+
9+
Connects to Adagio demand source to fetch bids.
10+
11+
## Test Parameters
12+
13+
```javascript
14+
var adUnits = [
15+
{
16+
code: 'ad-unit_code',
17+
sizes: [[300, 250], [300, 600]],
18+
bids: [
19+
{
20+
bidder: 'adagio', // Required
21+
params: {
22+
siteId: '0', // Required - Site ID from Adagio.
23+
placementId: '4', // Required - Placement ID from Adagio. Refers to the placement of an ad unit in a page.
24+
pagetypeId: '343', // Required - Page type ID from Adagio.
25+
categories: ['IAB12', 'IAB12-2'], // IAB categories of the page.
26+
}
27+
}
28+
]
29+
}
30+
];
31+
32+
pbjs.addAdUnits(adUnits);
33+
34+
pbjs.bidderSettings = {
35+
adagio: {
36+
alwaysUseBid: true,
37+
adserverTargeting: [
38+
{
39+
key: "placement",
40+
val: function (bidResponse) {
41+
return bidResponse.placementId;
42+
}
43+
},
44+
{
45+
key: "pagetype",
46+
val: function (bidResponse) {
47+
return bidResponse.pagetypeId;
48+
}
49+
},
50+
{
51+
key: "categories",
52+
val: function (bidResponse) {
53+
return bidResponse.categories.join(",");
54+
}
55+
}
56+
]
57+
}
58+
}
59+
60+
```

0 commit comments

Comments
 (0)