diff --git a/adapters/openx/openx.go b/adapters/openx/openx.go index f10985f3085..992baa0cdc7 100644 --- a/adapters/openx/openx.go +++ b/adapters/openx/openx.go @@ -4,6 +4,7 @@ import ( "encoding/json" "fmt" "net/http" + "strconv" "github.com/prebid/openrtb/v20/openrtb2" "github.com/prebid/prebid-server/v3/adapters" @@ -32,6 +33,12 @@ type openxRespExt struct { FledgeAuctionConfigs map[string]json.RawMessage `json:"fledge_auction_configs,omitempty"` } +type oxBidExt struct { + DspId int `json:"dsp_id,string,omitempty"` + BrandId int `json:"brand_id,string,omitempty"` + BuyerId string `json:"buyer_id,omitempty"` +} + func (a *OpenxAdapter) MakeRequests(request *openrtb2.BidRequest, reqInfo *adapters.ExtraRequestInfo) ([]*adapters.RequestData, []error) { var errs []error var bannerAndNativeImps []openrtb2.Imp @@ -238,6 +245,7 @@ func (a *OpenxAdapter) MakeBids(internalRequest *openrtb2.BidRequest, externalRe Bid: &sb.Bid[i], BidType: getBidType(sb.Bid[i].MType, sb.Bid[i].ImpID, internalRequest.Imp), BidVideo: getBidVideo(&sb.Bid[i]), + BidMeta: getBidMeta(&sb.Bid[i]), }) } } @@ -298,3 +306,36 @@ func Builder(bidderName openrtb_ext.BidderName, config config.Adapter, server co } return bidder, nil } + +func getBidMeta(bid *openrtb2.Bid) *openrtb_ext.ExtBidPrebidMeta { + if bid.Ext == nil { + return nil + } + + var ext *oxBidExt + if err := jsonutil.Unmarshal(bid.Ext, &ext); err != nil { + return nil + } + + buyerId := getBuyerIdFromExt(ext) + if buyerId <= 0 && ext.DspId <= 0 && ext.BrandId <= 0 { + return nil + } + + return &openrtb_ext.ExtBidPrebidMeta{ + NetworkID: ext.DspId, + AdvertiserID: buyerId, + BrandID: ext.BrandId, + } +} + +func getBuyerIdFromExt(ext *oxBidExt) int { + if ext.BuyerId == "" { + return 0 + } + buyerId, err := strconv.Atoi(ext.BuyerId) + if err != nil { + return 0 + } + return buyerId +} diff --git a/adapters/openx/openx_test.go b/adapters/openx/openx_test.go index 092e9190f90..fdfb37cc4a0 100644 --- a/adapters/openx/openx_test.go +++ b/adapters/openx/openx_test.go @@ -2,6 +2,7 @@ package openx import ( "encoding/json" + "net/http" "testing" "github.com/prebid/openrtb/v20/openrtb2" @@ -33,6 +34,119 @@ func TestResponseWithCurrencies(t *testing.T) { assertCurrencyInBidResponse(t, "EUR", ¤cy) } +func TestOpenxAdapter_GetBidMeta(t *testing.T) { + testCases := []struct { + bid *openrtb2.Bid + expectedMeta *openrtb_ext.ExtBidPrebidMeta + }{ + { + &openrtb2.Bid{Ext: json.RawMessage(`malformed`)}, + nil, + }, + { + &openrtb2.Bid{Ext: json.RawMessage(`{}`)}, + nil, + }, + { + &openrtb2.Bid{Ext: json.RawMessage(`{"dsp_id":"456","brand_id":"789","buyer_id":"123"}`)}, + &openrtb_ext.ExtBidPrebidMeta{AdvertiserID: 123, NetworkID: 456, BrandID: 789}, + }, + { + &openrtb2.Bid{Ext: json.RawMessage(`{"dsp_id":"456","brand_id":"malformed","buyer_id":"123"}`)}, + nil, + }, + { + &openrtb2.Bid{Ext: json.RawMessage(`{"dsp_id":"456","brand_id":"789","buyer_id":"123-456"}`)}, + &openrtb_ext.ExtBidPrebidMeta{AdvertiserID: 0, NetworkID: 456, BrandID: 789}, + }, + { + &openrtb2.Bid{Ext: json.RawMessage(`{"buyer_id":"123","dsp_id":"456"}`)}, + &openrtb_ext.ExtBidPrebidMeta{AdvertiserID: 123, NetworkID: 456, BrandID: 0}, + }, + { + &openrtb2.Bid{Ext: json.RawMessage(`{"buyer_id":"123","brand_id":"789"}`)}, + &openrtb_ext.ExtBidPrebidMeta{AdvertiserID: 123, NetworkID: 0, BrandID: 789}, + }, + { + &openrtb2.Bid{Ext: json.RawMessage(`{"dsp_id":"456","brand_id":"789"}`)}, + &openrtb_ext.ExtBidPrebidMeta{AdvertiserID: 0, NetworkID: 456, BrandID: 789}, + }, + { + &openrtb2.Bid{Ext: json.RawMessage(`{"buyer_id":"123"}`)}, + &openrtb_ext.ExtBidPrebidMeta{AdvertiserID: 123, NetworkID: 0, BrandID: 0}, + }, + { + &openrtb2.Bid{Ext: json.RawMessage(`{"dsp_id":"456"}`)}, + &openrtb_ext.ExtBidPrebidMeta{AdvertiserID: 0, NetworkID: 456, BrandID: 0}, + }, + { + &openrtb2.Bid{Ext: json.RawMessage(`{"brand_id":"789"}`)}, + &openrtb_ext.ExtBidPrebidMeta{AdvertiserID: 0, NetworkID: 0, BrandID: 789}, + }, + { + &openrtb2.Bid{Ext: json.RawMessage(`{"buyer_id":"123","dsp_id":"456"}`)}, + &openrtb_ext.ExtBidPrebidMeta{AdvertiserID: 123, NetworkID: 456, BrandID: 0}, + }, + { + &openrtb2.Bid{Ext: json.RawMessage(`{"buyer_id":"malformed","dsp_id":"malformed","brand_id":"malformed"}`)}, + nil, + }, + } + + for _, testCase := range testCases { + updatedMeta := getBidMeta(testCase.bid) + assert.Equal(t, testCase.expectedMeta, updatedMeta) + } +} + +func TestOpenxAdapter_MakeBids(t *testing.T) { + responseBody := `{"id":"test-request-id","seatbid":[{"seat":"openx","bid":[{"id":"all-buyer-ext","impid":"all-buyer-ext-imp-id","price":0.5,"adm":"some-test-ad","crid":"crid_10","ext":{"dsp_id":"123","brand_id":"456","buyer_id":"789"},"h":90,"w":728,"mtype":1},{"id":"only-dspId","impid":"only-dspId-imp-id","price":0.6,"adm":"some-test-ad","crid":"crid_11","ext":{"dsp_id":"321"},"h":90,"w":728,"mtype":1}]}],"cur":"USD"}` + response := &adapters.ResponseData{ + StatusCode: http.StatusOK, + Body: []byte(responseBody), + } + adapter := &OpenxAdapter{bidderName: "", endpoint: ""} + bids, _ := adapter.MakeBids(&openrtb2.BidRequest{}, &adapters.RequestData{}, response) + expectedBidderResponse := adapters.BidderResponse{ + Currency: "USD", + Bids: []*adapters.TypedBid{ + { + Bid: &openrtb2.Bid{ + ID: "all-buyer-ext", + ImpID: "all-buyer-ext-imp-id", + Price: 0.5, + AdM: "some-test-ad", + CrID: "crid_10", + W: 728, + H: 90, + MType: 1, + Ext: json.RawMessage(`{"dsp_id":"123","brand_id":"456","buyer_id":"789"}`), + }, + BidMeta: &openrtb_ext.ExtBidPrebidMeta{NetworkID: 123, BrandID: 456, AdvertiserID: 789}, + BidType: "banner", + BidVideo: &openrtb_ext.ExtBidPrebidVideo{Duration: 0, PrimaryCategory: ""}, + }, + { + Bid: &openrtb2.Bid{ + ID: "only-dspId", + ImpID: "only-dspId-imp-id", + Price: 0.6, + AdM: "some-test-ad", + CrID: "crid_11", + W: 728, + H: 90, + MType: 1, + Ext: json.RawMessage(`{"dsp_id":"321"}`), + }, + BidMeta: &openrtb_ext.ExtBidPrebidMeta{NetworkID: 321}, + BidType: "banner", + BidVideo: &openrtb_ext.ExtBidPrebidVideo{Duration: 0, PrimaryCategory: ""}, + }, + }, + } + assert.Equal(t, expectedBidderResponse, *bids) +} + func assertCurrencyInBidResponse(t *testing.T, expectedCurrency string, currency *string) { bidder, buildErr := Builder(openrtb_ext.BidderOpenx, config.Adapter{ Endpoint: "http://rtb.openx.net/prebid"}, config.Server{ExternalUrl: "http://hosturl.com", GvlID: 1, DataCenter: "2"})