diff --git a/adapters/criteo/criteo.go b/adapters/criteo/criteo.go index 69fc8b38f14..7b6a4cfff89 100644 --- a/adapters/criteo/criteo.go +++ b/adapters/criteo/criteo.go @@ -13,7 +13,8 @@ import ( ) type adapter struct { - endpoint string + endpoint string + bidderName string } type BidExt struct { @@ -25,9 +26,23 @@ type ExtPrebid struct { NetworkName string `json:"networkName"` } +type CriteoExt struct { + Igi []*CriteoExtIgi `json:"igi"` +} + +type CriteoExtIgi struct { + ImpId string `json:"impid"` + Igs []*CriteoExtIgs `json:"igs"` +} + +type CriteoExtIgs struct { + Config json.RawMessage `json:"config"` +} + func Builder(bidderName openrtb_ext.BidderName, config config.Adapter, server config.Server) (adapters.Bidder, error) { bidder := &adapter{ - endpoint: config.Endpoint, + endpoint: config.Endpoint, + bidderName: string(bidderName), } return bidder, nil } @@ -93,9 +108,36 @@ func (a *adapter) MakeBids(request *openrtb2.BidRequest, requestData *adapters.R } } + bidResponse.FledgeAuctionConfigs = a.ParseFledgeAuctionConfigs(response) + return bidResponse, nil } +func (a *adapter) ParseFledgeAuctionConfigs(response openrtb2.BidResponse) []*openrtb_ext.FledgeAuctionConfig { + var responseExt CriteoExt + if response.Ext != nil { + if err := json.Unmarshal(response.Ext, &responseExt); err == nil && len(responseExt.Igi) > 0 { + fledgeAuctionConfigs := make([]*openrtb_ext.FledgeAuctionConfig, 0, len(responseExt.Igi)) + for _, igi := range responseExt.Igi { + if len(igi.Igs) > 0 && igi.Igs[0].Config != nil { + fledgeAuctionConfig := &openrtb_ext.FledgeAuctionConfig{ + ImpId: igi.ImpId, + Bidder: a.bidderName, + Config: igi.Igs[0].Config, + } + fledgeAuctionConfigs = append(fledgeAuctionConfigs, fledgeAuctionConfig) + } + } + + if len(fledgeAuctionConfigs) > 0 { + return fledgeAuctionConfigs + } + } + } + + return nil +} + func getBidMeta(ext BidExt) *openrtb_ext.ExtBidPrebidMeta { var bidMeta *openrtb_ext.ExtBidPrebidMeta if ext.Prebid.NetworkName != "" { diff --git a/adapters/criteo/criteo_test.go b/adapters/criteo/criteo_test.go index ae538246444..5a70961e0b3 100644 --- a/adapters/criteo/criteo_test.go +++ b/adapters/criteo/criteo_test.go @@ -1,6 +1,9 @@ package criteo import ( + "fmt" + "github.com/prebid/openrtb/v20/openrtb2" + "github.com/stretchr/testify/assert" "testing" "github.com/prebid/prebid-server/v2/adapters/adapterstest" @@ -21,3 +24,34 @@ func TestJsonSamples(t *testing.T) { // Execute & Verify: adapterstest.RunJSONBidderTest(t, "criteotest", bidder) } + +func TestParseFledgeAuctionConfigs_Nil(t *testing.T) { + bidder, buildErr := Builder(openrtb_ext.BidderCriteo, config.Adapter{ + Endpoint: "https://ssp-bidder.criteo.com/openrtb/pbs/auction/request?profile=230"}, + config.Server{ExternalUrl: "http://hosturl.com", GvlID: 1, DataCenter: "2"}) + + if buildErr != nil { + t.Fatalf("Builder returned unexpected error %v", buildErr) + } + + var tests = []struct { + name string + bidResponse openrtb2.BidResponse + }{ + {"no ext", openrtb2.BidResponse{Ext: nil}}, + {"no igi", openrtb2.BidResponse{Ext: []byte("{}")}}, + {"igi empty", openrtb2.BidResponse{Ext: []byte(`{"igi":[]}`)}}, + {"no igs", openrtb2.BidResponse{Ext: []byte(`{"igi":[{}]}`)}}, + {"igs empty", openrtb2.BidResponse{Ext: []byte(`{"igi":[{"impid": "1", "igs": []}]}`)}}, + {"no config", openrtb2.BidResponse{Ext: []byte(`{"igi":[{"impid": "1", "igs": [{}]}]}`)}}, + } + + for _, tt := range tests { + testname := fmt.Sprintf("%s", tt.name) + t.Run(testname, func(t *testing.T) { + fledgeAuctionConfigs := bidder.(*adapter).ParseFledgeAuctionConfigs(tt.bidResponse) + + assert.Nil(t, fledgeAuctionConfigs) + }) + } +} diff --git a/adapters/criteo/criteotest/exemplary/simple-banner-paapi.json b/adapters/criteo/criteotest/exemplary/simple-banner-paapi.json new file mode 100644 index 00000000000..ea92a9026c8 --- /dev/null +++ b/adapters/criteo/criteotest/exemplary/simple-banner-paapi.json @@ -0,0 +1,176 @@ +{ + "mockBidRequest": { + "id": "test-request-id", + "site": { + "id": "site-id", + "page": "criteo.com" + }, + "device": { + "os": "android", + "ip": "91.199.242.236", + "ua": "random user agent" + }, + "user": { + "ext": { + "eids": [ + { + "source": "criteo.com", + "uids": [ + { + "id": "criteo-eid" + } + ] + } + ] + } + }, + "imp": [ + { + "id": "test-imp-id", + "banner": { + "format": [ + { + "w": 300, + "h": 250 + } + ] + }, + "ext": { + "ae": 1, + "bidder": { + "zoneid": 123456, + "networkid": 78910 + } + } + } + ] + }, + "httpCalls": [ + { + "expectedRequest": { + "uri": "https://ssp-bidder.criteo.com/openrtb/pbs/auction/request?profile=230", + "headers": {}, + "body": { + "id": "test-request-id", + "site": { + "id": "site-id", + "page": "criteo.com" + }, + "device": { + "os": "android", + "ip": "91.199.242.236", + "ua": "random user agent" + }, + "user": { + "ext": { + "eids": [ + { + "source": "criteo.com", + "uids": [ + { + "id": "criteo-eid" + } + ] + } + ] + } + }, + "imp": [ + { + "id": "test-imp-id", + "banner": { + "format": [ + { + "w": 300, + "h": 250 + } + ] + }, + "ext": { + "ae": 1, + "bidder": { + "zoneid": 123456, + "networkid": 78910 + } + } + } + ] + }, + "impIDs":["test-imp-id"] + }, + "mockResponse": { + "status": 200, + "body": { + "currency": "USD", + "seatbid": [ + { + "bid": [ + { + "id": "test-slot-id", + "impid": "test-imp-id", + "price": 0.1, + "crid": "creative-123", + "adm": "", + "w": 300, + "h": 250, + "ext": { + "prebid": { + "type": "banner" + } + } + } + ] + } + ], + "ext" : { + "igi": [ + { + "impid": "test-imp-id", + "igs": [ + { + "impid": "test-imp-id", + "config": { + "test": "test" + } + } + ] + } + ] + } + } + } + } + ], + "expectedBidResponses": [ + { + "currency": "USD", + "bids": [ + { + "bid": { + "id": "test-slot-id", + "impid": "test-imp-id", + "price": 0.1, + "crid": "creative-123", + "adm": "", + "w": 300, + "h": 250, + "ext": { + "prebid": { + "type": "banner" + } + } + }, + "type": "banner" + } + ], + "fledgeAuctionConfigs": [{ + "impid": "test-imp-id", + "config": { + "test": "test" + }, + "bidder": "criteo" + }] + } + ] +} +