/
pangleBidAdapter.js
110 lines (94 loc) · 3.12 KB
/
pangleBidAdapter.js
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
// ver V1.0.3
import { BANNER } from '../src/mediaTypes.js';
import { ortbConverter } from '../libraries/ortbConverter/converter.js'
import { registerBidder } from '../src/adapters/bidderFactory.js';
import { deepSetValue, generateUUID, timestamp } from '../src/utils.js';
import { getStorageManager } from '../src/storageManager.js';
import { MODULE_TYPE_RTD } from '../src/activities/modules.js';
const BIDDER_CODE = 'pangle';
const ENDPOINT = 'https://pangle.pangleglobal.com/api/ad/union/web_js/common/get_ads';
const DEFAULT_BID_TTL = 30;
const DEFAULT_CURRENCY = 'USD';
const DEFAULT_NET_REVENUE = true;
const PANGLE_COOKIE = '_pangle_id';
const COOKIE_EXP = 86400 * 1000 * 365 * 1; // 1 year
export const storage = getStorageManager({ moduleType: MODULE_TYPE_RTD, moduleName: BIDDER_CODE })
export function isValidUuid(uuid) {
return /^[0-9a-f]{8}-[0-9a-f]{4}-[1-5][0-9a-f]{3}-[89ab][0-9a-f]{3}-[0-9a-f]{12}$/i.test(
uuid
);
}
function getPangleCookieId() {
let sid = storage.cookiesAreEnabled() && storage.getCookie(PANGLE_COOKIE);
if (
!sid || !isValidUuid(sid)
) {
sid = generateUUID();
setPangleCookieId(sid);
}
return sid;
}
function setPangleCookieId(sid) {
if (storage.cookiesAreEnabled()) {
const expires = (new Date(timestamp() + COOKIE_EXP)).toGMTString();
storage.setCookie(PANGLE_COOKIE, sid, expires);
}
}
const converter = ortbConverter({
context: {
netRevenue: DEFAULT_NET_REVENUE,
ttl: DEFAULT_BID_TTL,
currency: DEFAULT_CURRENCY,
mediaType: BANNER
}
});
export const spec = {
code: BIDDER_CODE,
supportedMediaTypes: [BANNER],
getDeviceType: function (ua) {
if ((/ipad|android 3.0|xoom|sch-i800|playbook|tablet|kindle/i.test(ua.toLowerCase()))) {
return 5; // 'tablet'
}
if ((/iphone|ipod|android|blackberry|opera|mini|windows\sce|palm|smartphone|iemobile/i.test(ua.toLowerCase()))) {
return 4; // 'mobile'
}
return 2; // 'desktop'
},
isBidRequestValid: function (bid) {
return Boolean(bid.params.token);
},
buildRequests(bidRequests, bidderRequest) {
const data = converter.toORTB({ bidRequests, bidderRequest })
const devicetype = spec.getDeviceType(navigator.userAgent);
deepSetValue(data, 'device.devicetype', devicetype);
if (bidderRequest.userId && typeof bidderRequest.userId === 'object') {
const pangleId = getPangleCookieId();
// add pangle cookie
const _eids = data.user?.ext?.eids ?? []
deepSetValue(data, 'user.ext.eids', [..._eids, {
source: document.location.host,
uids: [
{
id: pangleId,
atype: 1
}
]
}]);
}
bidRequests.forEach((item, idx) => {
deepSetValue(data.imp[idx], 'ext.networkids', item.params);
deepSetValue(data.imp[idx], 'banner.api', [5]);
});
return [{
method: 'POST',
url: ENDPOINT,
data,
options: { contentType: 'application/json', withCredentials: true }
}]
},
interpretResponse(response, request) {
const bids = converter.fromORTB({ response: response.body, request: request.data }).bids;
return bids;
},
};
registerBidder(spec);