From d2b553c12eb7379278dcdb04a0aac4b57e5a7b50 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bj=C3=B6rn=20Andersson?= Date: Mon, 15 Nov 2021 23:14:26 +0100 Subject: [PATCH 1/6] Adform adapter lacked gross/net parameter support. Implementing priceType as in client adapter. --- adapters/adf/adf.go | 13 +++ .../single-banner-pricetype-gross.json | 110 ++++++++++++++++++ .../single-banner-pricetype-net.json | 110 ++++++++++++++++++ adapters/adf/params_test.go | 3 + openrtb_ext/imp_adf.go | 1 + static/bidder-params/adf.json | 5 + 6 files changed, 242 insertions(+) create mode 100644 adapters/adf/adftest/exemplary/single-banner-pricetype-gross.json create mode 100644 adapters/adf/adftest/exemplary/single-banner-pricetype-net.json diff --git a/adapters/adf/adf.go b/adapters/adf/adf.go index 8014bd5bb56..fa6258a6985 100644 --- a/adapters/adf/adf.go +++ b/adapters/adf/adf.go @@ -16,6 +16,10 @@ type adapter struct { endpoint string } +type adfRequestExt struct { + PriceType string `json:"pt"` +} + // Builder builds a new instance of the Adf adapter for the given bidder with the given config. func Builder(bidderName openrtb_ext.BidderName, config config.Adapter) (adapters.Bidder, error) { bidder := &adapter{ @@ -47,6 +51,15 @@ func (a *adapter) MakeRequests(request *openrtb2.BidRequest, requestInfo *adapte imp.TagID = adfImpExt.MasterTagID.String() validImps = append(validImps, imp) + + if adfImpExt.PriceType != "" { + requestExt := adfRequestExt{PriceType: adfImpExt.PriceType} + var err error + if request.Ext, err = json.Marshal(&requestExt); err != nil { + errors = append(errors, err) + continue + } + } } request.Imp = validImps diff --git a/adapters/adf/adftest/exemplary/single-banner-pricetype-gross.json b/adapters/adf/adftest/exemplary/single-banner-pricetype-gross.json new file mode 100644 index 00000000000..2bef42aa0a5 --- /dev/null +++ b/adapters/adf/adftest/exemplary/single-banner-pricetype-gross.json @@ -0,0 +1,110 @@ +{ + "mockBidRequest": { + "id": "test-request-id", + "imp": [{ + "id": "test-imp-id", + "ext": { + "bidder": { + "mid": "828782", + "priceType": "gross" + } + }, + "banner": { + "format": [{ + "w": 300, + "h": 250 + }] + } + }], + "site": { + "publisher": { + "id": "1" + }, + "page": "some-page-url" + }, + "device": { + "w": 1920, + "h": 800 + } + }, + "httpCalls": [{ + "expectedRequest": { + "uri": "https://adx.adform.net/adx/openrtb", + "body": { + "id": "test-request-id", + "ext": { + "pt": "gross" + }, + "imp": [{ + "id": "test-imp-id", + "ext": { + "bidder": { + "mid": "828782", + "priceType": "gross" + } + }, + "banner": { + "format": [{ + "w": 300, + "h": 250 + }] + }, + "tagid": "828782" + }], + "site": { + "publisher": { + "id": "1" + }, + "page": "some-page-url" + }, + "device": { + "w": 1920, + "h": 800 + } + } + }, + "mockResponse": { + "status": 200, + "body": { + "id": "test-request-id", + "seatbid": [{ + "bid": [{ + "id": "test-bid-id", + "impid": "test-imp-id", + "price": 10, + "adm": "{banner html}", + "adomain": [ "test.com" ], + "crid": "test-creative-id", + "ext": { + "prebid": { + "type": "banner" + } + } + }] + }], + "cur": "USD" + } + } + }], + "expectedBidResponses": [{ + "currency": "USD", + "bids": [ + { + "bid": { + "id": "test-bid-id", + "impid": "test-imp-id", + "price": 10, + "adm": "{banner html}", + "crid": "test-creative-id", + "adomain": [ "test.com" ], + "ext": { + "prebid": { + "type": "banner" + } + } + }, + "type": "banner" + } + ] + }] +} diff --git a/adapters/adf/adftest/exemplary/single-banner-pricetype-net.json b/adapters/adf/adftest/exemplary/single-banner-pricetype-net.json new file mode 100644 index 00000000000..2db031b11f6 --- /dev/null +++ b/adapters/adf/adftest/exemplary/single-banner-pricetype-net.json @@ -0,0 +1,110 @@ +{ + "mockBidRequest": { + "id": "test-request-id", + "imp": [{ + "id": "test-imp-id", + "ext": { + "bidder": { + "mid": "828782", + "priceType": "net" + } + }, + "banner": { + "format": [{ + "w": 300, + "h": 250 + }] + } + }], + "site": { + "publisher": { + "id": "1" + }, + "page": "some-page-url" + }, + "device": { + "w": 1920, + "h": 800 + } + }, + "httpCalls": [{ + "expectedRequest": { + "uri": "https://adx.adform.net/adx/openrtb", + "body": { + "id": "test-request-id", + "ext": { + "pt": "net" + }, + "imp": [{ + "id": "test-imp-id", + "ext": { + "bidder": { + "mid": "828782", + "priceType": "net" + } + }, + "banner": { + "format": [{ + "w": 300, + "h": 250 + }] + }, + "tagid": "828782" + }], + "site": { + "publisher": { + "id": "1" + }, + "page": "some-page-url" + }, + "device": { + "w": 1920, + "h": 800 + } + } + }, + "mockResponse": { + "status": 200, + "body": { + "id": "test-request-id", + "seatbid": [{ + "bid": [{ + "id": "test-bid-id", + "impid": "test-imp-id", + "price": 10, + "adm": "{banner html}", + "adomain": [ "test.com" ], + "crid": "test-creative-id", + "ext": { + "prebid": { + "type": "banner" + } + } + }] + }], + "cur": "USD" + } + } + }], + "expectedBidResponses": [{ + "currency": "USD", + "bids": [ + { + "bid": { + "id": "test-bid-id", + "impid": "test-imp-id", + "price": 10, + "adm": "{banner html}", + "crid": "test-creative-id", + "adomain": [ "test.com" ], + "ext": { + "prebid": { + "type": "banner" + } + } + }, + "type": "banner" + } + ] + }] +} diff --git a/adapters/adf/params_test.go b/adapters/adf/params_test.go index d075f914082..d46c6528da0 100644 --- a/adapters/adf/params_test.go +++ b/adapters/adf/params_test.go @@ -46,6 +46,8 @@ var validParams = []string{ `{"inv":321,"mname":"12345"}`, `{"mid":123,"inv":321,"mname":"pcl1"}`, `{"mid":"123","inv":321,"mname":"pcl1"}`, + `{"mid":"123","priceType":"gross"}`, + `{"mid":"123","priceType":"net"}`, } var invalidParams = []string{ @@ -62,4 +64,5 @@ var invalidParams = []string{ `{"inv":321}`, `{"inv":"321"}`, `{"mname":"12345"}`, + `{"mid":"123","priceType":"GROSS"}`, } diff --git a/openrtb_ext/imp_adf.go b/openrtb_ext/imp_adf.go index 6a8f9afaa33..e4f5283b7c2 100644 --- a/openrtb_ext/imp_adf.go +++ b/openrtb_ext/imp_adf.go @@ -8,4 +8,5 @@ type ExtImpAdf struct { MasterTagID json.Number `json:"mid,omitempty"` InventorySourceID int `json:"inv,omitempty"` PlacementName string `json:"mname,omitempty"` + PriceType string `json:"priceType,omitempty"` } diff --git a/static/bidder-params/adf.json b/static/bidder-params/adf.json index 4a1a11827ef..e165fa85b7e 100644 --- a/static/bidder-params/adf.json +++ b/static/bidder-params/adf.json @@ -16,6 +16,11 @@ "mname": { "type": ["string"], "description": "A Name which identifies the placement selling the impression" + }, + "priceType": { + "type": ["string"], + "description": "gross or net. Default is net.", + "pattern": "gross|net" } }, "anyOf":[ From 05d9d4b669cd800f97181856c8fe2bb49a470728 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bj=C3=B6rn=20Andersson?= Date: Tue, 16 Nov 2021 00:16:28 +0100 Subject: [PATCH 2/6] Extend request.ext --- adapters/adf/adf.go | 15 ++- ...gle-banner-pricetype-gross-extend-ext.json | 122 ++++++++++++++++++ .../single-banner-pricetype-gross.json | 2 + .../single-banner-pricetype-net.json | 2 + 4 files changed, 140 insertions(+), 1 deletion(-) create mode 100644 adapters/adf/adftest/exemplary/single-banner-pricetype-gross-extend-ext.json diff --git a/adapters/adf/adf.go b/adapters/adf/adf.go index fa6258a6985..9a6946523a9 100644 --- a/adapters/adf/adf.go +++ b/adapters/adf/adf.go @@ -17,6 +17,7 @@ type adapter struct { } type adfRequestExt struct { + openrtb_ext.ExtRequest PriceType string `json:"pt"` } @@ -53,7 +54,19 @@ func (a *adapter) MakeRequests(request *openrtb2.BidRequest, requestInfo *adapte validImps = append(validImps, imp) if adfImpExt.PriceType != "" { - requestExt := adfRequestExt{PriceType: adfImpExt.PriceType} + var requestExt adfRequestExt + + if len(request.Ext) > 0 { + if err := json.Unmarshal(request.Ext, &requestExt); err != nil { + errors = append(errors, err) + continue + } + } else { + requestExt = adfRequestExt{} + } + + requestExt.PriceType = adfImpExt.PriceType + var err error if request.Ext, err = json.Marshal(&requestExt); err != nil { errors = append(errors, err) diff --git a/adapters/adf/adftest/exemplary/single-banner-pricetype-gross-extend-ext.json b/adapters/adf/adftest/exemplary/single-banner-pricetype-gross-extend-ext.json new file mode 100644 index 00000000000..0cd03c75bb5 --- /dev/null +++ b/adapters/adf/adftest/exemplary/single-banner-pricetype-gross-extend-ext.json @@ -0,0 +1,122 @@ +{ + "mockBidRequest": { + "id": "test-request-id", + "ext":{ + "prebid":{ + "aliases":{ + "adfalias": "adf" + } + } + }, + "imp": [{ + "id": "test-imp-id", + "ext": { + "bidder": { + "mid": "828782", + "priceType": "gross" + } + }, + "banner": { + "format": [{ + "w": 300, + "h": 250 + }] + } + }], + "site": { + "publisher": { + "id": "1" + }, + "page": "some-page-url" + }, + "device": { + "w": 1920, + "h": 800 + } + }, + "httpCalls": [{ + "expectedRequest": { + "uri": "https://adx.adform.net/adx/openrtb", + "body": { + "id": "test-request-id", + "ext": { + "prebid":{ + "aliases":{ + "adfalias": "adf" + } + }, + "pt": "gross" + }, + "imp": [{ + "id": "test-imp-id", + "ext": { + "bidder": { + "mid": "828782", + "priceType": "gross" + } + }, + "banner": { + "format": [{ + "w": 300, + "h": 250 + }] + }, + "tagid": "828782" + }], + "site": { + "publisher": { + "id": "1" + }, + "page": "some-page-url" + }, + "device": { + "w": 1920, + "h": 800 + } + } + }, + "mockResponse": { + "status": 200, + "body": { + "id": "test-request-id", + "seatbid": [{ + "bid": [{ + "id": "test-bid-id", + "impid": "test-imp-id", + "price": 10, + "adm": "{banner html}", + "adomain": [ "test.com" ], + "crid": "test-creative-id", + "ext": { + "prebid": { + "type": "banner" + } + } + }] + }], + "cur": "USD" + } + } + }], + "expectedBidResponses": [{ + "currency": "USD", + "bids": [ + { + "bid": { + "id": "test-bid-id", + "impid": "test-imp-id", + "price": 10, + "adm": "{banner html}", + "crid": "test-creative-id", + "adomain": [ "test.com" ], + "ext": { + "prebid": { + "type": "banner" + } + } + }, + "type": "banner" + } + ] + }] +} diff --git a/adapters/adf/adftest/exemplary/single-banner-pricetype-gross.json b/adapters/adf/adftest/exemplary/single-banner-pricetype-gross.json index 2bef42aa0a5..2fb7cf24c5a 100644 --- a/adapters/adf/adftest/exemplary/single-banner-pricetype-gross.json +++ b/adapters/adf/adftest/exemplary/single-banner-pricetype-gross.json @@ -33,6 +33,8 @@ "body": { "id": "test-request-id", "ext": { + "prebid": { + }, "pt": "gross" }, "imp": [{ diff --git a/adapters/adf/adftest/exemplary/single-banner-pricetype-net.json b/adapters/adf/adftest/exemplary/single-banner-pricetype-net.json index 2db031b11f6..cb4b5f8a1f4 100644 --- a/adapters/adf/adftest/exemplary/single-banner-pricetype-net.json +++ b/adapters/adf/adftest/exemplary/single-banner-pricetype-net.json @@ -33,6 +33,8 @@ "body": { "id": "test-request-id", "ext": { + "prebid": { + }, "pt": "net" }, "imp": [{ From 1504712875e8f01703a17a4b9c9d91424ab9275f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bj=C3=B6rn=20Andersson?= Date: Wed, 17 Nov 2021 11:41:37 +0100 Subject: [PATCH 3/6] Some code optimizations --- adapters/adf/adf.go | 32 +++++++++++++++++--------------- 1 file changed, 17 insertions(+), 15 deletions(-) diff --git a/adapters/adf/adf.go b/adapters/adf/adf.go index 9a6946523a9..2d99c8b6900 100644 --- a/adapters/adf/adf.go +++ b/adapters/adf/adf.go @@ -32,6 +32,7 @@ func Builder(bidderName openrtb_ext.BidderName, config config.Adapter) (adapters func (a *adapter) MakeRequests(request *openrtb2.BidRequest, requestInfo *adapters.ExtraRequestInfo) ([]*adapters.RequestData, []error) { var errors []error var validImps = make([]openrtb2.Imp, 0, len(request.Imp)) + priceType := "" for _, imp := range request.Imp { var bidderExt adapters.ExtImpBidder @@ -53,26 +54,27 @@ func (a *adapter) MakeRequests(request *openrtb2.BidRequest, requestInfo *adapte imp.TagID = adfImpExt.MasterTagID.String() validImps = append(validImps, imp) - if adfImpExt.PriceType != "" { - var requestExt adfRequestExt - - if len(request.Ext) > 0 { - if err := json.Unmarshal(request.Ext, &requestExt); err != nil { - errors = append(errors, err) - continue - } - } else { - requestExt = adfRequestExt{} - } + // If imps specify priceType they should all be the same. If they differ, only the first one will be used + if adfImpExt.PriceType != "" && priceType == "" { + priceType = adfImpExt.PriceType + } + } - requestExt.PriceType = adfImpExt.PriceType + if priceType != "" { + requestExt := adfRequestExt{} - var err error - if request.Ext, err = json.Marshal(&requestExt); err != nil { + if len(request.Ext) > 0 { + if err := json.Unmarshal(request.Ext, &requestExt); err != nil { errors = append(errors, err) - continue } } + + requestExt.PriceType = priceType + + var err error + if request.Ext, err = json.Marshal(&requestExt); err != nil { + errors = append(errors, err) + } } request.Imp = validImps From 063990f8cd8b43b5c8d6d25c1a4ac449350710f7 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bj=C3=B6rn=20Andersson?= Date: Wed, 17 Nov 2021 11:51:40 +0100 Subject: [PATCH 4/6] Extended test --- ...nners-different-pricetypes-extend-ext.json | 151 ++++++++++++++++++ .../two-banners-different-pricetypes.json | 141 ++++++++++++++++ 2 files changed, 292 insertions(+) create mode 100644 adapters/adf/adftest/exemplary/two-banners-different-pricetypes-extend-ext.json create mode 100644 adapters/adf/adftest/exemplary/two-banners-different-pricetypes.json diff --git a/adapters/adf/adftest/exemplary/two-banners-different-pricetypes-extend-ext.json b/adapters/adf/adftest/exemplary/two-banners-different-pricetypes-extend-ext.json new file mode 100644 index 00000000000..59e380d5f2e --- /dev/null +++ b/adapters/adf/adftest/exemplary/two-banners-different-pricetypes-extend-ext.json @@ -0,0 +1,151 @@ +{ + "mockBidRequest": { + "id": "test-request-id", + "ext":{ + "prebid":{ + "aliases":{ + "adfalias": "adf" + } + } + }, + "imp": [{ + "id": "test-imp-id", + "ext": { + "bidder": { + "mid": "828782", + "priceType": "gross" + } + }, + "banner": { + "format": [{ + "w": 300, + "h": 250 + }] + } + },{ + "id": "test-imp-id2", + "ext": { + "bidder": { + "mid": "828783", + "priceType": "net" + } + }, + "banner": { + "format": [{ + "w": 300, + "h": 250 + }] + } + }], + "site": { + "publisher": { + "id": "1" + }, + "page": "some-page-url" + }, + "device": { + "w": 1920, + "h": 800 + } + }, + "httpCalls": [{ + "expectedRequest": { + "uri": "https://adx.adform.net/adx/openrtb", + "body": { + "id": "test-request-id", + "ext": { + "prebid":{ + "aliases":{ + "adfalias": "adf" + } + }, + "pt": "gross" + }, + "imp": [{ + "id": "test-imp-id", + "ext": { + "bidder": { + "mid": "828782", + "priceType": "gross" + } + }, + "banner": { + "format": [{ + "w": 300, + "h": 250 + }] + }, + "tagid": "828782" + },{ + "id": "test-imp-id2", + "ext": { + "bidder": { + "mid": "828783", + "priceType": "net" + } + }, + "banner": { + "format": [{ + "w": 300, + "h": 250 + }] + }, + "tagid": "828783" + }], + "site": { + "publisher": { + "id": "1" + }, + "page": "some-page-url" + }, + "device": { + "w": 1920, + "h": 800 + } + } + }, + "mockResponse": { + "status": 200, + "body": { + "id": "test-request-id", + "seatbid": [{ + "bid": [{ + "id": "test-bid-id", + "impid": "test-imp-id", + "price": 10, + "adm": "{banner html}", + "adomain": [ "test.com" ], + "crid": "test-creative-id", + "ext": { + "prebid": { + "type": "banner" + } + } + }] + }], + "cur": "USD" + } + } + }], + "expectedBidResponses": [{ + "currency": "USD", + "bids": [ + { + "bid": { + "id": "test-bid-id", + "impid": "test-imp-id", + "price": 10, + "adm": "{banner html}", + "crid": "test-creative-id", + "adomain": [ "test.com" ], + "ext": { + "prebid": { + "type": "banner" + } + } + }, + "type": "banner" + } + ] + }] +} diff --git a/adapters/adf/adftest/exemplary/two-banners-different-pricetypes.json b/adapters/adf/adftest/exemplary/two-banners-different-pricetypes.json new file mode 100644 index 00000000000..918ef3ca7f3 --- /dev/null +++ b/adapters/adf/adftest/exemplary/two-banners-different-pricetypes.json @@ -0,0 +1,141 @@ +{ + "mockBidRequest": { + "id": "test-request-id", + "imp": [{ + "id": "test-imp-id", + "ext": { + "bidder": { + "mid": "828782", + "priceType": "gross" + } + }, + "banner": { + "format": [{ + "w": 300, + "h": 250 + }] + } + },{ + "id": "test-imp-id2", + "ext": { + "bidder": { + "mid": "828783", + "priceType": "net" + } + }, + "banner": { + "format": [{ + "w": 300, + "h": 250 + }] + } + }], + "site": { + "publisher": { + "id": "1" + }, + "page": "some-page-url" + }, + "device": { + "w": 1920, + "h": 800 + } + }, + "httpCalls": [{ + "expectedRequest": { + "uri": "https://adx.adform.net/adx/openrtb", + "body": { + "id": "test-request-id", + "ext": { + "prebid": { + }, + "pt": "gross" + }, + "imp": [{ + "id": "test-imp-id", + "ext": { + "bidder": { + "mid": "828782", + "priceType": "gross" + } + }, + "banner": { + "format": [{ + "w": 300, + "h": 250 + }] + }, + "tagid": "828782" + },{ + "id": "test-imp-id2", + "ext": { + "bidder": { + "mid": "828783", + "priceType": "net" + } + }, + "banner": { + "format": [{ + "w": 300, + "h": 250 + }] + }, + "tagid": "828783" + }], + "site": { + "publisher": { + "id": "1" + }, + "page": "some-page-url" + }, + "device": { + "w": 1920, + "h": 800 + } + } + }, + "mockResponse": { + "status": 200, + "body": { + "id": "test-request-id", + "seatbid": [{ + "bid": [{ + "id": "test-bid-id", + "impid": "test-imp-id", + "price": 10, + "adm": "{banner html}", + "adomain": [ "test.com" ], + "crid": "test-creative-id", + "ext": { + "prebid": { + "type": "banner" + } + } + }] + }], + "cur": "USD" + } + } + }], + "expectedBidResponses": [{ + "currency": "USD", + "bids": [ + { + "bid": { + "id": "test-bid-id", + "impid": "test-imp-id", + "price": 10, + "adm": "{banner html}", + "crid": "test-creative-id", + "adomain": [ "test.com" ], + "ext": { + "prebid": { + "type": "banner" + } + } + }, + "type": "banner" + } + ] + }] +} From a3bfae64747f375c6f63b6171345a75390876c23 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bj=C3=B6rn=20Andersson?= Date: Thu, 18 Nov 2021 17:13:58 +0100 Subject: [PATCH 5/6] Duplicated adf documentation in adform docs --- static/bidder-params/adform.json | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/static/bidder-params/adform.json b/static/bidder-params/adform.json index 906241ffb34..e112f122e49 100644 --- a/static/bidder-params/adform.json +++ b/static/bidder-params/adform.json @@ -16,6 +16,11 @@ "mname": { "type": ["string"], "description": "A Name which identifies the placement selling the impression" + }, + "priceType": { + "type": ["string"], + "description": "gross or net. Default is net.", + "pattern": "gross|net" } }, "anyOf":[ From fffd6b6f5dca966bd7be584c6efb4af4c984fc6e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bj=C3=B6rn=20Andersson?= Date: Tue, 23 Nov 2021 14:08:52 +0100 Subject: [PATCH 6/6] Robustness --- adapters/adf/adf.go | 12 +++++++----- 1 file changed, 7 insertions(+), 5 deletions(-) diff --git a/adapters/adf/adf.go b/adapters/adf/adf.go index 2d99c8b6900..bc54f78f187 100644 --- a/adapters/adf/adf.go +++ b/adapters/adf/adf.go @@ -62,18 +62,20 @@ func (a *adapter) MakeRequests(request *openrtb2.BidRequest, requestInfo *adapte if priceType != "" { requestExt := adfRequestExt{} + var err error if len(request.Ext) > 0 { - if err := json.Unmarshal(request.Ext, &requestExt); err != nil { + if err = json.Unmarshal(request.Ext, &requestExt); err != nil { errors = append(errors, err) } } - requestExt.PriceType = priceType + if err == nil { + requestExt.PriceType = priceType - var err error - if request.Ext, err = json.Marshal(&requestExt); err != nil { - errors = append(errors, err) + if request.Ext, err = json.Marshal(&requestExt); err != nil { + errors = append(errors, err) + } } }