From 67c487d1bec5dbd737ab7b8cce7047e087436456 Mon Sep 17 00:00:00 2001 From: AlexBVolcy <74930484+AlexBVolcy@users.noreply.github.com> Date: Tue, 26 Mar 2024 14:35:37 -0400 Subject: [PATCH] Make Targeting in Response Optional (#3574) --- endpoints/openrtb2/auction.go | 42 ++++----- endpoints/openrtb2/auction_test.go | 85 ++---------------- .../targeting-optional-all-false.json | 69 ++++++++++++++ ...targeting-optional-includeformat-only.json | 89 +++++++++++++++++++ .../targeting-optional-includeformat.json | 69 ++++++++++++++ exchange/exchange.go | 4 +- 6 files changed, 254 insertions(+), 104 deletions(-) create mode 100644 endpoints/openrtb2/sample-requests/valid-whole/exemplary/targeting-optional-all-false.json create mode 100644 endpoints/openrtb2/sample-requests/valid-whole/exemplary/targeting-optional-includeformat-only.json create mode 100644 endpoints/openrtb2/sample-requests/valid-whole/exemplary/targeting-optional-includeformat.json diff --git a/endpoints/openrtb2/auction.go b/endpoints/openrtb2/auction.go index 780b9ebb0a1..9accae2e041 100644 --- a/endpoints/openrtb2/auction.go +++ b/endpoints/openrtb2/auction.go @@ -1697,36 +1697,28 @@ func validateRequestExt(req *openrtb_ext.RequestWrapper) []error { } func validateTargeting(t *openrtb_ext.ExtRequestTargeting) error { - if t == nil { - return nil - } - - if (t.IncludeWinners == nil || !*t.IncludeWinners) && (t.IncludeBidderKeys == nil || !*t.IncludeBidderKeys) { - return errors.New("ext.prebid.targeting: At least one of includewinners or includebidderkeys must be enabled to enable targeting support") - } - - if t.PriceGranularity != nil { - if err := validatePriceGranularity(t.PriceGranularity); err != nil { - return err + if t != nil { + if t.PriceGranularity != nil { + if err := validatePriceGranularity(t.PriceGranularity); err != nil { + return err + } } - } - - if t.MediaTypePriceGranularity.Video != nil { - if err := validatePriceGranularity(t.MediaTypePriceGranularity.Video); err != nil { - return err + if t.MediaTypePriceGranularity.Video != nil { + if err := validatePriceGranularity(t.MediaTypePriceGranularity.Video); err != nil { + return err + } } - } - if t.MediaTypePriceGranularity.Banner != nil { - if err := validatePriceGranularity(t.MediaTypePriceGranularity.Banner); err != nil { - return err + if t.MediaTypePriceGranularity.Banner != nil { + if err := validatePriceGranularity(t.MediaTypePriceGranularity.Banner); err != nil { + return err + } } - } - if t.MediaTypePriceGranularity.Native != nil { - if err := validatePriceGranularity(t.MediaTypePriceGranularity.Native); err != nil { - return err + if t.MediaTypePriceGranularity.Native != nil { + if err := validatePriceGranularity(t.MediaTypePriceGranularity.Native); err != nil { + return err + } } } - return nil } diff --git a/endpoints/openrtb2/auction_test.go b/endpoints/openrtb2/auction_test.go index f51979db10d..5356815d81b 100644 --- a/endpoints/openrtb2/auction_test.go +++ b/endpoints/openrtb2/auction_test.go @@ -1941,9 +1941,13 @@ func TestValidateRequestExt(t *testing.T) { givenRequestExt: json.RawMessage(`{"prebid":{"cache":{"bids":{},"vastxml":{}}}}`), }, { - description: "prebid targeting", // test integration with validateTargeting - givenRequestExt: json.RawMessage(`{"prebid":{"targeting":{}}}`), - expectedErrors: []string{"ext.prebid.targeting: At least one of includewinners or includebidderkeys must be enabled to enable targeting support"}, + description: "prebid price granularity invalid", + givenRequestExt: json.RawMessage(`{"prebid":{"targeting":{"pricegranularity":{"precision":-1,"ranges":[{"min":0,"max":20,"increment":0.1}]}}}}`), + expectedErrors: []string{"Price granularity error: precision must be non-negative"}, + }, + { + description: "prebid native media type price granualrity valid", + givenRequestExt: json.RawMessage(`{"prebid":{"targeting":{"mediatypepricegranularity":{"native":{"precision":3,"ranges":[{"max":20,"increment":4.5}]}}}}}`), }, { description: "valid multibid", @@ -1984,75 +1988,9 @@ func TestValidateTargeting(t *testing.T) { givenTargeting: nil, expectedError: nil, }, - { - name: "empty", - givenTargeting: &openrtb_ext.ExtRequestTargeting{}, - expectedError: errors.New("ext.prebid.targeting: At least one of includewinners or includebidderkeys must be enabled to enable targeting support"), - }, - { - name: "includewinners nil, includebidderkeys false", - givenTargeting: &openrtb_ext.ExtRequestTargeting{ - IncludeBidderKeys: ptrutil.ToPtr(false), - }, - expectedError: errors.New("ext.prebid.targeting: At least one of includewinners or includebidderkeys must be enabled to enable targeting support"), - }, - { - name: "includewinners nil, includebidderkeys true", - givenTargeting: &openrtb_ext.ExtRequestTargeting{ - IncludeBidderKeys: ptrutil.ToPtr(true), - }, - expectedError: nil, - }, - { - name: "includewinners false, includebidderkeys nil", - givenTargeting: &openrtb_ext.ExtRequestTargeting{ - IncludeWinners: ptrutil.ToPtr(false), - }, - expectedError: errors.New("ext.prebid.targeting: At least one of includewinners or includebidderkeys must be enabled to enable targeting support"), - }, - { - name: "includewinners true, includebidderkeys nil", - givenTargeting: &openrtb_ext.ExtRequestTargeting{ - IncludeWinners: ptrutil.ToPtr(true), - }, - expectedError: nil, - }, - { - name: "all false", - givenTargeting: &openrtb_ext.ExtRequestTargeting{ - IncludeWinners: ptrutil.ToPtr(false), - IncludeBidderKeys: ptrutil.ToPtr(false), - }, - expectedError: errors.New("ext.prebid.targeting: At least one of includewinners or includebidderkeys must be enabled to enable targeting support"), - }, - { - name: "includewinners false, includebidderkeys true", - givenTargeting: &openrtb_ext.ExtRequestTargeting{ - IncludeWinners: ptrutil.ToPtr(false), - IncludeBidderKeys: ptrutil.ToPtr(true), - }, - expectedError: nil, - }, - { - name: "includewinners false, includebidderkeys true", - givenTargeting: &openrtb_ext.ExtRequestTargeting{ - IncludeWinners: ptrutil.ToPtr(true), - IncludeBidderKeys: ptrutil.ToPtr(false), - }, - expectedError: nil, - }, - { - name: "includewinners true, includebidderkeys true", - givenTargeting: &openrtb_ext.ExtRequestTargeting{ - IncludeWinners: ptrutil.ToPtr(true), - IncludeBidderKeys: ptrutil.ToPtr(true), - }, - expectedError: nil, - }, { name: "price granularity ranges out of order", givenTargeting: &openrtb_ext.ExtRequestTargeting{ - IncludeWinners: ptrutil.ToPtr(true), PriceGranularity: &openrtb_ext.PriceGranularity{ Precision: ptrutil.ToPtr(2), Ranges: []openrtb_ext.GranularityRange{ @@ -2066,7 +2004,6 @@ func TestValidateTargeting(t *testing.T) { { name: "media type price granularity video correct", givenTargeting: &openrtb_ext.ExtRequestTargeting{ - IncludeWinners: ptrutil.ToPtr(true), MediaTypePriceGranularity: openrtb_ext.MediaTypePriceGranularity{ Video: &openrtb_ext.PriceGranularity{ Precision: ptrutil.ToPtr(2), @@ -2081,7 +2018,6 @@ func TestValidateTargeting(t *testing.T) { { name: "media type price granularity banner correct", givenTargeting: &openrtb_ext.ExtRequestTargeting{ - IncludeWinners: ptrutil.ToPtr(true), MediaTypePriceGranularity: openrtb_ext.MediaTypePriceGranularity{ Banner: &openrtb_ext.PriceGranularity{ Precision: ptrutil.ToPtr(2), @@ -2096,7 +2032,6 @@ func TestValidateTargeting(t *testing.T) { { name: "media type price granularity native correct", givenTargeting: &openrtb_ext.ExtRequestTargeting{ - IncludeWinners: ptrutil.ToPtr(true), MediaTypePriceGranularity: openrtb_ext.MediaTypePriceGranularity{ Native: &openrtb_ext.PriceGranularity{ Precision: ptrutil.ToPtr(2), @@ -2111,7 +2046,6 @@ func TestValidateTargeting(t *testing.T) { { name: "media type price granularity video and banner correct", givenTargeting: &openrtb_ext.ExtRequestTargeting{ - IncludeWinners: ptrutil.ToPtr(true), MediaTypePriceGranularity: openrtb_ext.MediaTypePriceGranularity{ Banner: &openrtb_ext.PriceGranularity{ Precision: ptrutil.ToPtr(2), @@ -2132,7 +2066,6 @@ func TestValidateTargeting(t *testing.T) { { name: "media type price granularity video incorrect", givenTargeting: &openrtb_ext.ExtRequestTargeting{ - IncludeWinners: ptrutil.ToPtr(true), MediaTypePriceGranularity: openrtb_ext.MediaTypePriceGranularity{ Video: &openrtb_ext.PriceGranularity{ Precision: ptrutil.ToPtr(2), @@ -2147,7 +2080,6 @@ func TestValidateTargeting(t *testing.T) { { name: "media type price granularity banner incorrect", givenTargeting: &openrtb_ext.ExtRequestTargeting{ - IncludeWinners: ptrutil.ToPtr(true), MediaTypePriceGranularity: openrtb_ext.MediaTypePriceGranularity{ Banner: &openrtb_ext.PriceGranularity{ Precision: ptrutil.ToPtr(2), @@ -2162,7 +2094,6 @@ func TestValidateTargeting(t *testing.T) { { name: "media type price granularity native incorrect", givenTargeting: &openrtb_ext.ExtRequestTargeting{ - IncludeWinners: ptrutil.ToPtr(true), MediaTypePriceGranularity: openrtb_ext.MediaTypePriceGranularity{ Native: &openrtb_ext.PriceGranularity{ Precision: ptrutil.ToPtr(2), @@ -2177,7 +2108,6 @@ func TestValidateTargeting(t *testing.T) { { name: "media type price granularity video correct and banner incorrect", givenTargeting: &openrtb_ext.ExtRequestTargeting{ - IncludeWinners: ptrutil.ToPtr(true), MediaTypePriceGranularity: openrtb_ext.MediaTypePriceGranularity{ Banner: &openrtb_ext.PriceGranularity{ Precision: ptrutil.ToPtr(2), @@ -2198,7 +2128,6 @@ func TestValidateTargeting(t *testing.T) { { name: "media type price granularity native incorrect and banner correct", givenTargeting: &openrtb_ext.ExtRequestTargeting{ - IncludeWinners: ptrutil.ToPtr(true), MediaTypePriceGranularity: openrtb_ext.MediaTypePriceGranularity{ Native: &openrtb_ext.PriceGranularity{ Precision: ptrutil.ToPtr(2), diff --git a/endpoints/openrtb2/sample-requests/valid-whole/exemplary/targeting-optional-all-false.json b/endpoints/openrtb2/sample-requests/valid-whole/exemplary/targeting-optional-all-false.json new file mode 100644 index 00000000000..020a2ed849c --- /dev/null +++ b/endpoints/openrtb2/sample-requests/valid-whole/exemplary/targeting-optional-all-false.json @@ -0,0 +1,69 @@ +{ + "description": "Targeting flags are all set to false, request is still valid, but no targeting data should be present in bids", + "config": { + "mockBidders": [ + { + "bidderName": "appnexus", + "currency": "USD", + "price": 0.00 + } + ] + }, + "mockBidRequest": { + "id": "some-request-id", + "site": { + "page": "prebid.org" + }, + "imp": [ + { + "id": "some-impression-id", + "banner": { + "format": [ + { + "w": 300, + "h": 250 + }, + { + "w": 300, + "h": 600 + } + ] + }, + "ext": { + "appnexus": { + "placementId": 12883451 + } + } + } + ], + "tmax": 500, + "ext": { + "prebid": { + "targeting": { + "includewinners": false, + "includebidderkeys": false, + "includeformat": false + } + } + } + }, + "expectedBidResponse": { + "id": "some-request-id", + "seatbid": [ + { + "bid": [ + { + "id": "appnexus-bid", + "impid": "some-impression-id", + "price": 0 + } + ], + "seat": "appnexus" + } + ], + "bidid": "test bid id", + "cur": "USD", + "nbr": 0 + }, + "expectedReturnCode": 200 + } \ No newline at end of file diff --git a/endpoints/openrtb2/sample-requests/valid-whole/exemplary/targeting-optional-includeformat-only.json b/endpoints/openrtb2/sample-requests/valid-whole/exemplary/targeting-optional-includeformat-only.json new file mode 100644 index 00000000000..56eeaf4cea2 --- /dev/null +++ b/endpoints/openrtb2/sample-requests/valid-whole/exemplary/targeting-optional-includeformat-only.json @@ -0,0 +1,89 @@ +{ + "description": "Targeting flags are all undefined besides includeformat, request is still valid, defaults should come in for other flags so targeting data should be present in bid", + "config": { + "mockBidders": [ + { + "bidderName": "appnexus", + "currency": "USD", + "price": 1.00 + } + ] + }, + "mockBidRequest": { + "id": "some-request-id", + "site": { + "page": "prebid.org" + }, + "imp": [ + { + "id": "some-impression-id", + "banner": { + "format": [ + { + "w": 300, + "h": 250 + }, + { + "w": 300, + "h": 600 + } + ] + }, + "ext": { + "appnexus": { + "placementId": 12883451 + } + } + } + ], + "tmax": 500, + "ext": { + "prebid": { + "targeting": { + "includeformat": true + } + } + } + }, + "expectedBidResponse": { + "id": "some-request-id", + "seatbid": [ + { + "bid": [ + { + "id": "appnexus-bid", + "impid": "some-impression-id", + "price": 1.00, + "ext": { + "origbidcpm": 1, + "origbidcur": "USD", + "prebid": { + "meta": { + "adaptercode": "appnexus" + }, + "targeting": { + "hb_bidder": "appnexus", + "hb_bidder_appnexus": "appnexus", + "hb_cache_host": "www.pbcserver.com", + "hb_cache_host_appnex": "www.pbcserver.com", + "hb_cache_path": "/pbcache/endpoint", + "hb_cache_path_appnex": "/pbcache/endpoint", + "hb_format": "banner", + "hb_format_appnexus": "banner", + "hb_pb": "1.00", + "hb_pb_appnexus": "1.00" + }, + "type": "banner" + } + } + } + ], + "seat": "appnexus" + } + ], + "bidid": "test bid id", + "cur": "USD", + "nbr": 0 + }, + "expectedReturnCode": 200 + } \ No newline at end of file diff --git a/endpoints/openrtb2/sample-requests/valid-whole/exemplary/targeting-optional-includeformat.json b/endpoints/openrtb2/sample-requests/valid-whole/exemplary/targeting-optional-includeformat.json new file mode 100644 index 00000000000..2d7b801e20f --- /dev/null +++ b/endpoints/openrtb2/sample-requests/valid-whole/exemplary/targeting-optional-includeformat.json @@ -0,0 +1,69 @@ +{ + "description": "Targeting flags are all set to false except for includeformat, request is still valid, but no targeting data should be present in bids", + "config": { + "mockBidders": [ + { + "bidderName": "appnexus", + "currency": "USD", + "price": 0.00 + } + ] + }, + "mockBidRequest": { + "id": "some-request-id", + "site": { + "page": "prebid.org" + }, + "imp": [ + { + "id": "some-impression-id", + "banner": { + "format": [ + { + "w": 300, + "h": 250 + }, + { + "w": 300, + "h": 600 + } + ] + }, + "ext": { + "appnexus": { + "placementId": 12883451 + } + } + } + ], + "tmax": 500, + "ext": { + "prebid": { + "targeting": { + "includewinners": false, + "includebidderkeys": false, + "includeformat": true + } + } + } + }, + "expectedBidResponse": { + "id": "some-request-id", + "seatbid": [ + { + "bid": [ + { + "id": "appnexus-bid", + "impid": "some-impression-id", + "price": 0 + } + ], + "seat": "appnexus" + } + ], + "bidid": "test bid id", + "cur": "USD", + "nbr": 0 + }, + "expectedReturnCode": 200 + } \ No newline at end of file diff --git a/exchange/exchange.go b/exchange/exchange.go index ef38736388d..c73eea9f10c 100644 --- a/exchange/exchange.go +++ b/exchange/exchange.go @@ -460,7 +460,9 @@ func (e *exchange) HoldAuction(ctx context.Context, r *AuctionRequest, debugLog errs = append(errs, cacheErrs...) } - targData.setTargeting(auc, r.BidRequestWrapper.BidRequest.App != nil, bidCategory, r.Account.TruncateTargetAttribute, multiBidMap) + if targData.includeWinners || targData.includeBidderKeys || targData.includeFormat { + targData.setTargeting(auc, r.BidRequestWrapper.BidRequest.App != nil, bidCategory, r.Account.TruncateTargetAttribute, multiBidMap) + } } bidResponseExt = e.makeExtBidResponse(adapterBids, adapterExtra, *r, responseDebugAllow, requestExtPrebid.Passthrough, fledge, errs) } else {