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"
+ }]
+ }
+ ]
+}
+