1
- import { deepAccess , isArray , logError } from '../src/utils.js' ;
1
+ import { deepAccess , mergeDeep , isArray , logError , logInfo } from '../src/utils.js' ;
2
2
import { getOrigin } from '../libraries/getOrigin/index.js' ;
3
3
import { BANNER , NATIVE } from '../src/mediaTypes.js' ;
4
4
import { registerBidder } from '../src/adapters/bidderFactory.js' ;
5
5
import { includes } from '../src/polyfill.js' ;
6
6
import { convertOrtbRequestToProprietaryNative } from '../src/native.js' ;
7
+ import { config } from '../src/config.js' ;
7
8
8
9
const BIDDER_CODE = 'rtbhouse' ;
9
10
const REGIONS = [ 'prebid-eu' , 'prebid-us' , 'prebid-asia' ] ;
10
11
const ENDPOINT_URL = 'creativecdn.com/bidder/prebid/bids' ;
12
+ const FLEDGE_ENDPOINT_URL = 'creativecdn.com/bidder/prebidfledge/bids' ;
11
13
const DEFAULT_CURRENCY_ARR = [ 'USD' ] ; // NOTE - USD is the only supported currency right now; Hardcoded for bids
12
14
const SUPPORTED_MEDIA_TYPES = [ BANNER , NATIVE ] ;
13
15
const TTL = 55 ;
@@ -50,12 +52,13 @@ export const spec = {
50
52
51
53
const request = {
52
54
id : validBidRequests [ 0 ] . auctionId ,
53
- imp : validBidRequests . map ( slot => mapImpression ( slot ) ) ,
55
+ imp : validBidRequests . map ( slot => mapImpression ( slot , bidderRequest ) ) ,
54
56
site : mapSite ( validBidRequests , bidderRequest ) ,
55
57
cur : DEFAULT_CURRENCY_ARR ,
56
58
test : validBidRequests [ 0 ] . params . test || 0 ,
57
59
source : mapSource ( validBidRequests [ 0 ] ) ,
58
60
} ;
61
+
59
62
if ( bidderRequest && bidderRequest . gdprConsent && bidderRequest . gdprConsent . gdprApplies ) {
60
63
const consentStr = ( bidderRequest . gdprConsent . consentString )
61
64
? bidderRequest . gdprConsent . consentString . replace ( / \+ / g, '-' ) . replace ( / \/ / g, '_' ) . replace ( / = + $ / , '' ) : '' ;
@@ -81,55 +84,105 @@ export const spec = {
81
84
}
82
85
}
83
86
84
- const ortb2Params = bidderRequest && bidderRequest . ortb2 ;
85
- if ( ortb2Params ?. user ) {
86
- request . user = {
87
- ...request . user ,
88
- ...( ortb2Params . user . data && {
89
- data : { ...request . user ?. data , ...ortb2Params . user . data } ,
90
- } ) ,
91
- ...( ortb2Params . user . ext && {
92
- ext : { ...request . user ?. ext , ...ortb2Params . user . ext } ,
93
- } ) ,
94
- } ;
87
+ const ortb2Params = bidderRequest ?. ortb2 || { } ;
88
+ if ( ortb2Params . site ) {
89
+ mergeDeep ( request , { site : ortb2Params . site } ) ;
90
+ }
91
+ if ( ortb2Params . user ) {
92
+ mergeDeep ( request , { user : ortb2Params . user } ) ;
93
+ }
94
+ if ( ortb2Params . device ) {
95
+ mergeDeep ( request , { device : ortb2Params . device } ) ;
95
96
}
96
- if ( ortb2Params ?. site ) {
97
- request . site = {
98
- ...request . site ,
99
- ...( ortb2Params . site . content && {
100
- content : { ...request . site ?. content , ...ortb2Params . site . content } ,
101
- } ) ,
102
- ...( ortb2Params . site . ext && {
103
- ext : { ...request . site ?. ext , ...ortb2Params . site . ext } ,
104
- } ) ,
105
- } ;
97
+
98
+ let computedEndpointUrl = ENDPOINT_URL ;
99
+
100
+ const fledgeConfig = config . getConfig ( 'fledgeConfig' ) ;
101
+ if ( bidderRequest . fledgeEnabled && fledgeConfig ) {
102
+ mergeDeep ( request , { ext : { fledge_config : fledgeConfig } } ) ;
103
+ computedEndpointUrl = FLEDGE_ENDPOINT_URL ;
106
104
}
107
105
108
106
return {
109
107
method : 'POST' ,
110
- url : 'https://' + validBidRequests [ 0 ] . params . region + '.' + ENDPOINT_URL ,
108
+ url : 'https://' + validBidRequests [ 0 ] . params . region + '.' + computedEndpointUrl ,
111
109
data : JSON . stringify ( request )
112
110
} ;
113
111
} ,
114
- interpretResponse : function ( serverResponse , originalRequest ) {
112
+ interpretOrtbResponse : function ( serverResponse , originalRequest ) {
115
113
const responseBody = serverResponse . body ;
116
114
if ( ! isArray ( responseBody ) ) {
117
115
return [ ] ;
118
116
}
119
117
120
118
const bids = [ ] ;
121
119
responseBody . forEach ( serverBid => {
122
- if ( serverBid . price === 0 ) {
120
+ if ( ! serverBid . price ) { // price may exist and is === 0 or there's no price prop at all (fledge req case)
123
121
return ;
124
122
}
123
+
124
+ let interpretedBid ;
125
+
125
126
// try...catch would be risky cause JSON.parse throws SyntaxError
126
127
if ( serverBid . adm . indexOf ( '{' ) === 0 ) {
127
- bids . push ( interpretNativeBid ( serverBid ) ) ;
128
+ interpretedBid = interpretNativeBid ( serverBid ) ;
128
129
} else {
129
- bids . push ( interpretBannerBid ( serverBid ) ) ;
130
+ interpretedBid = interpretBannerBid ( serverBid ) ;
130
131
}
132
+ if ( serverBid . ext ) interpretedBid . ext = serverBid . ext ;
133
+
134
+ bids . push ( interpretedBid ) ;
131
135
} ) ;
132
136
return bids ;
137
+ } ,
138
+ interpretResponse : function ( serverResponse , originalRequest ) {
139
+ let bids ;
140
+
141
+ const responseBody = serverResponse . body ;
142
+ let fledgeAuctionConfigs = null ;
143
+
144
+ if ( responseBody . bidid && isArray ( responseBody ?. ext ?. igbid ) ) {
145
+ // we have fledge response
146
+ // mimic the original response ([{},...])
147
+ bids = this . interpretOrtbResponse ( { body : responseBody . seatbid [ 0 ] ?. bid } , originalRequest ) ;
148
+
149
+ const seller = responseBody . ext . seller ;
150
+ const decisionLogicUrl = responseBody . ext . decisionLogicUrl ;
151
+ const sellerTimeout = 'sellerTimeout' in responseBody . ext ? { sellerTimeout : responseBody . ext . sellerTimeout } : { } ;
152
+ responseBody . ext . igbid . forEach ( ( igbid ) => {
153
+ const perBuyerSignals = { } ;
154
+ igbid . igbuyer . forEach ( buyerItem => {
155
+ perBuyerSignals [ buyerItem . igdomain ] = buyerItem . buyersignal
156
+ } ) ;
157
+ fledgeAuctionConfigs = fledgeAuctionConfigs || { } ;
158
+ fledgeAuctionConfigs [ igbid . impid ] = mergeDeep (
159
+ {
160
+ seller,
161
+ decisionLogicUrl,
162
+ interestGroupBuyers : Object . keys ( perBuyerSignals ) ,
163
+ perBuyerSignals,
164
+ } ,
165
+ sellerTimeout
166
+ ) ;
167
+ } ) ;
168
+ } else {
169
+ bids = this . interpretOrtbResponse ( serverResponse , originalRequest ) ;
170
+ }
171
+
172
+ if ( fledgeAuctionConfigs ) {
173
+ fledgeAuctionConfigs = Object . entries ( fledgeAuctionConfigs ) . map ( ( [ bidId , cfg ] ) => {
174
+ return Object . assign ( {
175
+ bidId,
176
+ auctionSignals : { }
177
+ } , cfg ) ;
178
+ } ) ;
179
+ logInfo ( 'Response with FLEDGE:' , { bids, fledgeAuctionConfigs } ) ;
180
+ return {
181
+ bids,
182
+ fledgeAuctionConfigs,
183
+ }
184
+ }
185
+ return bids ;
133
186
}
134
187
} ;
135
188
registerBidder ( spec ) ;
@@ -154,7 +207,7 @@ function applyFloor(slot) {
154
207
* @param {object } slot Ad Unit Params by Prebid
155
208
* @returns {object } Imp by OpenRTB 2.5 §3.2.4
156
209
*/
157
- function mapImpression ( slot ) {
210
+ function mapImpression ( slot , bidderRequest ) {
158
211
const imp = {
159
212
id : slot . bidId ,
160
213
banner : mapBanner ( slot ) ,
@@ -167,6 +220,14 @@ function mapImpression(slot) {
167
220
imp . bidfloor = bidfloor ;
168
221
}
169
222
223
+ if ( bidderRequest . fledgeEnabled ) {
224
+ imp . ext = imp . ext || { } ;
225
+ imp . ext . ae = slot ?. ortb2Imp ?. ext ?. ae
226
+ } else {
227
+ if ( imp . ext ?. ae ) {
228
+ delete imp . ext . ae ;
229
+ }
230
+ }
170
231
return imp ;
171
232
}
172
233
0 commit comments