forked from prebid/Prebid.js
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathexperianRtdProvider.js
141 lines (132 loc) · 5.59 KB
/
experianRtdProvider.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
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
import { submodule } from '../src/hook.js';
import { getStorageManager } from '../src/storageManager.js';
import { MODULE_TYPE_RTD } from '../src/activities/modules.js';
import {
deepAccess,
isArray,
isPlainObject,
isStr,
mergeDeep,
safeJSONParse,
timestamp
} from '../src/utils.js';
import { ajax } from '../src/ajax.js';
/**
* @typedef {import('../modules/rtdModule/index.js').RtdSubmodule} RtdSubmodule
* @typedef {import('../modules/rtdModule/index.js').SubmoduleConfig} SubmoduleConfig
* @typedef {import('../modules/rtdModule/index.js').UserConsentData} UserConsentData
*/
export const SUBMODULE_NAME = 'experian_rtid';
export const EXPERIAN_RTID_DATA_KEY = 'experian_rtid_data';
export const EXPERIAN_RTID_EXPIRATION_KEY = 'experian_rtid_expiration';
export const EXPERIAN_RTID_STALE_KEY = 'experian_rtid_stale';
export const EXPERIAN_RTID_NO_TRACK_KEY = 'experian_rtid_no_track';
const EXPERIAN_RTID_URL = 'https://rtid.tapad.com'
const storage = getStorageManager({ moduleType: MODULE_TYPE_RTD, moduleName: SUBMODULE_NAME });
export const experianRtdObj = {
/**
* @summary modify bid request data
* @param {Object} reqBidsConfigObj
* @param {function} done
* @param {SubmoduleConfig} config
* @param {UserConsentData} userConsent
*/
getBidRequestData(reqBidsConfigObj, done, config, userConsent) {
const dataEnvelope = storage.getDataFromLocalStorage(EXPERIAN_RTID_DATA_KEY, null);
const stale = storage.getDataFromLocalStorage(EXPERIAN_RTID_STALE_KEY, null);
const expired = storage.getDataFromLocalStorage(EXPERIAN_RTID_EXPIRATION_KEY, null);
const noTrack = storage.getDataFromLocalStorage(EXPERIAN_RTID_NO_TRACK_KEY, null);
const now = timestamp()
if (now > new Date(expired).getTime() || (noTrack == null && dataEnvelope == null)) {
// request data envelope and don't manipulate bids
experianRtdObj.requestDataEnvelope(config, userConsent)
done();
return false;
}
if (now > new Date(stale).getTime()) {
// request data envelope and manipulate bids
experianRtdObj.requestDataEnvelope(config, userConsent);
}
if (noTrack != null) {
done();
return false;
}
experianRtdObj.alterBids(reqBidsConfigObj, config);
done()
return true;
},
alterBids(reqBidsConfigObj, config) {
const dataEnvelope = safeJSONParse(storage.getDataFromLocalStorage(EXPERIAN_RTID_DATA_KEY, null));
if (dataEnvelope == null) {
return;
}
deepAccess(config, 'params.bidders').forEach((bidderCode) => {
const bidderData = dataEnvelope.find(({ bidder }) => bidder === bidderCode)
if (bidderData != null) {
mergeDeep(reqBidsConfigObj.ortb2Fragments.bidder, { [bidderCode]: { experianRtidKey: bidderData.data.key, experianRtidData: bidderData.data.data } })
}
})
},
requestDataEnvelope(config, userConsent) {
function storeDataEnvelopeResponse(response) {
const responseJson = safeJSONParse(response);
if (responseJson != null) {
storage.setDataInLocalStorage(EXPERIAN_RTID_STALE_KEY, responseJson.staleAt, null);
storage.setDataInLocalStorage(EXPERIAN_RTID_EXPIRATION_KEY, responseJson.expiresAt, null);
if (responseJson.status === 'no_track') {
storage.setDataInLocalStorage(EXPERIAN_RTID_NO_TRACK_KEY, 'no_track', null);
storage.removeDataFromLocalStorage(EXPERIAN_RTID_DATA_KEY, null);
} else {
storage.setDataInLocalStorage(EXPERIAN_RTID_DATA_KEY, JSON.stringify(responseJson.data), null);
storage.removeDataFromLocalStorage(EXPERIAN_RTID_NO_TRACK_KEY, null);
}
}
}
const queryString = experianRtdObj.extractConsentQueryString(config, userConsent)
const fullUrl = queryString == null ? `${EXPERIAN_RTID_URL}/acc/${deepAccess(config, 'params.accountId')}/ids` : `${EXPERIAN_RTID_URL}/acc/${deepAccess(config, 'params.accountId')}/ids${queryString}`
ajax(fullUrl, storeDataEnvelopeResponse, null, { withCredentials: true, contentType: 'application/json' })
},
extractConsentQueryString(config, userConsent) {
const queryObj = {};
if (userConsent != null) {
if (userConsent.gdpr != null) {
const { gdprApplies, consentString } = userConsent.gdpr;
mergeDeep(queryObj, {gdpr: gdprApplies, gdpr_consent: consentString})
}
if (userConsent.uspConsent != null) {
mergeDeep(queryObj, {us_privacy: userConsent.uspConsent})
}
}
const consentQueryString = Object.entries(queryObj).map(([key, val]) => `${key}=${val}`).join('&');
let idsString = '';
if (deepAccess(config, 'params.ids') != null && isPlainObject(deepAccess(config, 'params.ids'))) {
idsString = Object.entries(deepAccess(config, 'params.ids')).map(([idType, val]) => {
if (isArray(val)) {
return val.map((singleVal) => `id.${idType}=${singleVal}`).join('&')
} else {
return `id.${idType}=${val}`
}
}).join('&')
}
const combinedString = [consentQueryString, idsString].filter((string) => string !== '').join('&');
return combinedString !== '' ? `?${combinedString}` : undefined;
},
/**
* @function
* @summary init sub module
* @name RtdSubmodule#init
* @param {SubmoduleConfig} config
* @param {UserConsentData} userConsent
* @return {boolean} false to remove sub module
*/
init(config, userConsent) {
return isStr(deepAccess(config, 'params.accountId'));
}
}
/** @type {RtdSubmodule} */
export const experianRtdSubmodule = {
name: SUBMODULE_NAME,
getBidRequestData: experianRtdObj.getBidRequestData,
init: experianRtdObj.init
}
submodule('realTimeData', experianRtdSubmodule);