diff --git a/adapters/pixfuture/params_test.go b/adapters/pixfuture/params_test.go new file mode 100644 index 00000000000..94f7b4148c7 --- /dev/null +++ b/adapters/pixfuture/params_test.go @@ -0,0 +1,50 @@ +package pixfuture + +import ( + "fmt" + "testing" + + "github.com/prebid/prebid-server/v3/openrtb_ext" + "github.com/stretchr/testify/assert" +) + +func TestPixfutureParams(t *testing.T) { + testCases := []struct { + name string + params openrtb_ext.ImpExtPixfuture + expectedError string + }{ + { + name: "Valid Params", + params: openrtb_ext.ImpExtPixfuture{ + PlacementID: "123", + }, + expectedError: "", + }, + { + name: "Missing PlacementID", + params: openrtb_ext.ImpExtPixfuture{ + PlacementID: "", + }, + expectedError: "PlacementID is required", + }, + } + + for _, test := range testCases { + t.Run(test.name, func(t *testing.T) { + err := validatePixfutureParams(test.params) + if test.expectedError == "" { + assert.NoError(t, err) + } else { + assert.EqualError(t, err, test.expectedError) + } + }) + } +} + +func validatePixfutureParams(params openrtb_ext.ImpExtPixfuture) error { + if params.PlacementID == "" { + return fmt.Errorf("PlacementID is required") + } + return nil +} diff --git a/adapters/pixfuture/pixfuture.go b/adapters/pixfuture/pixfuture.go new file mode 100644 index 00000000000..b0f9e8e92f2 --- /dev/null +++ b/adapters/pixfuture/pixfuture.go @@ -0,0 +1,129 @@ +package pixfuture + +import ( + "encoding/json" + "fmt" + "net/http" + + "github.com/prebid/openrtb/v20/openrtb2" + "github.com/prebid/prebid-server/v3/adapters" + "github.com/prebid/prebid-server/v3/config" + "github.com/prebid/prebid-server/v3/errortypes" + "github.com/prebid/prebid-server/v3/openrtb_ext" + "github.com/prebid/prebid-server/v3/util/jsonutil" +) + +type adapter struct { + endpoint string +} + +// Builder builds a new instance of the Pixfuture adapter. +func Builder(bidderName openrtb_ext.BidderName, config config.Adapter, server config.Server) (adapters.Bidder, error) { + return &adapter{ + endpoint: config.Endpoint, + }, nil +} + +// MakeRequests prepares and serializes HTTP requests to be sent to the Pixfuture endpoint. +func (a *adapter) MakeRequests(bidRequest *openrtb2.BidRequest, reqInfo *adapters.ExtraRequestInfo) ([]*adapters.RequestData, []error) { + var errs []error + + // Validate the bid request + if bidRequest == nil || len(bidRequest.Imp) == 0 { + errs = append(errs, fmt.Errorf("no valid impressions in bid request")) + return nil, errs + } + + // Process impressions + var validImpressions []openrtb2.Imp + for _, imp := range bidRequest.Imp { + if imp.Banner == nil && imp.Video == nil { + errs = append(errs, fmt.Errorf("unsupported impression type for impID: %s", imp.ID)) + continue + } + validImpressions = append(validImpressions, imp) + } + + if len(validImpressions) == 0 { + errs = append(errs, fmt.Errorf("no valid impressions after filtering")) + return nil, errs + } + + // Create the outgoing request + bidRequest.Imp = validImpressions + body, err := json.Marshal(bidRequest) + if err != nil { + errs = append(errs, fmt.Errorf("failed to marshal bid request: %v", err)) + return nil, errs + } + + request := &adapters.RequestData{ + Method: "POST", + Uri: a.endpoint, + Body: body, + Headers: http.Header{ + "Content-Type": []string{"application/json"}, + }, + } + + return []*adapters.RequestData{request}, errs +} + +// getMediaTypeForBid extracts the bid type based on the bid extension data. +func getMediaTypeForBid(bid openrtb2.Bid) (openrtb_ext.BidType, error) { + if bid.Ext != nil { + var bidExt openrtb_ext.ExtBid + err := jsonutil.Unmarshal(bid.Ext, &bidExt) + if err == nil && bidExt.Prebid != nil { + return openrtb_ext.ParseBidType(string(bidExt.Prebid.Type)) + } + } + + return "", &errortypes.BadServerResponse{ + Message: fmt.Sprintf("Failed to parse impression \"%s\" mediatype", bid.ImpID), + } +} + +// MakeBids parses the HTTP response from the Pixfuture endpoint and generates a BidderResponse. +func (a *adapter) MakeBids(request *openrtb2.BidRequest, requestData *adapters.RequestData, responseData *adapters.ResponseData) (*adapters.BidderResponse, []error) { + // Handle No Content response + if adapters.IsResponseStatusCodeNoContent(responseData) { + return nil, nil + } + + // Check for errors in response status code + if err := adapters.CheckResponseStatusCodeForErrors(responseData); err != nil { + return nil, []error{err} + } + + // Parse the response body + var response openrtb2.BidResponse + if err := jsonutil.Unmarshal(responseData.Body, &response); err != nil { + return nil, []error{err} + } + + bidResponse := adapters.NewBidderResponseWithBidsCapacity(len(request.Imp)) + bidResponse.Currency = response.Cur + var errors []error + + for _, seatBid := range response.SeatBid { + for i, bid := range seatBid.Bid { + bidType, err := getMediaTypeForBid(bid) + if err != nil { + errors = append(errors, err) + continue + } + + // Set the MType explicitly in the bid + //mType := openrtb2.MType(bidType) + //seatBid.Bid[i].MType = mType + + bidResponse.Bids = append(bidResponse.Bids, &adapters.TypedBid{ + Bid: &seatBid.Bid[i], + BidType: bidType, + }) + } + } + + return bidResponse, errors +} diff --git a/adapters/pixfuture/pixfuture_test.go b/adapters/pixfuture/pixfuture_test.go new file mode 100644 index 00000000000..a254fb7a5db --- /dev/null +++ b/adapters/pixfuture/pixfuture_test.go @@ -0,0 +1,167 @@ +package pixfuture + +import ( + "encoding/json" + "net/http" + "testing" + + "github.com/prebid/openrtb/v20/openrtb2" + "github.com/prebid/prebid-server/v3/adapters" + "github.com/prebid/prebid-server/v3/config" + "github.com/prebid/prebid-server/v3/openrtb_ext" + "github.com/stretchr/testify/assert" +) + +func TestBuilder(t *testing.T) { + adapter, err := Builder("pixfuture", config.Adapter{Endpoint: "https://mock-endpoint.com"}, config.Server{}) + assert.NoError(t, err, "unexpected error during Builder execution") + assert.NotNil(t, adapter, "expected a non-nil adapter instance") +} + +func TestAdapter_MakeRequests(t *testing.T) { + adapter := &adapter{endpoint: "https://mock-pixfuture-endpoint.com"} + + t.Run("Valid Request", func(t *testing.T) { + bidRequest := &openrtb2.BidRequest{ + ID: "test-request-id", + Imp: []openrtb2.Imp{ + { + ID: "test-imp-id", + Banner: &openrtb2.Banner{W: int64Ptr(300), H: int64Ptr(250)}, + Ext: jsonRawExt(`{"bidder":{"siteId":"123"}}`), + }, + }, + } + + requests, errs := adapter.MakeRequests(bidRequest, nil) + assert.Empty(t, errs, "unexpected errors in MakeRequests") + assert.Equal(t, 1, len(requests), "expected exactly one request") + + request := requests[0] + assert.Equal(t, "POST", request.Method, "unexpected HTTP method") + assert.Equal(t, "https://mock-pixfuture-endpoint.com", request.Uri, "unexpected request URI") + assert.Contains(t, string(request.Body), `"id":"test-request-id"`, "unexpected request body") + assert.Equal(t, "application/json", request.Headers.Get("Content-Type"), "unexpected content-type") + }) + + t.Run("No Impressions", func(t *testing.T) { + bidRequest := &openrtb2.BidRequest{ID: "test-request-id"} + + requests, errs := adapter.MakeRequests(bidRequest, nil) + assert.NotEmpty(t, errs, "expected error for request with no impressions") + assert.Nil(t, requests, "expected no requests for request with no impressions") + }) + + t.Run("Malformed BidRequest", func(t *testing.T) { + bidRequest := &openrtb2.BidRequest{} + + requests, errs := adapter.MakeRequests(bidRequest, nil) + assert.NotEmpty(t, errs, "expected error for malformed request") + assert.Nil(t, requests, "expected no requests for malformed request") + }) +} + +func TestAdapter_MakeBids(t *testing.T) { + adapter := &adapter{} + + t.Run("Valid Response", func(t *testing.T) { + responseData := &adapters.ResponseData{ + StatusCode: http.StatusOK, + Body: []byte(`{ + "id": "test-response-id", + "seatbid": [{ + "bid": [{ + "id": "test-bid-id", + "impid": "test-imp-id", + "price": 1.23, + "adm": "Ad Content", + "crid": "creative-123", + "w": 300, + "h": 250, + "ext": {"prebid":{"type":"banner"}} + }] + }], + "cur": "USD" + }`), + } + + bidRequest := &openrtb2.BidRequest{ID: "test-request-id", Imp: []openrtb2.Imp{{ID: "test-imp-id"}}} + bidResponse, errs := adapter.MakeBids(bidRequest, nil, responseData) + + assert.Empty(t, errs, "unexpected errors in MakeBids") + assert.NotNil(t, bidResponse, "expected bid response") + assert.Equal(t, "USD", bidResponse.Currency, "unexpected currency") + assert.Equal(t, 1, len(bidResponse.Bids), "expected one bid") + + bid := bidResponse.Bids[0] + assert.Equal(t, "test-bid-id", bid.Bid.ID, "unexpected bid ID") + assert.Equal(t, "test-imp-id", bid.Bid.ImpID, "unexpected impression ID") + assert.Equal(t, 1.23, bid.Bid.Price, "unexpected bid price") + assert.Equal(t, openrtb_ext.BidTypeBanner, bid.BidType, "unexpected bid type") + }) + + t.Run("No Content Response", func(t *testing.T) { + responseData := &adapters.ResponseData{StatusCode: http.StatusNoContent} + bidRequest := &openrtb2.BidRequest{} + bidResponse, errs := adapter.MakeBids(bidRequest, nil, responseData) + assert.Nil(t, bidResponse, "expected no bid response") + assert.Empty(t, errs, "unexpected errors for no content response") + }) + + t.Run("Bad Request Response", func(t *testing.T) { + responseData := &adapters.ResponseData{StatusCode: http.StatusBadRequest} + bidRequest := &openrtb2.BidRequest{} + bidResponse, errs := adapter.MakeBids(bidRequest, nil, responseData) + assert.Nil(t, bidResponse, "expected no bid response") + assert.NotEmpty(t, errs, "expected errors for bad request response") + }) + + t.Run("Unexpected Status Code", func(t *testing.T) { + responseData := &adapters.ResponseData{StatusCode: http.StatusInternalServerError} + bidRequest := &openrtb2.BidRequest{} + bidResponse, errs := adapter.MakeBids(bidRequest, nil, responseData) + assert.Nil(t, bidResponse, "expected no bid response") + assert.NotEmpty(t, errs, "expected errors for unexpected status code") + }) + + t.Run("Malformed Response Body", func(t *testing.T) { + responseData := &adapters.ResponseData{ + StatusCode: http.StatusOK, + Body: []byte(`malformed response`), + } + bidRequest := &openrtb2.BidRequest{} + bidResponse, errs := adapter.MakeBids(bidRequest, nil, responseData) + assert.Nil(t, bidResponse, "expected no bid response") + assert.NotEmpty(t, errs, "expected errors for malformed response body") + }) +} + +func TestGetMediaTypeForBid(t *testing.T) { + t.Run("Valid Bid Ext", func(t *testing.T) { + bid := openrtb2.Bid{ + ID: "test-bid", + Ext: json.RawMessage(`{"prebid":{"type":"banner"}}`), + } + bidType, err := getMediaTypeForBid(bid) + assert.NoError(t, err, "unexpected error in getMediaTypeForBid") + assert.Equal(t, openrtb_ext.BidTypeBanner, bidType, "unexpected bid type") + }) + + t.Run("Invalid Bid Ext", func(t *testing.T) { + bid := openrtb2.Bid{ + ID: "test-bid", + Ext: json.RawMessage(`{"invalid":"data"}`), + } + bidType, err := getMediaTypeForBid(bid) + assert.Error(t, err, "expected error for invalid bid ext") + assert.Equal(t, openrtb_ext.BidType(""), bidType, "expected empty bid type for invalid bid ext") + }) +} + +func int64Ptr(i int64) *int64 { + return &i +} + +func jsonRawExt(jsonStr string) json.RawMessage { + return json.RawMessage(jsonStr) +} diff --git a/adapters/pixfuture/testdata/valid-bid-request.json b/adapters/pixfuture/testdata/valid-bid-request.json new file mode 100644 index 00000000000..39d3fedb431 --- /dev/null +++ b/adapters/pixfuture/testdata/valid-bid-request.json @@ -0,0 +1,24 @@ +{ + "id": "test-request-id", + "imp": [ + { + "id": "test-imp-id", + "banner": { + "w": 300, + "h": 250 + }, + "ext": { + "bidder": { + "siteId": "123" + } + } + } + ], + "site": { + "page": "http://example.com" + }, + "device": { + "ua": "Mozilla/5.0", + "ip": "192.168.0.1" + } +} diff --git a/adapters/pixfuture/testdata/valid-bid-response.json b/adapters/pixfuture/testdata/valid-bid-response.json new file mode 100644 index 00000000000..87aa7a26e14 --- /dev/null +++ b/adapters/pixfuture/testdata/valid-bid-response.json @@ -0,0 +1,24 @@ +{ + "id": "test-response-id", + "seatbid": [ + { + "bid": [ + { + "id": "test-bid-id", + "impid": "test-imp-id", + "price": 1.23, + "adm": "Ad Content", + "crid": "creative-123", + "w": 300, + "h": 250, + "ext": { + "prebid": { + "type": "banner" + } + } + } + ] + } + ], + "cur": "USD" +} diff --git a/config/config.go b/config/config.go index 30f8d69adc1..dfb0d743521 100644 --- a/config/config.go +++ b/config/config.go @@ -1111,8 +1111,8 @@ func SetupViper(v *viper.Viper, filename string, bidderInfos BidderInfos) { v.BindEnv("gdpr.default_value") v.SetDefault("gdpr.enabled", true) v.SetDefault("gdpr.host_vendor_id", 0) - v.SetDefault("gdpr.timeouts_ms.init_vendorlist_fetches", 0) - v.SetDefault("gdpr.timeouts_ms.active_vendorlist_fetch", 0) + v.SetDefault("gdpr.timeouts_ms.init_vendorlist_fetches", 30000) + v.SetDefault("gdpr.timeouts_ms.active_vendorlist_fetch", 30000) v.SetDefault("gdpr.non_standard_publishers", []string{""}) v.SetDefault("gdpr.tcf2.enabled", true) v.SetDefault("gdpr.tcf2.purpose1.enforce_vendors", true) diff --git a/coverage.out b/coverage.out new file mode 100644 index 00000000000..eb1d9d43b98 --- /dev/null +++ b/coverage.out @@ -0,0 +1,25 @@ +mode: set +github.com/prebid/prebid-server/v3/adapters/pixfuture/pixfuture.go:20.119,24.2 1 1 +github.com/prebid/prebid-server/v3/adapters/pixfuture/pixfuture.go:27.137,28.27 1 1 +github.com/prebid/prebid-server/v3/adapters/pixfuture/pixfuture.go:28.27,30.3 1 1 +github.com/prebid/prebid-server/v3/adapters/pixfuture/pixfuture.go:31.2,32.16 2 1 +github.com/prebid/prebid-server/v3/adapters/pixfuture/pixfuture.go:32.16,34.3 1 0 +github.com/prebid/prebid-server/v3/adapters/pixfuture/pixfuture.go:36.2,44.50 2 1 +github.com/prebid/prebid-server/v3/adapters/pixfuture/pixfuture.go:48.72,49.20 1 1 +github.com/prebid/prebid-server/v3/adapters/pixfuture/pixfuture.go:49.20,52.41 3 1 +github.com/prebid/prebid-server/v3/adapters/pixfuture/pixfuture.go:52.41,54.4 1 1 +github.com/prebid/prebid-server/v3/adapters/pixfuture/pixfuture.go:57.2,59.3 1 1 +github.com/prebid/prebid-server/v3/adapters/pixfuture/pixfuture.go:63.166,64.53 1 1 +github.com/prebid/prebid-server/v3/adapters/pixfuture/pixfuture.go:64.53,66.3 1 1 +github.com/prebid/prebid-server/v3/adapters/pixfuture/pixfuture.go:68.2,68.54 1 1 +github.com/prebid/prebid-server/v3/adapters/pixfuture/pixfuture.go:68.54,72.3 1 1 +github.com/prebid/prebid-server/v3/adapters/pixfuture/pixfuture.go:74.2,74.46 1 1 +github.com/prebid/prebid-server/v3/adapters/pixfuture/pixfuture.go:74.46,78.3 1 1 +github.com/prebid/prebid-server/v3/adapters/pixfuture/pixfuture.go:80.2,81.73 2 1 +github.com/prebid/prebid-server/v3/adapters/pixfuture/pixfuture.go:81.73,83.3 1 1 +github.com/prebid/prebid-server/v3/adapters/pixfuture/pixfuture.go:85.2,89.43 4 1 +github.com/prebid/prebid-server/v3/adapters/pixfuture/pixfuture.go:89.43,90.35 1 1 +github.com/prebid/prebid-server/v3/adapters/pixfuture/pixfuture.go:90.35,92.18 2 1 +github.com/prebid/prebid-server/v3/adapters/pixfuture/pixfuture.go:92.18,94.13 2 0 +github.com/prebid/prebid-server/v3/adapters/pixfuture/pixfuture.go:96.4,99.6 1 1 +github.com/prebid/prebid-server/v3/adapters/pixfuture/pixfuture.go:103.2,103.28 1 1 diff --git a/docs/pixfuture.md b/docs/pixfuture.md new file mode 100644 index 00000000000..60a9434afa7 --- /dev/null +++ b/docs/pixfuture.md @@ -0,0 +1,44 @@ +# Pixfuture Adapter + +## Features + +| Feature | Value | Feature | Value | +|---------------------------|---------------------|---------------------------|---------------------| +| **Bidder Code** | `pixfuture` | **Prebid.org Member** | No | +| **Prebid.js Adapter** | Yes | **Prebid Server Adapter** | Yes | +| **Media Types** | Display | **Multi Format Support** | Will-not-bid | +| **TCF-EU Support** | Yes | **IAB GVL ID** | TBD | +| **GPP Support** | USState_All | **DSA Support** | Check with bidder | +| **USP/CCPA Support** | Yes | **COPPA Support** | Yes | +| **Supply Chain Support** | Yes | **Demand Chain Support** | Check with bidder | +| **Safeframes OK** | Yes | **Supports Deals** | No | +| **Floors Module Support** | Yes | **First Party Data Support**| No | +| **User IDs** | All | **ORTB Blocking Support** | No | +| **Privacy Sandbox** | Check with bidder | **Prebid Server App Support** | Yes | + +## "Send All Bids" Ad Server Keys + +These are the bidder-specific keys that would be targeted within GAM in a Send-All-Bids scenario. GAM truncates keys to 20 characters. + +| Bidder Key | GAM Key Description | Example Value | +|---------------------------|-------------------------------|-----------------------------| +| `hb_pb_pixfuture` | Price bucket key | e.g., `1.23` | +| `hb_bidder_pixfuture` | Bidder key | e.g., `pixfuture` | +| `hb_adid_pixfuture` | Ad ID key | e.g., `12345` | +| `hb_size_pixfuture` | Ad size key | e.g., `300x250` | +| `hb_source_pixfuture` | Source key | e.g., `client` | +| `hb_format_pixfuture` | Format key | e.g., `banner` | +| `hb_cache_host_pixfuture` | Cache host key | e.g., `cache.host.com` | +| `hb_cache_id_pixfuture` | Cache ID key | e.g., `abcdef` | +| `hb_uuid_pixfuture` | UUID key | e.g., `123e4567-e89b-12d3` | +| `hb_cache_path_pixfuture` | Cache path key | e.g., `/cache` | +| `hb_deal_pixfuture` | Deal ID key | e.g., `deal123` | + +## Bid Params + +| Name | Scope | Description | Example | Type | +|--------------|-----------|--------------------------------|--------------------------------|--------| +| `pix_id` | Required | Placement ID | `12345` | String | + + +``` \ No newline at end of file diff --git a/exchange/adapter_builders.go b/exchange/adapter_builders.go index 3867cbde72b..3a34e7e5730 100755 --- a/exchange/adapter_builders.go +++ b/exchange/adapter_builders.go @@ -161,6 +161,7 @@ import ( "github.com/prebid/prebid-server/v3/adapters/ownadx" "github.com/prebid/prebid-server/v3/adapters/pangle" "github.com/prebid/prebid-server/v3/adapters/pgamssp" + "github.com/prebid/prebid-server/v3/adapters/pixfuture" "github.com/prebid/prebid-server/v3/adapters/playdigo" "github.com/prebid/prebid-server/v3/adapters/pubmatic" "github.com/prebid/prebid-server/v3/adapters/pubnative" @@ -466,5 +467,6 @@ func newAdapterBuilders() map[openrtb_ext.BidderName]adapters.Builder { openrtb_ext.BidderZeroClickFraud: zeroclickfraud.Builder, openrtb_ext.BidderZetaGlobalSsp: zeta_global_ssp.Builder, openrtb_ext.BidderZmaticoo: zmaticoo.Builder, + openrtb_ext.BidderPixfuture: pixfuture.Builder, } } diff --git a/go.mod b/go.mod index f5d9ee84483..a88e84cf672 100644 --- a/go.mod +++ b/go.mod @@ -36,7 +36,7 @@ require ( github.com/rs/cors v1.11.0 github.com/spf13/cast v1.5.0 github.com/spf13/viper v1.12.0 - github.com/stretchr/testify v1.8.1 + github.com/stretchr/testify v1.10.0 github.com/tidwall/gjson v1.17.1 github.com/tidwall/sjson v1.2.5 github.com/vrischmann/go-metrics-influxdb v0.1.1 @@ -71,7 +71,7 @@ require ( github.com/spf13/afero v1.8.2 // indirect github.com/spf13/jwalterweatherman v1.1.0 // indirect github.com/spf13/pflag v1.0.5 // indirect - github.com/stretchr/objx v0.5.0 // indirect + github.com/stretchr/objx v0.5.2 // indirect github.com/subosito/gotenv v1.3.0 // indirect github.com/tidwall/match v1.1.1 // indirect github.com/tidwall/pretty v1.2.0 // indirect diff --git a/go.sum b/go.sum index c7977cb07ed..fab03baf3b4 100644 --- a/go.sum +++ b/go.sum @@ -410,8 +410,6 @@ github.com/prebid/go-gdpr v1.12.0 h1:OrjQ7Uc+lCRYaOirQ48jjG/PBMvZsKNAaRTgzxN6iZ0 github.com/prebid/go-gdpr v1.12.0/go.mod h1:mPZAdkRxn+iuSjaUuJAi9+0SppBOdM1PCzv/55UH3pY= github.com/prebid/go-gpp v0.2.0 h1:41Ssxd4Zxr50WgwG1q/1+6awGU3pFnwV7FR4XCLQSuM= github.com/prebid/go-gpp v0.2.0/go.mod h1:b0TLoVln+HXFD9L9xeimxIH3FN8WDKPJ42auslxEkow= -github.com/prebid/openrtb/v20 v20.1.0 h1:Rb+Z3H3UxiqqnjgJK3R9Wt73ibrh7HPzG7ikBckQNqc= -github.com/prebid/openrtb/v20 v20.1.0/go.mod h1:hLBrA/APkSrxs5MaW639l+y/EAHivDfRagO2TX/wbSc= github.com/prebid/openrtb/v20 v20.3.0 h1:56z5mIrZ4FdjKxiu3Del0O4890f4AZpvz5PgPLMY1j0= github.com/prebid/openrtb/v20 v20.3.0/go.mod h1:hLBrA/APkSrxs5MaW639l+y/EAHivDfRagO2TX/wbSc= github.com/prometheus/client_golang v0.9.1/go.mod h1:7SWBe2y4D6OKWSNQJUaRYU/AaXPKyh/dDVn+NZz0KFw= @@ -478,8 +476,9 @@ github.com/spf13/viper v1.12.0/go.mod h1:b6COn30jlNxbm/V2IqWiNWkJ+vZNiMNksliPCiu github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= github.com/stretchr/objx v0.1.1/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= github.com/stretchr/objx v0.4.0/go.mod h1:YvHI0jy2hoMjB+UWwv71VJQ9isScKT/TqJzVSSt89Yw= -github.com/stretchr/objx v0.5.0 h1:1zr/of2m5FGMsad5YfcqgdqdWrIhu+EBEJRhR1U7z/c= github.com/stretchr/objx v0.5.0/go.mod h1:Yh+to48EsGEfYuaHDzXPcE3xhTkx73EhmCGUpEOglKo= +github.com/stretchr/objx v0.5.2 h1:xuMeJ0Sdp5ZMRXx/aWO6RZxdr3beISkG5/G/aIRr3pY= +github.com/stretchr/objx v0.5.2/go.mod h1:FRsXN1f5AsAjCGJKqEizvkpNtU+EGNCLh3NxZ/8L+MA= github.com/stretchr/testify v1.2.2/go.mod h1:a8OnRcib4nhh0OaRAV+Yts87kKdq0PP7pXfy6kDkUVs= github.com/stretchr/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UVUgZn+9EI= github.com/stretchr/testify v1.4.0/go.mod h1:j7eGeouHqKxXV5pUuKE4zz7dFj8WfuZ+81PSLYec5m4= @@ -488,8 +487,9 @@ github.com/stretchr/testify v1.6.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/ github.com/stretchr/testify v1.7.0/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= github.com/stretchr/testify v1.7.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= github.com/stretchr/testify v1.8.0/go.mod h1:yNjHg4UonilssWZ8iaSj1OCr/vHnekPRkoO+kdMU+MU= -github.com/stretchr/testify v1.8.1 h1:w7B6lhMri9wdJUVmEZPGGhZzrYTPvgJArz7wNPgYKsk= github.com/stretchr/testify v1.8.1/go.mod h1:w2LPCIKwWwSfY2zedu0+kehJoqGctiVI29o6fzry7u4= +github.com/stretchr/testify v1.10.0 h1:Xv5erBjTwe/5IxqUQTdXv5kgmIvbHo3QQyRwhJsOfJA= +github.com/stretchr/testify v1.10.0/go.mod h1:r2ic/lqez/lEtzL7wO/rwa5dbSLXVDPFyf8C91i36aY= github.com/subosito/gotenv v1.2.0/go.mod h1:N0PQaV/YGNqwC0u51sEeR/aUtSLEXKX9iv69rRypqCw= github.com/subosito/gotenv v1.3.0 h1:mjC+YW8QpAdXibNi+vNWgzmgBH4+5l5dCXv8cNysBLI= github.com/subosito/gotenv v1.3.0/go.mod h1:YzJjq/33h7nrwdY+iHMhEOEEbW0ovIz0tB6t6PwAXzs= diff --git a/openrtb_ext/bidders.go b/openrtb_ext/bidders.go index 894baf9a3bb..c0907c16a79 100644 --- a/openrtb_ext/bidders.go +++ b/openrtb_ext/bidders.go @@ -247,6 +247,7 @@ var coreBidderNames []BidderName = []BidderName{ BidderZeroClickFraud, BidderZetaGlobalSsp, BidderZmaticoo, + BidderPixfuture, } func GetAliasBidderToParent() map[BidderName]BidderName { @@ -589,6 +590,7 @@ const ( BidderZeroClickFraud BidderName = "zeroclickfraud" BidderZetaGlobalSsp BidderName = "zeta_global_ssp" BidderZmaticoo BidderName = "zmaticoo" + BidderPixfuture BidderName = "pixfuture" ) // CoreBidderNames returns a slice of all core bidders. diff --git a/openrtb_ext/imp_pixfuture.go b/openrtb_ext/imp_pixfuture.go new file mode 100644 index 00000000000..55bb062d790 --- /dev/null +++ b/openrtb_ext/imp_pixfuture.go @@ -0,0 +1,5 @@ +package openrtb_ext + +type ImpExtPixfuture struct { + PlacementID string `json:"pix_id"` +} diff --git a/static/bidder-info/pixfuture.yaml b/static/bidder-info/pixfuture.yaml new file mode 100644 index 00000000000..266603010b9 --- /dev/null +++ b/static/bidder-info/pixfuture.yaml @@ -0,0 +1,16 @@ +endpoint: "https://srv-adapter.pixfuture.com/pixservices" +maintainer: + email: "client-support@pixfuture.com" +gvlVendorID: 839 +capabilities: + site: + mediaTypes: + - banner + - video + app: + mediaTypes: + - banner + - video +userSync: + redirect: + url: "https://sync.pixfuture.com/sync?gdpr={{.GDPR}}&consent={{.GDPRConsent}}&us_privacy={{.USPrivacy}}&redirect={{.RedirectURL}}" diff --git a/static/bidder-params/pixfuture.json b/static/bidder-params/pixfuture.json new file mode 100644 index 00000000000..2f06a0ba023 --- /dev/null +++ b/static/bidder-params/pixfuture.json @@ -0,0 +1,16 @@ +{ + "$schema": "http://json-schema.org/draft-04/schema#", + "title": "PixFuture Adapter Params", + "description": "A schema which validates params accepted by the PixFuture adapter", + "type": "object", + + "properties": { + "pix_id": { + "type": "string", + "description": "PixFuture placement ID" + } + }, + + "required": ["pix_id"] + } + \ No newline at end of file