Skip to content

Commit 112d2aa

Browse files
authored
Revert "Prebid 8: Delete adgeneration (#9904)" (#9915)
This reverts commit ce984b3.
1 parent 3fad13e commit 112d2aa

File tree

3 files changed

+1374
-0
lines changed

3 files changed

+1374
-0
lines changed

modules/adgenerationBidAdapter.js

Lines changed: 315 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,315 @@
1+
import {tryAppendQueryString, getBidIdParameter, escapeUnsafeChars} from '../src/utils.js';
2+
import {registerBidder} from '../src/adapters/bidderFactory.js';
3+
import {BANNER, NATIVE} from '../src/mediaTypes.js';
4+
import {config} from '../src/config.js';
5+
import { convertOrtbRequestToProprietaryNative } from '../src/native.js';
6+
7+
const ADG_BIDDER_CODE = 'adgeneration';
8+
9+
export const spec = {
10+
code: ADG_BIDDER_CODE,
11+
aliases: ['adg'], // short code
12+
supportedMediaTypes: [BANNER, NATIVE],
13+
/**
14+
* Determines whether or not the given bid request is valid.
15+
*
16+
* @param {BidRequest} bid The bid params to validate.
17+
* @return boolean True if this is a valid bid, and false otherwise.
18+
*/
19+
isBidRequestValid: function (bid) {
20+
return !!(bid.params.id);
21+
},
22+
/**
23+
* Make a server request from the list of BidRequests.
24+
*
25+
* @param {validBidRequests[]} - an array of bids
26+
* @return ServerRequest Info describing the request to the server.
27+
*/
28+
buildRequests: function (validBidRequests, bidderRequest) {
29+
// convert Native ORTB definition to old-style prebid native definition
30+
validBidRequests = convertOrtbRequestToProprietaryNative(validBidRequests);
31+
const ADGENE_PREBID_VERSION = '1.4.0';
32+
let serverRequests = [];
33+
for (let i = 0, len = validBidRequests.length; i < len; i++) {
34+
const validReq = validBidRequests[i];
35+
const DEBUG_URL = 'https://api-test.scaleout.jp/adsv/v1';
36+
const URL = 'https://d.socdm.com/adsv/v1';
37+
const url = validReq.params.debug ? DEBUG_URL : URL;
38+
const criteoId = getCriteoId(validReq);
39+
const id5id = getId5Id(validReq);
40+
const id5LinkType = getId5LinkType(validReq);
41+
let data = ``;
42+
data = tryAppendQueryString(data, 'posall', 'SSPLOC');
43+
const id = getBidIdParameter('id', validReq.params);
44+
data = tryAppendQueryString(data, 'id', id);
45+
data = tryAppendQueryString(data, 'sdktype', '0');
46+
data = tryAppendQueryString(data, 'hb', 'true');
47+
data = tryAppendQueryString(data, 't', 'json3');
48+
data = tryAppendQueryString(data, 'transactionid', validReq.transactionId);
49+
data = tryAppendQueryString(data, 'sizes', getSizes(validReq));
50+
data = tryAppendQueryString(data, 'currency', getCurrencyType());
51+
data = tryAppendQueryString(data, 'pbver', '$prebid.version$');
52+
data = tryAppendQueryString(data, 'sdkname', 'prebidjs');
53+
data = tryAppendQueryString(data, 'adapterver', ADGENE_PREBID_VERSION);
54+
data = tryAppendQueryString(data, 'adgext_criteo_id', criteoId);
55+
data = tryAppendQueryString(data, 'adgext_id5_id', id5id);
56+
data = tryAppendQueryString(data, 'adgext_id5_id_link_type', id5LinkType);
57+
// native以外にvideo等の対応が入った場合は要修正
58+
if (!validReq.mediaTypes || !validReq.mediaTypes.native) {
59+
data = tryAppendQueryString(data, 'imark', '1');
60+
}
61+
62+
// TODO: is 'page' the right value here?
63+
data = tryAppendQueryString(data, 'tp', bidderRequest.refererInfo.page);
64+
if (isIos()) {
65+
const hyperId = getHyperId(validReq);
66+
if (hyperId != null) {
67+
data = tryAppendQueryString(data, 'hyper_id', hyperId);
68+
}
69+
}
70+
// remove the trailing "&"
71+
if (data.lastIndexOf('&') === data.length - 1) {
72+
data = data.substring(0, data.length - 1);
73+
}
74+
serverRequests.push({
75+
method: 'GET',
76+
url: url,
77+
data: data,
78+
bidRequest: validBidRequests[i]
79+
});
80+
}
81+
return serverRequests;
82+
},
83+
/**
84+
* Unpack the response from the server into a list of bids.
85+
*
86+
* @param {ServerResponse} serverResponse A successful response from the server.
87+
* @param {BidRequest} bidRequests
88+
* @return {Bid[]} An array of bids which were nested inside the server.
89+
*/
90+
interpretResponse: function (serverResponse, bidRequests) {
91+
const body = serverResponse.body;
92+
if (!body.results || body.results.length < 1) {
93+
return [];
94+
}
95+
const bidRequest = bidRequests.bidRequest;
96+
const bidResponse = {
97+
requestId: bidRequest.bidId,
98+
cpm: body.cpm || 0,
99+
width: body.w ? body.w : 1,
100+
height: body.h ? body.h : 1,
101+
creativeId: body.creativeid || '',
102+
dealId: body.dealid || '',
103+
currency: getCurrencyType(),
104+
netRevenue: true,
105+
ttl: body.ttl || 10,
106+
};
107+
if (body.adomain && Array.isArray(body.adomain) && body.adomain.length) {
108+
bidResponse.meta = {
109+
advertiserDomains: body.adomain
110+
}
111+
}
112+
if (isNative(body)) {
113+
bidResponse.native = createNativeAd(body);
114+
bidResponse.mediaType = NATIVE;
115+
} else {
116+
// banner
117+
bidResponse.ad = createAd(body, bidRequest);
118+
}
119+
return [bidResponse];
120+
},
121+
122+
/**
123+
* Register the user sync pixels which should be dropped after the auction.
124+
*
125+
* @param {SyncOptions} syncOptions Which user syncs are allowed?
126+
* @param {ServerResponse[]} serverResponses List of server's responses.
127+
* @return {UserSync[]} The user syncs which should be dropped.
128+
*/
129+
getUserSyncs: function (syncOptions, serverResponses) {
130+
const syncs = [];
131+
return syncs;
132+
}
133+
};
134+
135+
function createAd(body, bidRequest) {
136+
let ad = body.ad;
137+
if (body.vastxml && body.vastxml.length > 0) {
138+
if (isUpperBillboard(body)) {
139+
const marginTop = bidRequest.params.marginTop ? bidRequest.params.marginTop : '0';
140+
ad = `<body>${createADGBrowserMTag()}${insertVASTMethodForADGBrowserM(body.vastxml, marginTop)}</body>`;
141+
} else {
142+
ad = `<body><div id="apvad-${bidRequest.bidId}"></div>${createAPVTag()}${insertVASTMethodForAPV(bidRequest.bidId, body.vastxml)}</body>`;
143+
}
144+
}
145+
ad = appendChildToBody(ad, body.beacon);
146+
if (removeWrapper(ad)) return removeWrapper(ad);
147+
return ad;
148+
}
149+
150+
function isUpperBillboard(body) {
151+
if (body.location_params && body.location_params.option && body.location_params.option.ad_type) {
152+
return body.location_params.option.ad_type === 'upper_billboard';
153+
}
154+
return false;
155+
}
156+
157+
function isNative(body) {
158+
if (!body) return false;
159+
return body.native_ad && body.native_ad.assets.length > 0;
160+
}
161+
162+
function createNativeAd(body) {
163+
let native = {};
164+
if (body.native_ad && body.native_ad.assets.length > 0) {
165+
const assets = body.native_ad.assets;
166+
for (let i = 0, len = assets.length; i < len; i++) {
167+
switch (assets[i].id) {
168+
case 1:
169+
native.title = assets[i].title.text;
170+
break;
171+
case 2:
172+
native.image = {
173+
url: assets[i].img.url,
174+
height: assets[i].img.h,
175+
width: assets[i].img.w,
176+
};
177+
break;
178+
case 3:
179+
native.icon = {
180+
url: assets[i].img.url,
181+
height: assets[i].img.h,
182+
width: assets[i].img.w,
183+
};
184+
break;
185+
case 4:
186+
native.sponsoredBy = assets[i].data.value;
187+
break;
188+
case 5:
189+
native.body = assets[i].data.value;
190+
break;
191+
case 6:
192+
native.cta = assets[i].data.value;
193+
break;
194+
case 502:
195+
native.privacyLink = encodeURIComponent(assets[i].data.value);
196+
break;
197+
}
198+
}
199+
native.clickUrl = body.native_ad.link.url;
200+
native.clickTrackers = body.native_ad.link.clicktrackers || [];
201+
native.impressionTrackers = body.native_ad.imptrackers || [];
202+
if (body.beaconurl && body.beaconurl != '') {
203+
native.impressionTrackers.push(body.beaconurl);
204+
}
205+
}
206+
return native;
207+
}
208+
209+
function appendChildToBody(ad, data) {
210+
return ad.replace(/<\/\s?body>/, `${data}</body>`);
211+
}
212+
213+
function createAPVTag() {
214+
const APVURL = 'https://cdn.apvdr.com/js/VideoAd.min.js';
215+
let apvScript = document.createElement('script');
216+
apvScript.type = 'text/javascript';
217+
apvScript.id = 'apv';
218+
apvScript.src = APVURL;
219+
return apvScript.outerHTML;
220+
}
221+
222+
function createADGBrowserMTag() {
223+
const ADGBrowserMURL = 'https://i.socdm.com/sdk/js/adg-browser-m.js';
224+
return `<script type="text/javascript" src="${ADGBrowserMURL}"></script>`;
225+
}
226+
227+
function insertVASTMethodForAPV(targetId, vastXml) {
228+
let apvVideoAdParam = {
229+
s: targetId
230+
};
231+
let script = document.createElement(`script`);
232+
script.type = 'text/javascript';
233+
script.innerHTML = `(function(){ new APV.VideoAd(${escapeUnsafeChars(JSON.stringify(apvVideoAdParam))}).load('${vastXml.replace(/\r?\n/g, '')}'); })();`;
234+
return script.outerHTML;
235+
}
236+
237+
function insertVASTMethodForADGBrowserM(vastXml, marginTop) {
238+
const script = document.createElement(`script`);
239+
script.type = 'text/javascript';
240+
script.innerHTML = `window.ADGBrowserM.init({vastXml: '${vastXml.replace(/\r?\n/g, '')}', marginTop: '${marginTop}'});`;
241+
return script.outerHTML;
242+
}
243+
244+
/**
245+
*
246+
* @param ad
247+
*/
248+
function removeWrapper(ad) {
249+
const bodyIndex = ad.indexOf('<body>');
250+
const lastBodyIndex = ad.lastIndexOf('</body>');
251+
if (bodyIndex === -1 || lastBodyIndex === -1) return false;
252+
return ad.substr(bodyIndex, lastBodyIndex).replace('<body>', '').replace('</body>', '');
253+
}
254+
255+
/**
256+
* request
257+
* @param validReq request
258+
* @returns {?string} 300x250,320x50...
259+
*/
260+
function getSizes(validReq) {
261+
const sizes = validReq.sizes;
262+
if (!sizes || sizes.length < 1) return null;
263+
let sizesStr = '';
264+
for (const i in sizes) {
265+
const size = sizes[i];
266+
if (size.length !== 2) return null;
267+
sizesStr += `${size[0]}x${size[1]},`;
268+
}
269+
if (sizesStr || sizesStr.lastIndexOf(',') === sizesStr.length - 1) {
270+
sizesStr = sizesStr.substring(0, sizesStr.length - 1);
271+
}
272+
return sizesStr;
273+
}
274+
275+
/**
276+
* @return {?string} USD or JPY
277+
*/
278+
function getCurrencyType() {
279+
if (config.getConfig('currency.adServerCurrency') && config.getConfig('currency.adServerCurrency').toUpperCase() === 'USD') return 'USD';
280+
return 'JPY';
281+
}
282+
283+
/**
284+
*
285+
* @param validReq request
286+
* @return {null|string}
287+
*/
288+
function getCriteoId(validReq) {
289+
return (validReq.userId && validReq.userId.criteoId) ? validReq.userId.criteoId : null
290+
}
291+
292+
function getId5Id(validReq) {
293+
return validId5(validReq) ? validReq.userId.id5id.uid : null
294+
}
295+
296+
function getId5LinkType(validReq) {
297+
return validId5(validReq) ? validReq.userId.id5id.ext.linkType : null
298+
}
299+
300+
function validId5(validReq) {
301+
return validReq.userId && validReq.userId.id5id && validReq.userId.id5id.uid && validReq.userId.id5id.ext.linkType
302+
}
303+
304+
function getHyperId(validReq) {
305+
if (validReq.userId && validReq.userId.novatiq && validReq.userId.novatiq.snowflake.syncResponse === 1) {
306+
return validReq.userId.novatiq.snowflake.id;
307+
}
308+
return null;
309+
}
310+
311+
function isIos() {
312+
return (/(ios|ipod|ipad|iphone)/i).test(window.navigator.userAgent);
313+
}
314+
315+
registerBidder(spec);

modules/adgenerationBidAdapter.md

Lines changed: 75 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,75 @@
1+
# Overview
2+
3+
```
4+
Module Name: AdGeneration Bid Adapter
5+
Module Type: Bidder Adapter
6+
Maintainer: [email protected]
7+
```
8+
9+
# Description
10+
11+
Connects to AdGeneration exchange for bids.
12+
13+
AdGeneration bid adapter supports Banner and Native.
14+
15+
# Test Parameters
16+
```
17+
var adUnits = [
18+
// Banner adUnit
19+
{
20+
code: 'banner-div', // banner
21+
mediaTypes: {
22+
banner: {
23+
sizes: [[300, 250]],
24+
}
25+
},
26+
bids: [
27+
{
28+
bidder: 'adg',
29+
params: {
30+
id: '58278', // banner
31+
}
32+
},
33+
]
34+
},
35+
// Native adUnit
36+
{
37+
code: 'native-div',
38+
sizes: [[1,1]],
39+
mediaTypes: {
40+
native: {
41+
image: {
42+
required: true
43+
},
44+
title: {
45+
required: true,
46+
len: 80
47+
},
48+
sponsoredBy: {
49+
required: true
50+
},
51+
clickUrl: {
52+
required: true
53+
},
54+
body: {
55+
required: true
56+
},
57+
icon: {
58+
required: true
59+
},
60+
privacyLink: {
61+
required: true
62+
},
63+
},
64+
},
65+
bids: [
66+
{
67+
bidder: 'adg',
68+
params: {
69+
id: '58279', //native
70+
}
71+
},
72+
]
73+
},
74+
];
75+
```

0 commit comments

Comments
 (0)