From 9888190824757d0c9adda30b8b2e5da38305cdcf Mon Sep 17 00:00:00 2001 From: Brian Sardo <1168933+bsardo@users.noreply.github.com> Date: Mon, 24 Feb 2025 12:26:05 -0500 Subject: [PATCH 1/6] Upgrade to Go 1.24 (#4234) --- .devcontainer/devcontainer.json | 2 +- .github/workflows/adapter-code-coverage.yml | 2 +- .github/workflows/validate-merge.yml | 2 +- .github/workflows/validate.yml | 2 +- Dockerfile | 4 ++-- README.md | 2 +- go.mod | 2 +- 7 files changed, 8 insertions(+), 8 deletions(-) diff --git a/.devcontainer/devcontainer.json b/.devcontainer/devcontainer.json index d924cdba4f7..1e17a21f4ba 100644 --- a/.devcontainer/devcontainer.json +++ b/.devcontainer/devcontainer.json @@ -6,7 +6,7 @@ "dockerfile": "Dockerfile", "args": { // Update the VARIANT arg to pick a version of Go - "VARIANT": "1.23", + "VARIANT": "1.24", // Options "INSTALL_NODE": "false", "NODE_VERSION": "lts/*" diff --git a/.github/workflows/adapter-code-coverage.yml b/.github/workflows/adapter-code-coverage.yml index 854c2568df2..10dd9e89773 100644 --- a/.github/workflows/adapter-code-coverage.yml +++ b/.github/workflows/adapter-code-coverage.yml @@ -15,7 +15,7 @@ jobs: - name: Install Go uses: actions/setup-go@v5 with: - go-version: 1.23.4 + go-version: 1.24.0 - name: Checkout Code uses: actions/checkout@v4 diff --git a/.github/workflows/validate-merge.yml b/.github/workflows/validate-merge.yml index 2d60ca2d28b..729a17114e1 100644 --- a/.github/workflows/validate-merge.yml +++ b/.github/workflows/validate-merge.yml @@ -12,7 +12,7 @@ jobs: - name: Install Go uses: actions/setup-go@v5 with: - go-version: 1.23.4 + go-version: 1.24.0 - name: Checkout Merged Branch uses: actions/checkout@v4 diff --git a/.github/workflows/validate.yml b/.github/workflows/validate.yml index effb57656f8..3c1e3fac4ea 100644 --- a/.github/workflows/validate.yml +++ b/.github/workflows/validate.yml @@ -10,7 +10,7 @@ jobs: validate: strategy: matrix: - go-version: [1.22.x, 1.23.x] + go-version: [1.23.x, 1.24.x] os: [ubuntu-20.04] runs-on: ${{ matrix.os }} diff --git a/Dockerfile b/Dockerfile index 3e17c3aeec7..c2e8e4d9cf8 100644 --- a/Dockerfile +++ b/Dockerfile @@ -3,8 +3,8 @@ RUN apt-get update && \ apt-get -y upgrade && \ apt-get install -y wget WORKDIR /tmp -RUN wget https://dl.google.com/go/go1.23.4.linux-amd64.tar.gz && \ - tar -xf go1.23.4.linux-amd64.tar.gz && \ +RUN wget https://dl.google.com/go/go1.24.0.linux-amd64.tar.gz && \ + tar -xf go1.24.0.linux-amd64.tar.gz && \ mv go /usr/local RUN mkdir -p /app/prebid-server/ WORKDIR /app/prebid-server/ diff --git a/README.md b/README.md index 9e4fb436728..4c526b47a01 100644 --- a/README.md +++ b/README.md @@ -44,7 +44,7 @@ Ensure that you deploy the `/static` directory, as Prebid Server requires those ## Developing -Prebid Server requires [Go](https://go.dev) version 1.22 or newer. You can develop on any operating system that Go supports; however, please note that our helper scripts are written in bash. +Prebid Server requires [Go](https://go.dev) version 1.23 or newer. You can develop on any operating system that Go supports; however, please note that our helper scripts are written in bash. 1. Clone The Repository ``` bash diff --git a/go.mod b/go.mod index ef05f217116..c8e1d25d309 100644 --- a/go.mod +++ b/go.mod @@ -1,6 +1,6 @@ module github.com/prebid/prebid-server/v3 -go 1.22 +go 1.23 retract v3.0.0 // Forgot to update major version in import path and module name From 3c24bbffd5040a980056a67ffbfe2619eb407c60 Mon Sep 17 00:00:00 2001 From: SmartHubSolutions <87376145+SmartHubSolutions@users.noreply.github.com> Date: Tue, 25 Feb 2025 05:51:25 +0200 Subject: [PATCH 2/6] Attekmi: Remove partnerName param requirement (#4208) --- adapters/smarthub/params_test.go | 8 ++++++-- adapters/smarthub/smarthub.go | 3 ++- static/bidder-params/smarthub.json | 4 +--- 3 files changed, 9 insertions(+), 6 deletions(-) diff --git a/adapters/smarthub/params_test.go b/adapters/smarthub/params_test.go index 96799700710..18616abd0f9 100644 --- a/adapters/smarthub/params_test.go +++ b/adapters/smarthub/params_test.go @@ -9,6 +9,8 @@ import ( var validParams = []string{ `{"partnerName":"partnertest", "seat":"9Q20EdGxzgWdfPYShScl", "token":"eKmw6alpP3zWQhRCe3flOpz0wpuwRFjW"}`, + `{"partnerName":"", "seat":"1", "token":"1"}`, + `{"seat":"1", "token":"1"}`, } func TestValidParams(t *testing.T) { @@ -35,13 +37,15 @@ var invalidParams = []string{ `{"partnerName":"partnertest"}`, `{"seat":"9Q20EdGxzgWdfPYShScl"}`, `{"token":"Y9Evrh40ejsrCR4EtidUt1cSxhJsz8X1"}`, - `{"seat":"9Q20EdGxzgWdfPYShScl", "token":"alNYtemWggraDVbhJrsOs9pXc3Eld32E"}`, `{"partnerName":"partnertest", "token":"LNywdP2ebX5iETF8gvBeEoB6Cam64eeq"}`, `{"partnerName":"partnertest", "seat":"9Q20EdGxzgWdfPYShScl"}`, `{"partnerName":"", "seat":"", "token":""}`, - `{"partnerName":"", "seat":"9Q20EdGxzgWdfPYShScl", "token":"alNYtemWggraDVbhJrsOs9pXc3Eld32E"}`, `{"partnerName":"partnertest", "seat":"9Q20EdGxzgWdfPYShScl", "token":""}`, `{"partnerName":"partnertest", "seat":"", "token":"alNYtemWggraDVbhJrsOs9pXc3Eld32E"}`, + `{"partnerName":""}`, + `{"partnerName":"1"}`, + `{"seat":"1"}`, + `{"token":"1"}`, } func TestInvalidParams(t *testing.T) { diff --git a/adapters/smarthub/smarthub.go b/adapters/smarthub/smarthub.go index 080fe01fd1a..7048bb0cc03 100644 --- a/adapters/smarthub/smarthub.go +++ b/adapters/smarthub/smarthub.go @@ -60,10 +60,11 @@ func (a *adapter) getImpressionExt(imp *openrtb2.Imp) (*openrtb_ext.ExtSmartHub, func (a *adapter) buildEndpointURL(params *openrtb_ext.ExtSmartHub) (string, error) { endpointParams := macros.EndpointTemplateParams{ - Host: params.PartnerName, AccountID: params.Seat, SourceId: params.Token, + Host: params.PartnerName, } + return macros.ResolveMacros(a.endpoint, endpointParams) } diff --git a/static/bidder-params/smarthub.json b/static/bidder-params/smarthub.json index 53d93bddfe8..aba567b560e 100644 --- a/static/bidder-params/smarthub.json +++ b/static/bidder-params/smarthub.json @@ -6,8 +6,7 @@ "properties": { "partnerName": { "type": "string", - "description": "Attekmi (formerly SmartHub) unique partner name", - "minLength": 1 + "description": "Attekmi (formerly SmartHub) unique partner name" }, "seat": { "type": "string", @@ -21,7 +20,6 @@ } }, "required": [ - "partnerName", "seat", "token" ] From 3b4f6a1a489426b1429ec3ae7901b6539dd7843f Mon Sep 17 00:00:00 2001 From: SmartHubSolutions <87376145+SmartHubSolutions@users.noreply.github.com> Date: Tue, 25 Feb 2025 06:00:51 +0200 Subject: [PATCH 3/6] New Adapter: Jambojar - Attekmi (SmartHub) Alias (#4199) --- static/bidder-info/jambojar.yaml | 2 ++ 1 file changed, 2 insertions(+) create mode 100644 static/bidder-info/jambojar.yaml diff --git a/static/bidder-info/jambojar.yaml b/static/bidder-info/jambojar.yaml new file mode 100644 index 00000000000..5ab15a47d4b --- /dev/null +++ b/static/bidder-info/jambojar.yaml @@ -0,0 +1,2 @@ +endpoint: "https://jambojar-prebid.attekmi.com/pbserver/?seat={{.AccountID}}&token={{.SourceId}}" +aliasOf: "smarthub" From 82cdfc4ad7b3085a32c98e95e9195c1ae8c29458 Mon Sep 17 00:00:00 2001 From: SmartHubSolutions <87376145+SmartHubSolutions@users.noreply.github.com> Date: Tue, 25 Feb 2025 17:11:29 +0200 Subject: [PATCH 4/6] New Adapter: Adinify - Attekmi (SmartHub) alias (#4164) --- static/bidder-info/adinify.yaml | 2 ++ 1 file changed, 2 insertions(+) create mode 100644 static/bidder-info/adinify.yaml diff --git a/static/bidder-info/adinify.yaml b/static/bidder-info/adinify.yaml new file mode 100644 index 00000000000..501b54df3f1 --- /dev/null +++ b/static/bidder-info/adinify.yaml @@ -0,0 +1,2 @@ +endpoint: "https://adinify-prebid.attekmi.com/pbserver/?seat={{.AccountID}}&token={{.SourceId}}" +aliasOf: "smarthub" From 63b7d6b1dcdc73484ca01f46fe6f5ac95e16f99e Mon Sep 17 00:00:00 2001 From: SmartHubSolutions <87376145+SmartHubSolutions@users.noreply.github.com> Date: Tue, 25 Feb 2025 18:11:48 +0200 Subject: [PATCH 5/6] New Adapter: Artechnology - Attekmi (SmartHub) alias (#4165) --- static/bidder-info/artechnology.yaml | 2 ++ 1 file changed, 2 insertions(+) create mode 100644 static/bidder-info/artechnology.yaml diff --git a/static/bidder-info/artechnology.yaml b/static/bidder-info/artechnology.yaml new file mode 100644 index 00000000000..07812353363 --- /dev/null +++ b/static/bidder-info/artechnology.yaml @@ -0,0 +1,2 @@ +endpoint: "https://artechnology-prebid.attekmi.com/pbserver/?seat={{.AccountID}}&token={{.SourceId}}" +aliasOf: "smarthub" From 17f40d133486d8b65074cc4ad0b3dc3ab0d8e567 Mon Sep 17 00:00:00 2001 From: sangarbe Date: Tue, 25 Feb 2025 19:02:50 +0100 Subject: [PATCH 6/6] New Adapter: Seedtag (#4198) --- adapters/seedtag/params_test.go | 44 +++++ adapters/seedtag/seedtag.go | 120 +++++++++++++ adapters/seedtag/seedtag_test.go | 20 +++ .../seedtag/seedtagtest/exemplary/banner.json | 129 ++++++++++++++ .../exemplary/bidfloor_converted.json | 157 ++++++++++++++++++ .../seedtag/seedtagtest/exemplary/video.json | 133 +++++++++++++++ .../invalid_bidfloor_conversion.json | 55 ++++++ .../supplemental/invalid_mtype.json | 119 +++++++++++++ .../response_unmarshal_error.json | 113 +++++++++++++ .../supplemental/status_bad_request.json | 69 ++++++++ .../supplemental/status_no_content.json | 63 +++++++ .../supplemental/status_not_ok.json | 69 ++++++++ exchange/adapter_builders.go | 2 + openrtb_ext/bidders.go | 2 + openrtb_ext/imp_seedtag.go | 5 + static/bidder-info/seedtag.yaml | 14 ++ static/bidder-params/seedtag.json | 16 ++ 17 files changed, 1130 insertions(+) create mode 100644 adapters/seedtag/params_test.go create mode 100644 adapters/seedtag/seedtag.go create mode 100644 adapters/seedtag/seedtag_test.go create mode 100644 adapters/seedtag/seedtagtest/exemplary/banner.json create mode 100644 adapters/seedtag/seedtagtest/exemplary/bidfloor_converted.json create mode 100644 adapters/seedtag/seedtagtest/exemplary/video.json create mode 100644 adapters/seedtag/seedtagtest/supplemental/invalid_bidfloor_conversion.json create mode 100644 adapters/seedtag/seedtagtest/supplemental/invalid_mtype.json create mode 100644 adapters/seedtag/seedtagtest/supplemental/response_unmarshal_error.json create mode 100644 adapters/seedtag/seedtagtest/supplemental/status_bad_request.json create mode 100644 adapters/seedtag/seedtagtest/supplemental/status_no_content.json create mode 100644 adapters/seedtag/seedtagtest/supplemental/status_not_ok.json create mode 100644 openrtb_ext/imp_seedtag.go create mode 100644 static/bidder-info/seedtag.yaml create mode 100644 static/bidder-params/seedtag.json diff --git a/adapters/seedtag/params_test.go b/adapters/seedtag/params_test.go new file mode 100644 index 00000000000..b93be85dfb5 --- /dev/null +++ b/adapters/seedtag/params_test.go @@ -0,0 +1,44 @@ +package seedtag + +import ( + "encoding/json" + "testing" + + "github.com/prebid/prebid-server/v3/openrtb_ext" +) + +func TestValidParams(t *testing.T) { + validator, err := openrtb_ext.NewBidderParamsValidator("../../static/bidder-params") + if err != nil { + t.Fatalf("Failed to fetch the json schema. %v", err) + } + + for _, p := range validParams { + if err := validator.Validate(openrtb_ext.BidderSeedtag, json.RawMessage(p)); err != nil { + t.Errorf("Schema rejected valid params: %s", p) + } + } +} + +func TestInvalidParams(t *testing.T) { + validator, err := openrtb_ext.NewBidderParamsValidator("../../static/bidder-params") + if err != nil { + t.Fatalf("Failed to fetch the json schema. %v", err) + } + + for _, p := range invalidParams { + if err := validator.Validate(openrtb_ext.BidderSeedtag, json.RawMessage(p)); err == nil { + t.Errorf("Schema allowed invalid params: %s", p) + } + } +} + +var validParams = []string{ + `{"adUnitId": "27604970"}`, +} + +var invalidParams = []string{ + `{"adUnitId": 123}`, + `{"adUnitId": ""}`, + `{}`, +} diff --git a/adapters/seedtag/seedtag.go b/adapters/seedtag/seedtag.go new file mode 100644 index 00000000000..738d589fed2 --- /dev/null +++ b/adapters/seedtag/seedtag.go @@ -0,0 +1,120 @@ +package seedtag + +import ( + "errors" + "net/http" + "strings" + + "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/prebid/prebid-server/v3/util/jsonutil" +) + +type adapter struct { + endpoint string +} + +// Builder builds a new instance of the Seedtag adapter for the given bidder with the given config. +func Builder(_ openrtb_ext.BidderName, config config.Adapter, server config.Server) (adapters.Bidder, error) { + bidder := &adapter{ + endpoint: config.Endpoint, + } + return bidder, nil +} + +// MakeRequests makes outgoing HTTP requests to Seedtag endpoint. +func (a *adapter) MakeRequests(request *openrtb2.BidRequest, reqInfo *adapters.ExtraRequestInfo) ([]*adapters.RequestData, []error) { + + var errors []error + imps := make([]openrtb2.Imp, 0, len(request.Imp)) + + for _, imp := range request.Imp { + // Convert Floor into USD + if imp.BidFloor > 0 && imp.BidFloorCur != "" && strings.ToUpper(imp.BidFloorCur) != "USD" { + convertedValue, err := reqInfo.ConvertCurrency(imp.BidFloor, imp.BidFloorCur, "USD") + if err != nil { + errors = append(errors, err) + continue + } + + imp.BidFloorCur = "USD" + imp.BidFloor = convertedValue + } + + imps = append(imps, imp) + } + + if len(imps) < 1 { + return nil, errors + } + + requestCopy := *request + requestCopy.Imp = imps + requestJSON, err := jsonutil.Marshal(requestCopy) + if err != nil { + return nil, []error{err} + } + + requestData := &adapters.RequestData{ + Method: http.MethodPost, + Uri: a.endpoint, + Body: requestJSON, + ImpIDs: openrtb_ext.GetImpIDs(requestCopy.Imp), + } + + return []*adapters.RequestData{requestData}, errors +} + +// MakeBids unpacks the server's response into Bids. +func (a *adapter) MakeBids(request *openrtb2.BidRequest, requestData *adapters.RequestData, responseData *adapters.ResponseData) (*adapters.BidderResponse, []error) { + if adapters.IsResponseStatusCodeNoContent(responseData) { + return nil, nil + } + + err := adapters.CheckResponseStatusCodeForErrors(responseData) + if err != nil { + return nil, []error{err} + } + + var response openrtb2.BidResponse + if err := jsonutil.Unmarshal(responseData.Body, &response); err != nil { + return nil, []error{err} + } + + bidResponse := adapters.NewBidderResponseWithBidsCapacity(len(requestData.ImpIDs)) + + var errs []error + + for _, seatBid := range response.SeatBid { + for i := range seatBid.Bid { + bid := &seatBid.Bid[i] + + bidType, err := getMediaTypeForBid(*bid) + if err != nil { + errs = append(errs, err) + continue + } + + bidResponse.Bids = append(bidResponse.Bids, &adapters.TypedBid{ + Bid: bid, + BidType: bidType, + }) + } + } + + return bidResponse, errs +} + +func getMediaTypeForBid(bid openrtb2.Bid) (openrtb_ext.BidType, error) { + switch bid.MType { + case 1: + return openrtb_ext.BidTypeBanner, nil + case 2: + return openrtb_ext.BidTypeVideo, nil + default: + return "", errors.New("bid.MType invalid") + } + +} diff --git a/adapters/seedtag/seedtag_test.go b/adapters/seedtag/seedtag_test.go new file mode 100644 index 00000000000..bdfbc7725e9 --- /dev/null +++ b/adapters/seedtag/seedtag_test.go @@ -0,0 +1,20 @@ +package seedtag + +import ( + "testing" + + "github.com/prebid/prebid-server/v3/adapters/adapterstest" + "github.com/prebid/prebid-server/v3/config" + "github.com/prebid/prebid-server/v3/openrtb_ext" +) + +func TestJsonSamples(t *testing.T) { + bidder, buildErr := Builder(openrtb_ext.BidderSeedtag, config.Adapter{ + Endpoint: "http://url.seedtag.com"}, config.Server{ExternalUrl: "http://hosturl.com", GvlID: 1, DataCenter: "2"}) + + if buildErr != nil { + t.Fatalf("builder returned unexpected error %v", buildErr) + } + + adapterstest.RunJSONBidderTest(t, "seedtagtest", bidder) +} diff --git a/adapters/seedtag/seedtagtest/exemplary/banner.json b/adapters/seedtag/seedtagtest/exemplary/banner.json new file mode 100644 index 00000000000..94b3ef7bf40 --- /dev/null +++ b/adapters/seedtag/seedtagtest/exemplary/banner.json @@ -0,0 +1,129 @@ +{ + "mockBidRequest": { + "id": "test-request-id", + "site": { + "publisher": { + "id": "foo", + "name": "foo" + } + }, + "imp": [ + { + "id": "test-imp-id", + "banner": { + "format": [ + { + "w": 300, + "h": 250 + }, + { + "w": 300, + "h": 600 + } + ] + }, + "ext": { + "bidder": { + "adUnitId": "example-tag-id" + } + } + } + ] + }, + "httpCalls": [ + { + "expectedRequest": { + "uri": "http://url.seedtag.com", + "body": { + "id": "test-request-id", + "imp": [ + { + "id": "test-imp-id", + "banner": { + "format": [ + { + "w": 300, + "h": 250 + }, + { + "w": 300, + "h": 600 + } + ] + }, + "ext": { + "bidder": { + "adUnitId": "example-tag-id" + } + } + } + ], + "site": { + "publisher": { + "id": "foo", + "name": "foo" + } + } + }, + "impIDs":["test-imp-id"] + }, + "mockResponse": { + "status": 200, + "body": { + "id": "test-request-id", + "seatbid": [ + { + "seat": "123", + "bid": [ + { + "id": "7706636740145184841", + "impid": "test-imp-id", + "price": 0.5, + "adid": "12341234", + "adm": "some-test-ad", + "adomain": [ + "domain.com" + ], + "iurl": "http://abc.com/cr?id=12341234", + "cid": "123", + "crid": "12341234", + "h": 250, + "w": 300, + "mtype": 1 + } + ] + } + ], + "bidid": "5778926625248726496", + "cur": "USD" + } + } + } + ], + "expectedBidResponses": [ + { + "currency": "USD", + "bids": [ + { + "bid": { + "id": "7706636740145184841", + "impid": "test-imp-id", + "price": 0.5, + "adm": "some-test-ad", + "adid": "12341234", + "adomain": [ + "domain.com" + ], + "iurl": "http://abc.com/cr?id=12341234", + "cid": "123", + "crid": "12341234", + "w": 300, + "h": 250, + "mtype": 1 + }, + "type": "banner" + } + ] + } + ] +} \ No newline at end of file diff --git a/adapters/seedtag/seedtagtest/exemplary/bidfloor_converted.json b/adapters/seedtag/seedtagtest/exemplary/bidfloor_converted.json new file mode 100644 index 00000000000..5992a589679 --- /dev/null +++ b/adapters/seedtag/seedtagtest/exemplary/bidfloor_converted.json @@ -0,0 +1,157 @@ +{ + "mockBidRequest": { + "id": "test-request-id", + "site": { + "publisher": { + "id": "foo", + "name": "foo" + } + }, + "imp": [ + { + "id": "test-imp-id", + "banner": { + "format": [ + { + "w": 300, + "h": 250 + }, + { + "w": 300, + "h": 600 + } + ] + }, + "ext": { + "bidder": { + "adUnitId": "example-tag-id" + } + }, + "bidfloor": 0.5, + "bidfloorcur": "EUR" + } + ], + "ext": { + "prebid": { + "currency": { + "rates": { + "EUR": { + "USD": 0.05 + } + }, + "usepbsrates": false + } + } + } + }, + "httpCalls": [ + { + "expectedRequest": { + "uri": "http://url.seedtag.com", + "body": { + "id": "test-request-id", + "imp": [ + { + "id": "test-imp-id", + "banner": { + "format": [ + { + "w": 300, + "h": 250 + }, + { + "w": 300, + "h": 600 + } + ] + }, + "ext": { + "bidder": { + "adUnitId": "example-tag-id" + } + }, + "bidfloor": 0.025, + "bidfloorcur": "USD" + } + ], + "site": { + "publisher": { + "id": "foo", + "name": "foo" + } + }, + "ext": { + "prebid": { + "currency": { + "rates": { + "EUR": { + "USD": 0.05 + } + }, + "usepbsrates": false + } + } + } + }, + "impIDs":["test-imp-id"] + }, + "mockResponse": { + "status": 200, + "body": { + "id": "test-request-id", + "seatbid": [ + { + "seat": "123", + "bid": [ + { + "id": "7706636740145184841", + "impid": "test-imp-id", + "price": 0.5, + "adid": "12341234", + "adm": "some-test-ad", + "adomain": [ + "domain.com" + ], + "iurl": "http://abc.com/cr?id=12341234", + "cid": "123", + "crid": "12341234", + "h": 250, + "w": 300, + "mtype": 1 + } + ] + } + ], + "bidid": "5778926625248726496", + "cur": "USD" + } + } + } + ], + "expectedBidResponses": [ + { + "currency": "USD", + "bids": [ + { + "bid": { + "id": "7706636740145184841", + "impid": "test-imp-id", + "price": 0.5, + "adm": "some-test-ad", + "adid": "12341234", + "adomain": [ + "domain.com" + ], + "iurl": "http://abc.com/cr?id=12341234", + "cid": "123", + "crid": "12341234", + "w": 300, + "h": 250, + "mtype": 1 + }, + "type": "banner" + } + ] + } + ] +} \ No newline at end of file diff --git a/adapters/seedtag/seedtagtest/exemplary/video.json b/adapters/seedtag/seedtagtest/exemplary/video.json new file mode 100644 index 00000000000..c6c1f49c8da --- /dev/null +++ b/adapters/seedtag/seedtagtest/exemplary/video.json @@ -0,0 +1,133 @@ +{ + "mockBidRequest": { + "id": "test-request-id", + "site": { + "publisher": { + "id": "foo", + "name": "foo" + } + }, + "imp": [ + { + "id": "test-imp-id", + "video": { + "mimes": [ + "video/mp4", + "video/3gpp", + "video/x-ms-wmv" + ], + "maxduration": 30, + "protocols": [ + 4, + 5, + 6, + 8 + ] + }, + "ext": { + "bidder": { + "adUnitId": "example-tag-id" + } + } + } + ] + }, + "httpCalls": [ + { + "expectedRequest": { + "uri": "http://url.seedtag.com", + "body": { + "id": "test-request-id", + "imp": [ + { + "id": "test-imp-id", + "video": { + "mimes": [ + "video/mp4", + "video/3gpp", + "video/x-ms-wmv" + ], + "maxduration": 30, + "protocols": [ + 4, + 5, + 6, + 8 + ] + }, + "ext": { + "bidder": { + "adUnitId": "example-tag-id" + } + } + } + ], + "site": { + "publisher": { + "id": "foo", + "name": "foo" + } + } + }, + "impIDs":["test-imp-id"] + }, + "mockResponse": { + "status": 200, + "body": { + "id": "test-request-id", + "seatbid": [ + { + "seat": "123", + "bid": [ + { + "id": "7706636740145184841", + "impid": "test-imp-id", + "price": 0.5, + "adid": "12341234", + "adm": "some-test-ad", + "adomain": [ + "domain.com" + ], + "iurl": "http://abc.com/cr?id=12341234", + "cid": "123", + "crid": "12341234", + "h": 250, + "w": 300, + "mtype": 2 + } + ] + } + ], + "bidid": "5778926625248726496", + "cur": "USD" + } + } + } + ], + "expectedBidResponses": [ + { + "currency": "USD", + "bids": [ + { + "bid": { + "id": "7706636740145184841", + "impid": "test-imp-id", + "price": 0.5, + "adm": "some-test-ad", + "adid": "12341234", + "adomain": [ + "domain.com" + ], + "iurl": "http://abc.com/cr?id=12341234", + "cid": "123", + "crid": "12341234", + "w": 300, + "h": 250, + "mtype": 2 + }, + "type": "video" + } + ] + } + ] +} \ No newline at end of file diff --git a/adapters/seedtag/seedtagtest/supplemental/invalid_bidfloor_conversion.json b/adapters/seedtag/seedtagtest/supplemental/invalid_bidfloor_conversion.json new file mode 100644 index 00000000000..b853ff00c4c --- /dev/null +++ b/adapters/seedtag/seedtagtest/supplemental/invalid_bidfloor_conversion.json @@ -0,0 +1,55 @@ +{ + "mockBidRequest": { + "id": "test-request-id", + "site": { + "publisher": { + "id": "foo", + "name": "foo" + } + }, + "imp": [ + { + "id": "test-imp-id", + "video": { + "mimes": [ + "video/mp4", + "video/3gpp", + "video/x-ms-wmv" + ], + "maxduration": 30, + "protocols": [ + 4, + 5, + 6, + 8 + ] + }, + "ext": { + "bidder": { + "adUnitId": "example-tag-id" + } + }, + "bidfloor": 0.5, + "bidfloorcur": "JPY" + } + ], + "ext": { + "prebid": { + "currency": { + "rates": { + "MXN": { + "USD": 0.05 + } + }, + "usepbsrates": false + } + } + } + }, + "expectedMakeRequestsErrors": [ + { + "value": "Currency conversion rate not found: 'JPY' => 'USD'", + "comparison": "literal" + } + ] +} \ No newline at end of file diff --git a/adapters/seedtag/seedtagtest/supplemental/invalid_mtype.json b/adapters/seedtag/seedtagtest/supplemental/invalid_mtype.json new file mode 100644 index 00000000000..636cb0ce97f --- /dev/null +++ b/adapters/seedtag/seedtagtest/supplemental/invalid_mtype.json @@ -0,0 +1,119 @@ +{ + "mockBidRequest": { + "id": "test-request-id", + "site": { + "publisher": { + "id": "foo", + "name": "foo" + } + }, + "imp": [ + { + "id": "test-imp-id", + "video": { + "mimes": [ + "video/mp4", + "video/3gpp", + "video/x-ms-wmv" + ], + "maxduration": 30, + "protocols": [ + 4, + 5, + 6, + 8 + ] + }, + "ext": { + "bidder": { + "adUnitId": "example-tag-id" + } + } + } + ] + }, + "httpCalls": [ + { + "expectedRequest": { + "uri": "http://url.seedtag.com", + "body": { + "id": "test-request-id", + "imp": [ + { + "id": "test-imp-id", + "video": { + "mimes": [ + "video/mp4", + "video/3gpp", + "video/x-ms-wmv" + ], + "maxduration": 30, + "protocols": [ + 4, + 5, + 6, + 8 + ] + }, + "ext": { + "bidder": { + "adUnitId": "example-tag-id" + } + } + } + ], + "site": { + "publisher": { + "id": "foo", + "name": "foo" + } + } + }, + "impIDs":["test-imp-id"] + }, + "mockResponse": { + "status": 200, + "body": { + "id": "test-request-id", + "seatbid": [ + { + "seat": "123", + "bid": [ + { + "id": "7706636740145184841", + "impid": "test-imp-id", + "price": 0.5, + "adid": "12341234", + "adm": "some-test-ad", + "adomain": [ + "domain.com" + ], + "iurl": "http://abc.com/cr?id=12341234", + "cid": "123", + "crid": "12341234", + "h": 250, + "w": 300, + "mtype": 0 + } + ] + } + ], + "bidid": "5778926625248726496", + "cur": "USD" + } + } + } + ], + "expectedBidResponses": [ + { + "currency": "USD", + "bids": [] + } + ], + "expectedMakeBidsErrors": [ + { + "value": "bid.MType invalid", + "comparison": "literal" + } + ] +} \ No newline at end of file diff --git a/adapters/seedtag/seedtagtest/supplemental/response_unmarshal_error.json b/adapters/seedtag/seedtagtest/supplemental/response_unmarshal_error.json new file mode 100644 index 00000000000..de60e366d48 --- /dev/null +++ b/adapters/seedtag/seedtagtest/supplemental/response_unmarshal_error.json @@ -0,0 +1,113 @@ +{ + "mockBidRequest": { + "id": "test-request-id", + "site": { + "publisher": { + "id": "foo", + "name": "foo" + } + }, + "imp": [ + { + "id": "test-imp-id", + "video": { + "mimes": [ + "video/mp4", + "video/3gpp", + "video/x-ms-wmv" + ], + "maxduration": 30, + "protocols": [ + 4, + 5, + 6, + 8 + ] + }, + "ext": { + "bidder": { + "adUnitId": "example-tag-id" + } + } + } + ] + }, + "httpCalls": [ + { + "expectedRequest": { + "uri": "http://url.seedtag.com", + "body": { + "id": "test-request-id", + "imp": [ + { + "id": "test-imp-id", + "video": { + "mimes": [ + "video/mp4", + "video/3gpp", + "video/x-ms-wmv" + ], + "maxduration": 30, + "protocols": [ + 4, + 5, + 6, + 8 + ] + }, + "ext": { + "bidder": { + "adUnitId": "example-tag-id" + } + } + } + ], + "site": { + "publisher": { + "id": "foo", + "name": "foo" + } + } + }, + "impIDs":["test-imp-id"] + }, + "mockResponse": { + "status": 200, + "body": { + "id": "test-request-id", + "seatbid": [ + { + "seat": "123", + "bid": [ + { + "id": "7706636740145184841", + "impid": "test-imp-id", + "price": 0.5, + "adid": "12341234", + "adm": "some-test-ad", + "adomain": [ + "domain.com" + ], + "iurl": "http://abc.com/cr?id=12341234", + "cid": "123", + "crid": "12341234", + "h": 250, + "w": 300, + "mtype": "video" + } + ] + } + ], + "bidid": "5778926625248726496", + "cur": "USD" + } + } + } + ], + "expectedMakeBidsErrors": [ + { + "value": "cannot unmarshal", + "comparison": "startswith" + } + ] +} \ No newline at end of file diff --git a/adapters/seedtag/seedtagtest/supplemental/status_bad_request.json b/adapters/seedtag/seedtagtest/supplemental/status_bad_request.json new file mode 100644 index 00000000000..8cd058864ed --- /dev/null +++ b/adapters/seedtag/seedtagtest/supplemental/status_bad_request.json @@ -0,0 +1,69 @@ +{ + "mockBidRequest": { + "id": "test-request-id", + "imp": [ + { + "id": "test-imp-id", + "banner": { + "format": [ + { + "w": 300, + "h": 250 + }, + { + "w": 300, + "h": 600 + } + ] + }, + "ext": { + "bidder": { + "adUnitId": "example-tag-id" + } + } + } + ] + }, + "httpCalls": [ + { + "expectedRequest": { + "uri": "http://url.seedtag.com", + "body": { + "id": "test-request-id", + "imp": [ + { + "id": "test-imp-id", + "banner": { + "format": [ + { + "w": 300, + "h": 250 + }, + { + "w": 300, + "h": 600 + } + ] + }, + "ext": { + "bidder": { + "adUnitId": "example-tag-id" + } + } + } + ] + }, + "impIDs":["test-imp-id"] + }, + "mockResponse": { + "status": 400 + } + } + ], + "expectedMakeBidsErrors": [ + { + "value": "Unexpected status code: 400. Run with request.debug = 1 for more info", + "comparison": "literal" + } + ] +} \ No newline at end of file diff --git a/adapters/seedtag/seedtagtest/supplemental/status_no_content.json b/adapters/seedtag/seedtagtest/supplemental/status_no_content.json new file mode 100644 index 00000000000..aa415e17ed8 --- /dev/null +++ b/adapters/seedtag/seedtagtest/supplemental/status_no_content.json @@ -0,0 +1,63 @@ +{ + "mockBidRequest": { + "id": "test-request-id", + "imp": [ + { + "id": "test-imp-id", + "banner": { + "format": [ + { + "w": 300, + "h": 250 + }, + { + "w": 300, + "h": 600 + } + ] + }, + "ext": { + "bidder": { + "adUnitId": "example-tag-id" + } + } + } + ] + }, + "httpCalls": [ + { + "expectedRequest": { + "uri": "http://url.seedtag.com", + "body": { + "id": "test-request-id", + "imp": [ + { + "id": "test-imp-id", + "banner": { + "format": [ + { + "w": 300, + "h": 250 + }, + { + "w": 300, + "h": 600 + } + ] + }, + "ext": { + "bidder": { + "adUnitId": "example-tag-id" + } + } + } + ] + }, + "impIDs":["test-imp-id"] + }, + "mockResponse": { + "status": 204 + } + } + ] +} \ No newline at end of file diff --git a/adapters/seedtag/seedtagtest/supplemental/status_not_ok.json b/adapters/seedtag/seedtagtest/supplemental/status_not_ok.json new file mode 100644 index 00000000000..a5d8f80b414 --- /dev/null +++ b/adapters/seedtag/seedtagtest/supplemental/status_not_ok.json @@ -0,0 +1,69 @@ +{ + "mockBidRequest": { + "id": "test-request-id", + "imp": [ + { + "id": "test-imp-id", + "banner": { + "format": [ + { + "w": 300, + "h": 250 + }, + { + "w": 300, + "h": 600 + } + ] + }, + "ext": { + "bidder": { + "adUnitId": "example-tag-id" + } + } + } + ] + }, + "httpCalls": [ + { + "expectedRequest": { + "uri": "http://url.seedtag.com", + "body": { + "id": "test-request-id", + "imp": [ + { + "id": "test-imp-id", + "banner": { + "format": [ + { + "w": 300, + "h": 250 + }, + { + "w": 300, + "h": 600 + } + ] + }, + "ext": { + "bidder": { + "adUnitId": "example-tag-id" + } + } + } + ] + }, + "impIDs":["test-imp-id"] + }, + "mockResponse": { + "status": 404 + } + } + ], + "expectedMakeBidsErrors": [ + { + "value": "Unexpected status code: 404. Run with request.debug = 1 for more info", + "comparison": "literal" + } + ] +} \ No newline at end of file diff --git a/exchange/adapter_builders.go b/exchange/adapter_builders.go index f9f33a18ce3..7647de71786 100755 --- a/exchange/adapter_builders.go +++ b/exchange/adapter_builders.go @@ -188,6 +188,7 @@ import ( salunamedia "github.com/prebid/prebid-server/v3/adapters/sa_lunamedia" "github.com/prebid/prebid-server/v3/adapters/screencore" "github.com/prebid/prebid-server/v3/adapters/seedingAlliance" + "github.com/prebid/prebid-server/v3/adapters/seedtag" "github.com/prebid/prebid-server/v3/adapters/sharethrough" "github.com/prebid/prebid-server/v3/adapters/silvermob" "github.com/prebid/prebid-server/v3/adapters/silverpush" @@ -435,6 +436,7 @@ func newAdapterBuilders() map[openrtb_ext.BidderName]adapters.Builder { openrtb_ext.BidderRTBHouse: rtbhouse.Builder, openrtb_ext.BidderRubicon: rubicon.Builder, openrtb_ext.BidderSeedingAlliance: seedingAlliance.Builder, + openrtb_ext.BidderSeedtag: seedtag.Builder, openrtb_ext.BidderSaLunaMedia: salunamedia.Builder, openrtb_ext.BidderScreencore: screencore.Builder, openrtb_ext.BidderSharethrough: sharethrough.Builder, diff --git a/openrtb_ext/bidders.go b/openrtb_ext/bidders.go index 2d42fdfb694..10755dfd7fd 100644 --- a/openrtb_ext/bidders.go +++ b/openrtb_ext/bidders.go @@ -204,6 +204,7 @@ var coreBidderNames []BidderName = []BidderName{ BidderRTBHouse, BidderRubicon, BidderSeedingAlliance, + BidderSeedtag, BidderSaLunaMedia, BidderScreencore, BidderSharethrough, @@ -557,6 +558,7 @@ const ( BidderRTBHouse BidderName = "rtbhouse" BidderRubicon BidderName = "rubicon" BidderSeedingAlliance BidderName = "seedingAlliance" + BidderSeedtag BidderName = "seedtag" BidderSaLunaMedia BidderName = "sa_lunamedia" BidderScreencore BidderName = "screencore" BidderSharethrough BidderName = "sharethrough" diff --git a/openrtb_ext/imp_seedtag.go b/openrtb_ext/imp_seedtag.go new file mode 100644 index 00000000000..825595dd291 --- /dev/null +++ b/openrtb_ext/imp_seedtag.go @@ -0,0 +1,5 @@ +package openrtb_ext + +type ImpExtSeedtag struct { + AdUnitID string `json:"adUnitId"` +} diff --git a/static/bidder-info/seedtag.yaml b/static/bidder-info/seedtag.yaml new file mode 100644 index 00000000000..20df62ff0e4 --- /dev/null +++ b/static/bidder-info/seedtag.yaml @@ -0,0 +1,14 @@ +endpoint: "https://s.seedtag.com/c/openrtb?partner=prebidserver" +endpointCompression: gzip +maintainer: + email: prebid@seedtag.com +gvlVendorID: 157 +capabilities: + site: + mediaTypes: + - video + - banner +userSync: + iframe: + url: "https://s.seedtag.com/cs/cookiesync/prebid?gdpr={{.GDPR}}&gdpr_consent={{.GDPRConsent}}&usp_consent={{.USPrivacy}}&redirect={{.RedirectURL}}" + userMacro: "$UID" diff --git a/static/bidder-params/seedtag.json b/static/bidder-params/seedtag.json new file mode 100644 index 00000000000..7f361c44f9e --- /dev/null +++ b/static/bidder-params/seedtag.json @@ -0,0 +1,16 @@ +{ + "$schema": "http://json-schema.org/draft-04/schema#", + "title": "Seedtag Adapter Params", + "description": "A schema which validates params accepted by the Seedtag adapter", + "type": "object", + "properties": { + "adUnitId": { + "type": "string", + "description": "Ad Unit ID", + "minLength": 1 + } + }, + "required": [ + "adUnitId" + ] +} \ No newline at end of file