@@ -254,46 +254,7 @@ export const spec = {
254
254
utils . deepSetValue ( data , 'source.ext.schain' , bidRequest . schain ) ;
255
255
}
256
256
257
- const siteData = Object . assign ( { } , bidRequest . params . inventory , config . getConfig ( 'fpd.context' ) ) ;
258
- const userData = Object . assign ( { } , bidRequest . params . visitor , config . getConfig ( 'fpd.user' ) ) ;
259
- if ( ! utils . isEmpty ( siteData ) || ! utils . isEmpty ( userData ) ) {
260
- const bidderData = {
261
- bidders : [ bidderRequest . bidderCode ] ,
262
- config : {
263
- fpd : { }
264
- }
265
- } ;
266
-
267
- if ( ! utils . isEmpty ( siteData ) ) {
268
- bidderData . config . fpd . site = siteData ;
269
- }
270
-
271
- if ( ! utils . isEmpty ( userData ) ) {
272
- bidderData . config . fpd . user = userData ;
273
- }
274
-
275
- utils . deepSetValue ( data , 'ext.prebid.bidderconfig.0' , bidderData ) ;
276
- }
277
-
278
- /**
279
- * Prebid AdSlot
280
- * @type {(string|undefined) }
281
- */
282
- const pbAdSlot = utils . deepAccess ( bidRequest , 'fpd.context.pbAdSlot' ) ;
283
- if ( typeof pbAdSlot === 'string' && pbAdSlot ) {
284
- utils . deepSetValue ( data . imp [ 0 ] . ext , 'context.data.pbadslot' , pbAdSlot ) ;
285
- }
286
-
287
- /**
288
- * Copy GAM AdUnit and Name to imp
289
- */
290
- [ 'name' , 'adSlot' ] . forEach ( name => {
291
- /** @type {(string|undefined) } */
292
- const value = utils . deepAccess ( bidRequest , `fpd.context.adserver.${ name } ` ) ;
293
- if ( typeof value === 'string' && value ) {
294
- utils . deepSetValue ( data . imp [ 0 ] . ext , `context.data.adserver.${ name . toLowerCase ( ) } ` , value ) ;
295
- }
296
- } ) ;
257
+ applyFPD ( bidRequest , VIDEO , data ) ;
297
258
298
259
// if storedAuctionResponse has been set, pass SRID
299
260
if ( bidRequest . storedAuctionResponse ) {
@@ -547,49 +508,7 @@ export const spec = {
547
508
data [ 'us_privacy' ] = encodeURIComponent ( bidderRequest . uspConsent ) ;
548
509
}
549
510
550
- // visitor properties
551
- const visitorData = Object . assign ( { } , params . visitor , config . getConfig ( 'fpd.user' ) ) ;
552
- Object . keys ( visitorData ) . forEach ( ( key ) => {
553
- if ( visitorData [ key ] != null && key !== 'keywords' ) {
554
- data [ `tg_v.${ key } ` ] = typeof visitorData [ key ] === 'object' && ! Array . isArray ( visitorData [ key ] )
555
- ? JSON . stringify ( visitorData [ key ] )
556
- : visitorData [ key ] . toString ( ) ; // initialize array;
557
- }
558
- } ) ;
559
-
560
- // inventory properties
561
- const inventoryData = Object . assign ( { } , params . inventory , config . getConfig ( 'fpd.context' ) ) ;
562
- Object . keys ( inventoryData ) . forEach ( ( key ) => {
563
- if ( inventoryData [ key ] != null && key !== 'keywords' ) {
564
- data [ `tg_i.${ key } ` ] = typeof inventoryData [ key ] === 'object' && ! Array . isArray ( inventoryData [ key ] )
565
- ? JSON . stringify ( inventoryData [ key ] )
566
- : inventoryData [ key ] . toString ( ) ;
567
- }
568
- } ) ;
569
-
570
- // keywords
571
- const keywords = ( params . keywords || [ ] ) . concat (
572
- utils . deepAccess ( config . getConfig ( 'fpd.user' ) , 'keywords' ) || [ ] ,
573
- utils . deepAccess ( config . getConfig ( 'fpd.context' ) , 'keywords' ) || [ ] ) ;
574
- data . kw = Array . isArray ( keywords ) && keywords . length ? keywords . join ( ',' ) : '' ;
575
-
576
- /**
577
- * Prebid AdSlot
578
- * @type {(string|undefined) }
579
- */
580
- const pbAdSlot = utils . deepAccess ( bidRequest , 'fpd.context.pbAdSlot' ) ;
581
- if ( typeof pbAdSlot === 'string' && pbAdSlot ) {
582
- data [ 'tg_i.pbadslot' ] = pbAdSlot . replace ( / ^ \/ + / , '' ) ;
583
- }
584
-
585
- /**
586
- * GAM Ad Unit
587
- * @type {(string|undefined) }
588
- */
589
- const gamAdUnit = utils . deepAccess ( bidRequest , 'fpd.context.adServer.adSlot' ) ;
590
- if ( typeof gamAdUnit === 'string' && gamAdUnit ) {
591
- data [ 'tg_i.dfp_ad_unit_code' ] = gamAdUnit . replace ( / ^ \/ + / , '' ) ;
592
- }
511
+ applyFPD ( bidRequest , BANNER , data ) ;
593
512
594
513
if ( config . getConfig ( 'coppa' ) === true ) {
595
514
data [ 'coppa' ] = 1 ;
@@ -949,6 +868,81 @@ function addVideoParameters(data, bidRequest) {
949
868
data . imp [ 0 ] . video . h = size [ 1 ]
950
869
}
951
870
871
+ function applyFPD ( bidRequest , mediaType , data ) {
872
+ const bidFpd = {
873
+ user : { ...bidRequest . params . visitor } ,
874
+ context : { ...bidRequest . params . inventory }
875
+ } ;
876
+
877
+ if ( bidRequest . params . keywords ) bidFpd . context . keywords = ( utils . isArray ( bidRequest . params . keywords ) ) ? bidRequest . params . keywords . join ( ',' ) : bidRequest . params . keywords ;
878
+
879
+ let fpd = utils . mergeDeep ( { } , config . getConfig ( 'fpd' ) || { } , bidRequest . fpd || { } , bidFpd ) ;
880
+
881
+ const map = { user : { banner : 'tg_v.' , code : 'user' } , context : { banner : 'tg_i.' , code : 'site' } , adserver : 'dfp_ad_unit_code' } ;
882
+ let obj = { } ;
883
+ let impData = { } ;
884
+ let keywords = [ ] ;
885
+ const validate = function ( prop , key ) {
886
+ if ( typeof prop === 'object' && ! Array . isArray ( prop ) ) {
887
+ utils . logWarn ( 'Rubicon: Filtered FPD key: ' , key , ': Expected value to be string, integer, or an array of strings/ints' ) ;
888
+ } else if ( typeof prop !== 'undefined' ) {
889
+ return ( Array . isArray ( prop ) ) ? prop . filter ( value => {
890
+ if ( typeof value !== 'object' && typeof value !== 'undefined' ) return value . toString ( ) ;
891
+
892
+ utils . logWarn ( 'Rubicon: Filtered value: ' , value , 'for key' , key , ': Expected value to be string, integer, or an array of strings/ints' ) ;
893
+ } ) . toString ( ) : prop . toString ( ) ;
894
+ }
895
+ } ;
896
+
897
+ Object . keys ( fpd ) . filter ( value => fpd [ value ] && map [ value ] && typeof fpd [ value ] === 'object' ) . forEach ( ( type ) => {
898
+ obj [ map [ type ] . code ] = Object . keys ( fpd [ type ] ) . filter ( value => typeof fpd [ type ] [ value ] !== 'undefined' ) . reduce ( ( result , key ) => {
899
+ if ( key === 'keywords' ) {
900
+ if ( ! Array . isArray ( fpd [ type ] [ key ] ) && mediaType === BANNER ) fpd [ type ] [ key ] = [ fpd [ type ] [ key ] ]
901
+
902
+ result [ key ] = fpd [ type ] [ key ] ;
903
+
904
+ if ( mediaType === BANNER ) keywords = keywords . concat ( fpd [ type ] [ key ] ) ;
905
+ } else if ( key === 'data' ) {
906
+ utils . mergeDeep ( result , { ext : { data : fpd [ type ] [ key ] } } ) ;
907
+ } else if ( key === 'adServer' || key === 'pbAdSlot' ) {
908
+ ( key === 'adServer' ) ? [ 'name' , 'adSlot' ] . forEach ( name => {
909
+ const value = validate ( fpd [ type ] [ key ] [ name ] ) ;
910
+ if ( value ) utils . deepSetValue ( impData , `adserver.${ name . toLowerCase ( ) } ` , value . replace ( / ^ \/ + / , '' ) )
911
+ } ) : impData [ key . toLowerCase ( ) ] = fpd [ type ] [ key ] . replace ( / ^ \/ + / , '' )
912
+ } else {
913
+ utils . mergeDeep ( result , { ext : { data : { [ key ] : fpd [ type ] [ key ] } } } ) ;
914
+ }
915
+
916
+ return result ;
917
+ } , { } ) ;
918
+
919
+ if ( mediaType === BANNER ) {
920
+ let duplicate = ( typeof obj [ map [ type ] . code ] . ext === 'object' && obj [ map [ type ] . code ] . ext . data ) || { } ;
921
+
922
+ Object . keys ( duplicate ) . forEach ( ( key ) => {
923
+ const val = ( key === 'adserver' ) ? duplicate . adserver . adslot : validate ( duplicate [ key ] , key ) ;
924
+
925
+ if ( val ) data [ ( map [ key ] ) ? `${ map [ type ] [ BANNER ] } ${ map [ key ] } ` : `${ map [ type ] [ BANNER ] } ${ key } ` ] = val ;
926
+ } ) ;
927
+ }
928
+ } ) ;
929
+
930
+ Object . keys ( impData ) . forEach ( ( key ) => {
931
+ if ( mediaType === BANNER ) {
932
+ ( map [ key ] ) ? data [ `tg_i.${ map [ key ] } ` ] = impData [ key ] . adslot : data [ `tg_i.${ key . toLowerCase ( ) } ` ] = impData [ key ] ;
933
+ } else {
934
+ utils . mergeDeep ( data . imp [ 0 ] , { ext : { context : { data : { [ key ] : impData [ key ] } } } } ) ;
935
+ }
936
+ } ) ;
937
+
938
+ if ( mediaType === BANNER ) {
939
+ let kw = validate ( keywords , 'keywords' ) ;
940
+ if ( kw ) data . kw = kw ;
941
+ } else {
942
+ utils . mergeDeep ( data , obj ) ;
943
+ }
944
+ }
945
+
952
946
/**
953
947
* @param sizes
954
948
* @returns {* }
0 commit comments