From 33714f275908f709738689681d9b12cdcdd06e6b Mon Sep 17 00:00:00 2001 From: ownAdx <135326256+ownAdx-prebid@users.noreply.github.com> Date: Wed, 26 Jul 2023 20:49:57 +0530 Subject: [PATCH] New Adapter: OwnAdX (#2850) Co-authored by @ownAdx-prebid --- adapters/ownadx/ownadx.go | 213 ++++++++++++++++++ adapters/ownadx/ownadx_test.go | 17 ++ .../ownadx/ownadxtest/exemplary/banner.json | 166 ++++++++++++++ .../ownadx/ownadxtest/exemplary/video.json | 196 ++++++++++++++++ .../supplemental/bad-server-response.json | 108 +++++++++ .../ownadxtest/supplemental/bid-empty-.json | 118 ++++++++++ .../ownadxtest/supplemental/bidext-type.json | 141 ++++++++++++ .../supplemental/http-status-204.json | 51 +++++ .../supplemental/http-status-400.json | 57 +++++ .../supplemental/invalid-req-empty-imp.json | 34 +++ .../supplemental/invalid-req-imp-ext.json | 47 ++++ .../invalid-req-imp.ext.bidder.json | 49 ++++ .../supplemental/seatbid-empty-.json | 113 ++++++++++ .../supplemental/unexpected-status.json | 107 +++++++++ exchange/adapter_builders.go | 2 + openrtb_ext/bidders.go | 2 + openrtb_ext/imp_ownadx.go | 7 + static/bidder-info/ownadx.yaml | 12 + static/bidder-params/ownadx.json | 27 +++ 19 files changed, 1467 insertions(+) create mode 100644 adapters/ownadx/ownadx.go create mode 100644 adapters/ownadx/ownadx_test.go create mode 100644 adapters/ownadx/ownadxtest/exemplary/banner.json create mode 100644 adapters/ownadx/ownadxtest/exemplary/video.json create mode 100644 adapters/ownadx/ownadxtest/supplemental/bad-server-response.json create mode 100644 adapters/ownadx/ownadxtest/supplemental/bid-empty-.json create mode 100644 adapters/ownadx/ownadxtest/supplemental/bidext-type.json create mode 100644 adapters/ownadx/ownadxtest/supplemental/http-status-204.json create mode 100644 adapters/ownadx/ownadxtest/supplemental/http-status-400.json create mode 100644 adapters/ownadx/ownadxtest/supplemental/invalid-req-empty-imp.json create mode 100644 adapters/ownadx/ownadxtest/supplemental/invalid-req-imp-ext.json create mode 100644 adapters/ownadx/ownadxtest/supplemental/invalid-req-imp.ext.bidder.json create mode 100644 adapters/ownadx/ownadxtest/supplemental/seatbid-empty-.json create mode 100644 adapters/ownadx/ownadxtest/supplemental/unexpected-status.json create mode 100644 openrtb_ext/imp_ownadx.go create mode 100644 static/bidder-info/ownadx.yaml create mode 100644 static/bidder-params/ownadx.json diff --git a/adapters/ownadx/ownadx.go b/adapters/ownadx/ownadx.go new file mode 100644 index 00000000000..c19343ba47f --- /dev/null +++ b/adapters/ownadx/ownadx.go @@ -0,0 +1,213 @@ +package ownadx + +import ( + "encoding/json" + "fmt" + "github.com/prebid/openrtb/v19/openrtb2" + "github.com/prebid/prebid-server/adapters" + "github.com/prebid/prebid-server/config" + "github.com/prebid/prebid-server/errortypes" + "github.com/prebid/prebid-server/macros" + "github.com/prebid/prebid-server/openrtb_ext" + "net/http" + "text/template" +) + +type adapter struct { + endpoint *template.Template +} +type bidExt struct { + MediaType string `json:"mediaType"` +} + +func (adapter *adapter) getRequestData(bidRequest *openrtb2.BidRequest, impExt *openrtb_ext.ExtImpOwnAdx, imps []openrtb2.Imp) (*adapters.RequestData, error) { + pbidRequest := createBidRequest(bidRequest, imps) + reqJSON, err := json.Marshal(pbidRequest) + if err != nil { + return nil, &errortypes.BadInput{ + Message: "Prebid bidder request not valid or can't be marshalled. Err: " + err.Error(), + } + } + url, err := adapter.buildEndpointURL(impExt) + if err != nil { + return nil, &errortypes.BadInput{ + Message: "Error while creating endpoint. Err: " + err.Error(), + } + } + + headers := http.Header{} + headers.Add("Content-Type", "application/json;charset=utf-8") + headers.Add("Accept", "application/json") + headers.Add("x-openrtb-version", "2.5") + + return &adapters.RequestData{ + Method: "POST", + Uri: url, + Body: reqJSON, + Headers: headers}, nil + +} +func createBidRequest(rtbBidRequest *openrtb2.BidRequest, imps []openrtb2.Imp) *openrtb2.BidRequest { + bidRequest := *rtbBidRequest + bidRequest.Imp = imps + return &bidRequest +} +func (adapter *adapter) buildEndpointURL(params *openrtb_ext.ExtImpOwnAdx) (string, error) { + endpointParams := macros.EndpointTemplateParams{ + ZoneID: params.SspId, + AccountID: params.SeatId, + SourceId: params.TokenId, + } + return macros.ResolveMacros(adapter.endpoint, endpointParams) +} + +func getImpressionExt(imp *openrtb2.Imp) (*openrtb_ext.ExtImpOwnAdx, error) { + var bidderExt adapters.ExtImpBidder + if err := json.Unmarshal(imp.Ext, &bidderExt); err != nil { + return nil, &errortypes.BadInput{ + Message: "Bidder extension not valid or can't be unmarshalled", + } + } + + var ownAdxExt openrtb_ext.ExtImpOwnAdx + if err := json.Unmarshal(bidderExt.Bidder, &ownAdxExt); err != nil { + return nil, &errortypes.BadInput{ + Message: "Error while unmarshaling bidder extension", + } + } + + return &ownAdxExt, nil +} + +func (adapter *adapter) MakeRequests(request *openrtb2.BidRequest, reqInfo *adapters.ExtraRequestInfo) ([]*adapters.RequestData, []error) { + + errs := make([]error, 0, len(request.Imp)) + if len(request.Imp) == 0 { + errs = append(errs, &errortypes.BadInput{ + Message: "No impression in the bid request"}, + ) + return nil, errs + } + extImps, errors := groupImpsByExt(request.Imp) + if len(errors) != 0 { + errs = append(errs, errors...) + } + if len(extImps) == 0 { + return nil, errs + } + reqDetail := make([]*adapters.RequestData, 0, len(extImps)) + for k, imps := range extImps { + bidRequest, err := adapter.getRequestData(request, &k, imps) + if err != nil { + errs = append(errs, err) + } else { + reqDetail = append(reqDetail, bidRequest) + } + } + return reqDetail, errs +} +func groupImpsByExt(imps []openrtb2.Imp) (map[openrtb_ext.ExtImpOwnAdx][]openrtb2.Imp, []error) { + respExt := make(map[openrtb_ext.ExtImpOwnAdx][]openrtb2.Imp) + errors := make([]error, 0, len(imps)) + for _, imp := range imps { + ownAdxExt, err := getImpressionExt(&(imp)) + if err != nil { + errors = append(errors, err) + continue + } + + respExt[*ownAdxExt] = append(respExt[*ownAdxExt], imp) + } + return respExt, errors +} + +func (adapter *adapter) MakeBids(internalRequest *openrtb2.BidRequest, externalRequest *adapters.RequestData, response *adapters.ResponseData) (*adapters.BidderResponse, []error) { + if response.StatusCode == http.StatusNoContent { + return nil, nil + } + if response.StatusCode == http.StatusBadRequest { + return nil, []error{ + &errortypes.BadServerResponse{ + Message: fmt.Sprintf("Bad request: %d", response.StatusCode), + }, + } + } + if response.StatusCode != http.StatusOK { + return nil, []error{ + &errortypes.BadServerResponse{ + Message: fmt.Sprintf("Unexpected status code: %d. Run with request.test = 1 for more info.", response.StatusCode), + }, + } + } + var bidResp openrtb2.BidResponse + if err := json.Unmarshal(response.Body, &bidResp); err != nil { + return nil, []error{ + &errortypes.BadServerResponse{ + Message: fmt.Sprintf("Bad server response "), + }, + } + } + if len(bidResp.SeatBid) == 0 { + return nil, []error{ + &errortypes.BadServerResponse{ + Message: fmt.Sprintf("Array SeatBid cannot be empty "), + }, + } + } + + seatBid := bidResp.SeatBid[0] + bidResponse := adapters.NewBidderResponseWithBidsCapacity(len(bidResp.SeatBid[0].Bid)) + if len(seatBid.Bid) == 0 { + return nil, []error{ + &errortypes.BadServerResponse{ + Message: fmt.Sprintf("Bid cannot be empty "), + }, + } + } + for i := 0; i < len(seatBid.Bid); i++ { + var bidType openrtb_ext.BidType + bid := seatBid.Bid[i] + + bidType, err := getMediaType(bid) + if err != nil { + return nil, []error{&errortypes.BadServerResponse{ + Message: "Bid type is invalid", + }} + } + bidResponse.Bids = append(bidResponse.Bids, &adapters.TypedBid{ + Bid: &bid, + BidType: bidType, + }) + } + + return bidResponse, nil +} + +// Builder builds a new instance of the OwnAdx adapter for the given bidder with the given config +func Builder(bidderName openrtb_ext.BidderName, config config.Adapter, server config.Server) (adapters.Bidder, error) { + template, err := template.New("endpointTemplate").Parse(config.Endpoint) + if err != nil { + return nil, fmt.Errorf("unable to parse endpoint url template: %v", err) + } + + bidder := &adapter{ + endpoint: template, + } + + return bidder, nil +} + +func getMediaType(bid openrtb2.Bid) (openrtb_ext.BidType, error) { + switch bid.MType { + case openrtb2.MarkupBanner: + return openrtb_ext.BidTypeBanner, nil + case openrtb2.MarkupVideo: + return openrtb_ext.BidTypeVideo, nil + case openrtb2.MarkupAudio: + return openrtb_ext.BidTypeAudio, nil + case openrtb2.MarkupNative: + return openrtb_ext.BidTypeNative, nil + default: + return "", fmt.Errorf("invalid BidType: %d", bid.MType) + } +} diff --git a/adapters/ownadx/ownadx_test.go b/adapters/ownadx/ownadx_test.go new file mode 100644 index 00000000000..9bd7ba70353 --- /dev/null +++ b/adapters/ownadx/ownadx_test.go @@ -0,0 +1,17 @@ +package ownadx + +import ( + "github.com/prebid/prebid-server/adapters/adapterstest" + "github.com/prebid/prebid-server/config" + "github.com/prebid/prebid-server/openrtb_ext" + "github.com/stretchr/testify/assert" + "testing" +) + +func TestJsonSamples(t *testing.T) { + bidder, buildErr := Builder(openrtb_ext.BidderOwnAdx, config.Adapter{ + Endpoint: "https://pbs.prebid-ownadx.com/bidder/bid/{{.AccountID}}/{{.ZoneID}}?token={{.SourceId}}"}, config.Server{ExternalUrl: "http://hosturl.com", GvlID: 1, DataCenter: "2"}) + + assert.NoError(t, buildErr) + adapterstest.RunJSONBidderTest(t, "ownadxtest", bidder) +} diff --git a/adapters/ownadx/ownadxtest/exemplary/banner.json b/adapters/ownadx/ownadxtest/exemplary/banner.json new file mode 100644 index 00000000000..f77321c53b1 --- /dev/null +++ b/adapters/ownadx/ownadxtest/exemplary/banner.json @@ -0,0 +1,166 @@ +{ + "mockBidRequest": { + "id": "id", + "imp": [ + { + "id": "id", + "secure": 1, + "bidfloor": 0.01, + "bidfloorcur": "USD", + "banner": { + "w": 300, + "h": 250 + }, + "ext": { + "bidder": { + "tokenId": "126151698247", + "sspId": "11", + "seatId": "2" + } + } + } + ], + "device": { + "ua": "UA", + "ip": "123.3.4.123" + }, + "regs": { + "ext": { + "gdpr": 0 + } + }, + "user": { + "id": "userid" + }, + "site": { + "id": "id", + "domain": "test,com", + "cat": [ + "IAB12" + ], + "publisher": { + "id": "pubid" + } + } + }, + "httpCalls": [ + { + "expectedRequest": { + "uri": "https://pbs.prebid-ownadx.com/bidder/bid/2/11?token=126151698247", + "body": { + "id": "id", + "imp": [ + { + "id": "id", + "secure": 1, + "bidfloor": 0.01, + "bidfloorcur": "USD", + "banner": { + "w": 300, + "h": 250 + }, + "ext": { + "bidder": { + "tokenId": "126151698247", + "sspId": "11", + "seatId": "2" + } + } + } + ], + "device": { + "ua": "UA", + "ip": "123.3.4.123" + }, + "regs": { + "ext": { + "gdpr": 0 + } + }, + "user": { + "id": "userid" + }, + "site": { + "id": "id", + "domain": "test,com", + "cat": [ + "IAB12" + ], + "publisher": { + "id": "pubid" + } + } + } + }, + "mockResponse": { + "status": 200, + "body": { + "id": "id", + "bidid": "id", + "seatbid": [ + { + "bid": [ + { + "mtype": 1, + "id": "id", + "impid": "id", + "price": 0.1, + "nurl": "http://test.com/nurl", + "burl": "http://test.com/burl", + "adm": "Test", + "adomain": [ + "test.com" + ], + "cat": [ + "IAB1" + ], + "cid": "cid", + "crid": "crid", + "w": 300, + "h": 250, + "ext": { + "mediaType": "banner" + } + } + ], + "seat": "seat" + } + ], + "cur": "USD" + } + } + } + ], + "expectedBidResponses": [ + { + "currency": "USD", + "bids": [ + { + "bid": { + "mtype": 1, + "id": "id", + "impid": "id", + "price": 0.1, + "nurl": "http://test.com/nurl", + "burl": "http://test.com/burl", + "adm": "Test", + "adomain": [ + "test.com" + ], + "cat": [ + "IAB1" + ], + "cid": "cid", + "crid": "crid", + "w": 300, + "h": 250, + "ext": { + "mediaType": "banner" + } + }, + "type": "banner" + } + ] + } + ] +} \ No newline at end of file diff --git a/adapters/ownadx/ownadxtest/exemplary/video.json b/adapters/ownadx/ownadxtest/exemplary/video.json new file mode 100644 index 00000000000..7cac425c7e3 --- /dev/null +++ b/adapters/ownadx/ownadxtest/exemplary/video.json @@ -0,0 +1,196 @@ +{ + "mockBidRequest": { + "id": "id", + "imp": [ + { + "id": "id", + "secure": 1, + "bidfloor": 0.01, + "bidfloorcur": "USD", + "video": { + "mimes": [ + "video/mp4", + "video/ogg", + "video/webm" + ], + "minduration": 3, + "maxduration": 3000, + "protocols": [ + 2, + 3, + 5, + 6, + 7, + 8 + ], + "w": 480, + "h": 320, + "linearity": 1, + "playbackmethod": [ + 2 + ], + "pos": 0 + }, + "ext": { + "bidder": { + "tokenId": "126151698247", + "sspId": "11", + "seatId": "2" + } + } + } + ], + "device": { + "ua": "UA", + "ip": "123.3.4.123" + }, + "regs": { + "ext": { + "gdpr": 0 + } + }, + "user": { + "id": "userid" + }, + "site": { + "id": "id", + "domain": "test,com", + "cat": [ + "IAB12" + ], + "publisher": { + "id": "pubid" + } + } + }, + "httpCalls": [ + { + "expectedRequest": { + "uri": "https://pbs.prebid-ownadx.com/bidder/bid/2/11?token=126151698247", + "body": { + "id": "id", + "imp": [ + { + "id": "id", + "secure": 1, + "bidfloor": 0.01, + "bidfloorcur": "USD", + "video": { + "mimes": [ + "video/mp4", + "video/ogg", + "video/webm" + ], + "minduration": 3, + "maxduration": 3000, + "protocols": [ + 2, + 3, + 5, + 6, + 7, + 8 + ], + "w": 480, + "h": 320, + "linearity": 1, + "playbackmethod": [ + 2 + ], + "pos": 0 + }, + "ext": { + "bidder": { + "tokenId": "126151698247", + "sspId": "11", + "seatId": "2" + } + } + } + ], + "device": { + "ua": "UA", + "ip": "123.3.4.123" + }, + "regs": { + "ext": { + "gdpr": 0 + } + }, + "user": { + "id": "userid" + }, + "site": { + "id": "id", + "domain": "test,com", + "cat": [ + "IAB12" + ], + "publisher": { + "id": "pubid" + } + } + } + }, + "mockResponse": { + "status": 200, + "body": { + "id": "id", + "bidid": "id", + "seatbid": [ + { + "bid": [ + { + "id": "id", + "impid": "id", + "price": 0.1, + "nurl": "http://test.com/nurl", + "burl": "http://test.com/burl", + "adm": "", + "adomain": [ + "test.com" + ], + "cat": [ + "IAB1" + ], + "cid": "cid", + "crid": "crid", + "mtype": 2 + } + ], + "seat": "seat" + } + ], + "cur": "USD" + } + } + } + ], + "expectedBidResponses": [ + { + "currency": "USD", + "bids": [ + { + "bid": { + "id": "id", + "impid": "id", + "price": 0.1, + "nurl": "http://test.com/nurl", + "burl": "http://test.com/burl", + "adm": "", + "adomain": [ + "test.com" + ], + "cat": [ + "IAB1" + ], + "cid": "cid", + "crid": "crid", + "mtype": 2 + }, + "type": "video" + } + ] + } + ] +} \ No newline at end of file diff --git a/adapters/ownadx/ownadxtest/supplemental/bad-server-response.json b/adapters/ownadx/ownadxtest/supplemental/bad-server-response.json new file mode 100644 index 00000000000..61b6da04fa8 --- /dev/null +++ b/adapters/ownadx/ownadxtest/supplemental/bad-server-response.json @@ -0,0 +1,108 @@ +{ + "mockBidRequest": { + "id": "id", + "imp": [ + { + "id": "id", + "secure": 1, + "bidfloor": 0.01, + "bidfloorcur": "USD", + "banner": { + "w": 300, + "h": 250 + }, + "ext": { + "bidder": { + "tokenId": "126151698247", + "sspId": "11", + "seatId": "2" + } + } + } + ], + "device": { + "ua": "UA", + "ip": "123.3.4.123" + }, + "regs": { + "ext": { + "gdpr": 0 + } + }, + "user": { + "id": "userid" + }, + "site": { + "id": "id", + "domain": "test,com", + "cat": [ + "IAB12" + ], + "publisher": { + "id": "pubid" + } + } + }, + "httpCalls": [ + { + "expectedRequest": { + "uri": "https://pbs.prebid-ownadx.com/bidder/bid/2/11?token=126151698247", + "body": { + "id": "id", + "imp": [ + { + "id": "id", + "secure": 1, + "bidfloor": 0.01, + "bidfloorcur": "USD", + "banner": { + "w": 300, + "h": 250 + }, + "ext": { + "bidder": { + "tokenId": "126151698247", + "sspId": "11", + "seatId": "2" + } + } + } + ], + "device": { + "ua": "UA", + "ip": "123.3.4.123" + }, + "regs": { + "ext": { + "gdpr": 0 + } + }, + "user": { + "id": "userid" + }, + "site": { + "id": "id", + "domain": "test,com", + "cat": [ + "IAB12" + ], + "publisher": { + "id": "pubid" + } + } + } + }, + "mockResponse": { + "status": 200 + + } + } + ], + "expectedMakeBidsErrors": [ + { + "value": "Bad server response ", + "comparison": "literal" + } + ], + "expectedBidResponses": [] +} \ No newline at end of file diff --git a/adapters/ownadx/ownadxtest/supplemental/bid-empty-.json b/adapters/ownadx/ownadxtest/supplemental/bid-empty-.json new file mode 100644 index 00000000000..8d40e878925 --- /dev/null +++ b/adapters/ownadx/ownadxtest/supplemental/bid-empty-.json @@ -0,0 +1,118 @@ +{ + "mockBidRequest": { + "id": "id", + "imp": [ + { + "id": "id", + "secure": 1, + "bidfloor": 0.01, + "bidfloorcur": "USD", + "banner": { + "w": 300, + "h": 250 + }, + "ext": { + "bidder": { + "tokenId": "126151698247", + "sspId": "11", + "seatId": "2" + } + } + } + ], + "device": { + "ua": "UA", + "ip": "123.3.4.123" + }, + "regs": { + "ext": { + "gdpr": 0 + } + }, + "user": { + "id": "userid" + }, + "site": { + "id": "id", + "domain": "test,com", + "cat": [ + "IAB12" + ], + "publisher": { + "id": "pubid" + } + } + }, + "httpCalls": [ + { + "expectedRequest": { + "uri": "https://pbs.prebid-ownadx.com/bidder/bid/2/11?token=126151698247", + "body": { + "id": "id", + "imp": [ + { + "id": "id", + "secure": 1, + "bidfloor": 0.01, + "bidfloorcur": "USD", + "banner": { + "w": 300, + "h": 250 + }, + "ext": { + "bidder": { + "tokenId": "126151698247", + "sspId": "11", + "seatId": "2" + } + } + } + ], + "device": { + "ua": "UA", + "ip": "123.3.4.123" + }, + "regs": { + "ext": { + "gdpr": 0 + } + }, + "user": { + "id": "userid" + }, + "site": { + "id": "id", + "domain": "test,com", + "cat": [ + "IAB12" + ], + "publisher": { + "id": "pubid" + } + } + } + }, + "mockResponse": { + "status": 200, + "body": { + "id": "id", + "bidid": "id", + "seatbid": [ + { + "seat": "seat" + } + ], + "cur": "USD" + } + + } + } + ], + "expectedMakeBidsErrors": [ + { + "value": "Bid cannot be empty ", + "comparison": "literal" + } + ], + "expectedBidResponses": [] +} \ No newline at end of file diff --git a/adapters/ownadx/ownadxtest/supplemental/bidext-type.json b/adapters/ownadx/ownadxtest/supplemental/bidext-type.json new file mode 100644 index 00000000000..b1d634287d7 --- /dev/null +++ b/adapters/ownadx/ownadxtest/supplemental/bidext-type.json @@ -0,0 +1,141 @@ +{ + "mockBidRequest": { + "id": "id", + "imp": [ + { + "id": "id", + "secure": 1, + "bidfloor": 0.01, + "bidfloorcur": "USD", + "banner": { + "w": 300, + "h": 250 + }, + "ext": { + "bidder": { + "tokenId": "126151698247", + "sspId": "11", + "seatId": "2" + } + } + } + ], + "device": { + "ua": "UA", + "ip": "123.3.4.123" + }, + "regs": { + "ext": { + "gdpr": 0 + } + }, + "user": { + "id": "userid" + }, + "site": { + "id": "id", + "domain": "test,com", + "cat": [ + "IAB12" + ], + "publisher": { + "id": "pubid" + } + } + }, + "httpCalls": [ + { + "expectedRequest": { + "uri": "https://pbs.prebid-ownadx.com/bidder/bid/2/11?token=126151698247", + "body": { + "id": "id", + "imp": [ + { + "id": "id", + "secure": 1, + "bidfloor": 0.01, + "bidfloorcur": "USD", + "banner": { + "w": 300, + "h": 250 + }, + "ext": { + "bidder": { + "tokenId": "126151698247", + "sspId": "11", + "seatId": "2" + } + } + } + ], + "device": { + "ua": "UA", + "ip": "123.3.4.123" + }, + "regs": { + "ext": { + "gdpr": 0 + } + }, + "user": { + "id": "userid" + }, + "site": { + "id": "id", + "domain": "test,com", + "cat": [ + "IAB12" + ], + "publisher": { + "id": "pubid" + } + } + } + }, + "mockResponse": { + "status": 200, + "body": { + "id": "id", + "bidid": "id", + "seatbid": [ + { + "bid": [ + { + "id": "id", + "impid": "id", + "price": 0.1, + "nurl": "http://test.com/nurl", + "burl": "http://test.com/burl", + "adm": "Test", + "adomain": [ + "test.com" + ], + "cat": [ + "IAB1" + ], + "cid": "cid", + "crid": "crid", + "w": 300, + "h": 250, + "ext": { + + } + } + ], + "seat": "seat" + } + ], + "cur": "USD" + } + + } + } + ], + "expectedMakeBidsErrors": [ + { + "value": "Bid type is invalid", + "comparison": "literal" + } + ], + "expectedBidResponses": [] +} \ No newline at end of file diff --git a/adapters/ownadx/ownadxtest/supplemental/http-status-204.json b/adapters/ownadx/ownadxtest/supplemental/http-status-204.json new file mode 100644 index 00000000000..4b7f8663f02 --- /dev/null +++ b/adapters/ownadx/ownadxtest/supplemental/http-status-204.json @@ -0,0 +1,51 @@ +{ + "mockBidRequest": { + "id": "test-request-id", + "imp": [ + { + "id": "test-imp-id", + "banner": { + "w": 300, + "h": 250 + }, + "ext": { + "bidder": { + "tokenId": "126151698247", + "sspId": "11", + "seatId": "2" + } + } + } + ] + }, + "httpCalls": [ + { + "expectedRequest": { + "uri": "https://pbs.prebid-ownadx.com/bidder/bid/2/11?token=126151698247", + "body": { + "id": "test-request-id", + "imp": [ + { + "id": "test-imp-id", + "banner": { + "w": 300, + "h": 250 + }, + "ext": { + "bidder": { + "tokenId": "126151698247", + "sspId": "11", + "seatId": "2" + } + } + } + ] + } + }, + "mockResponse": { + "status": 204 + } + } + ], + "expectedBidResponses": [] +} \ No newline at end of file diff --git a/adapters/ownadx/ownadxtest/supplemental/http-status-400.json b/adapters/ownadx/ownadxtest/supplemental/http-status-400.json new file mode 100644 index 00000000000..035bc323e38 --- /dev/null +++ b/adapters/ownadx/ownadxtest/supplemental/http-status-400.json @@ -0,0 +1,57 @@ +{ + "mockBidRequest": { + "id": "test-request-id", + "imp": [ + { + "id": "test-imp-id", + "banner": { + "w": 300, + "h": 250 + }, + "ext": { + "bidder": { + "tokenId": "126151698247", + "sspId": "11", + "seatId": "2" + } + } + } + ] + }, + "httpCalls": [ + { + "expectedRequest": { + "uri": "https://pbs.prebid-ownadx.com/bidder/bid/2/11?token=126151698247", + "body": { + "id": "test-request-id", + "imp": [ + { + "id": "test-imp-id", + "banner": { + "w": 300, + "h": 250 + }, + "ext": { + "bidder": { + "tokenId": "126151698247", + "sspId": "11", + "seatId": "2" + } + } + } + ] + } + }, + "mockResponse": { + "status": 400 + } + } + ], + "expectedMakeBidsErrors": [ + { + "value": "Bad request: 400", + "comparison": "literal" + } + ], + "expectedBidResponses": [] +} \ No newline at end of file diff --git a/adapters/ownadx/ownadxtest/supplemental/invalid-req-empty-imp.json b/adapters/ownadx/ownadxtest/supplemental/invalid-req-empty-imp.json new file mode 100644 index 00000000000..0407ed6cfbf --- /dev/null +++ b/adapters/ownadx/ownadxtest/supplemental/invalid-req-empty-imp.json @@ -0,0 +1,34 @@ +{ + "expectedMakeRequestsErrors": [ + { + "value": "No impression in the bid request", + "comparison": "literal" + } + ], + "mockBidRequest": { + "id": "id", + "device": { + "ua": "UA", + "ip": "123.3.4.123" + }, + "regs": { + "ext": { + "gdpr": 0 + } + }, + "user": { + "id": "userid" + }, + "site": { + "id": "id", + "domain": "test,com", + "cat": [ + "IAB12" + ], + "publisher": { + "id": "pubid" + } + } + }, + "httpCalls": [] +} diff --git a/adapters/ownadx/ownadxtest/supplemental/invalid-req-imp-ext.json b/adapters/ownadx/ownadxtest/supplemental/invalid-req-imp-ext.json new file mode 100644 index 00000000000..9b8ba0d1820 --- /dev/null +++ b/adapters/ownadx/ownadxtest/supplemental/invalid-req-imp-ext.json @@ -0,0 +1,47 @@ +{ + "expectedMakeRequestsErrors": [ + { + "value": "Bidder extension not valid or can't be unmarshalled", + "comparison": "literal" + } + ], + "mockBidRequest": { + "id": "id", + "imp": [ + { + "id": "id", + "secure": 1, + "bidfloor": 0.01, + "bidfloorcur": "USD", + "banner": { + "w": 300, + "h": 250 + } + + } + ], + "device": { + "ua": "UA", + "ip": "123.3.4.123" + }, + "regs": { + "ext": { + "gdpr": 0 + } + }, + "user": { + "id": "userid" + }, + "site": { + "id": "id", + "domain": "test,com", + "cat": [ + "IAB12" + ], + "publisher": { + "id": "pubid" + } + } + }, + "httpCalls": [] +} diff --git a/adapters/ownadx/ownadxtest/supplemental/invalid-req-imp.ext.bidder.json b/adapters/ownadx/ownadxtest/supplemental/invalid-req-imp.ext.bidder.json new file mode 100644 index 00000000000..b04e037d0a2 --- /dev/null +++ b/adapters/ownadx/ownadxtest/supplemental/invalid-req-imp.ext.bidder.json @@ -0,0 +1,49 @@ +{ + "expectedMakeRequestsErrors": [ + { + "value": "Error while unmarshaling bidder extension", + "comparison": "literal" + } + ], + "mockBidRequest": { + "id": "id", + "imp": [ + { + "id": "id", + "secure": 1, + "bidfloor": 0.01, + "bidfloorcur": "USD", + "banner": { + "w": 300, + "h": 250 + }, + "ext": { + "bidder": [] + } + } + ], + "device": { + "ua": "UA", + "ip": "123.3.4.123" + }, + "regs": { + "ext": { + "gdpr": 0 + } + }, + "user": { + "id": "userid" + }, + "site": { + "id": "id", + "domain": "test,com", + "cat": [ + "IAB12" + ], + "publisher": { + "id": "pubid" + } + } + }, + "httpCalls": [] +} diff --git a/adapters/ownadx/ownadxtest/supplemental/seatbid-empty-.json b/adapters/ownadx/ownadxtest/supplemental/seatbid-empty-.json new file mode 100644 index 00000000000..f49ece3ea2f --- /dev/null +++ b/adapters/ownadx/ownadxtest/supplemental/seatbid-empty-.json @@ -0,0 +1,113 @@ +{ + "mockBidRequest": { + "id": "id", + "imp": [ + { + "id": "id", + "secure": 1, + "bidfloor": 0.01, + "bidfloorcur": "USD", + "banner": { + "w": 300, + "h": 250 + }, + "ext": { + "bidder": { + "tokenId": "126151698247", + "sspId": "11", + "seatId": "2" + } + } + } + ], + "device": { + "ua": "UA", + "ip": "123.3.4.123" + }, + "regs": { + "ext": { + "gdpr": 0 + } + }, + "user": { + "id": "userid" + }, + "site": { + "id": "id", + "domain": "test,com", + "cat": [ + "IAB12" + ], + "publisher": { + "id": "pubid" + } + } + }, + "httpCalls": [ + { + "expectedRequest": { + "uri": "https://pbs.prebid-ownadx.com/bidder/bid/2/11?token=126151698247", + "body": { + "id": "id", + "imp": [ + { + "id": "id", + "secure": 1, + "bidfloor": 0.01, + "bidfloorcur": "USD", + "banner": { + "w": 300, + "h": 250 + }, + "ext": { + "bidder": { + "tokenId": "126151698247", + "sspId": "11", + "seatId": "2" + } + } + } + ], + "device": { + "ua": "UA", + "ip": "123.3.4.123" + }, + "regs": { + "ext": { + "gdpr": 0 + } + }, + "user": { + "id": "userid" + }, + "site": { + "id": "id", + "domain": "test,com", + "cat": [ + "IAB12" + ], + "publisher": { + "id": "pubid" + } + } + } + }, + "mockResponse": { + "status": 200, + "body": { + "id": "id", + "bidid": "id", + "cur": "USD" + } + + } + } + ], + "expectedMakeBidsErrors": [ + { + "value": "Array SeatBid cannot be empty ", + "comparison": "literal" + } + ], + "expectedBidResponses": [] +} \ No newline at end of file diff --git a/adapters/ownadx/ownadxtest/supplemental/unexpected-status.json b/adapters/ownadx/ownadxtest/supplemental/unexpected-status.json new file mode 100644 index 00000000000..f501a11064e --- /dev/null +++ b/adapters/ownadx/ownadxtest/supplemental/unexpected-status.json @@ -0,0 +1,107 @@ +{ + "mockBidRequest": { + "id": "id", + "imp": [ + { + "id": "id", + "secure": 1, + "bidfloor": 0.01, + "bidfloorcur": "USD", + "banner": { + "w": 300, + "h": 250 + }, + "ext": { + "bidder": { + "tokenId": "126151698247", + "sspId": "11", + "seatId": "2" + } + } + } + ], + "device": { + "ua": "UA", + "ip": "123.3.4.123" + }, + "regs": { + "ext": { + "gdpr": 0 + } + }, + "user": { + "id": "userid" + }, + "site": { + "id": "id", + "domain": "test,com", + "cat": [ + "IAB12" + ], + "publisher": { + "id": "pubid" + } + } + }, + "httpCalls": [ + { + "expectedRequest": { + "uri": "https://pbs.prebid-ownadx.com/bidder/bid/2/11?token=126151698247", + "body": { + "id": "id", + "imp": [ + { + "id": "id", + "secure": 1, + "bidfloor": 0.01, + "bidfloorcur": "USD", + "banner": { + "w": 300, + "h": 250 + }, + "ext": { + "bidder": { + "tokenId": "126151698247", + "sspId": "11", + "seatId": "2" + } + } + } + ], + "device": { + "ua": "UA", + "ip": "123.3.4.123" + }, + "regs": { + "ext": { + "gdpr": 0 + } + }, + "user": { + "id": "userid" + }, + "site": { + "id": "id", + "domain": "test,com", + "cat": [ + "IAB12" + ], + "publisher": { + "id": "pubid" + } + } + } + }, + "mockResponse": { + "status": 403 + } + } + ], + "expectedMakeBidsErrors": [ + { + "value": "Unexpected status code: 403. Run with request.test = 1 for more info.", + "comparison": "literal" + } + ], + "expectedBidResponses": [] +} \ No newline at end of file diff --git a/exchange/adapter_builders.go b/exchange/adapter_builders.go index 96d6aa64b0f..a1038d7152d 100755 --- a/exchange/adapter_builders.go +++ b/exchange/adapter_builders.go @@ -127,6 +127,7 @@ import ( "github.com/prebid/prebid-server/adapters/operaads" "github.com/prebid/prebid-server/adapters/orbidder" "github.com/prebid/prebid-server/adapters/outbrain" + "github.com/prebid/prebid-server/adapters/ownadx" "github.com/prebid/prebid-server/adapters/pangle" "github.com/prebid/prebid-server/adapters/pubmatic" "github.com/prebid/prebid-server/adapters/pubnative" @@ -320,6 +321,7 @@ func newAdapterBuilders() map[openrtb_ext.BidderName]adapters.Builder { openrtb_ext.BidderOperaads: operaads.Builder, openrtb_ext.BidderOrbidder: orbidder.Builder, openrtb_ext.BidderOutbrain: outbrain.Builder, + openrtb_ext.BidderOwnAdx: ownadx.Builder, openrtb_ext.BidderPangle: pangle.Builder, openrtb_ext.BidderPGAM: adtelligent.Builder, openrtb_ext.BidderPubmatic: pubmatic.Builder, diff --git a/openrtb_ext/bidders.go b/openrtb_ext/bidders.go index 2398af8e62a..e9cc81f8c38 100644 --- a/openrtb_ext/bidders.go +++ b/openrtb_ext/bidders.go @@ -220,6 +220,7 @@ const ( BidderOperaads BidderName = "operaads" BidderOrbidder BidderName = "orbidder" BidderOutbrain BidderName = "outbrain" + BidderOwnAdx BidderName = "ownadx" BidderPangle BidderName = "pangle" BidderPGAM BidderName = "pgam" BidderPubmatic BidderName = "pubmatic" @@ -419,6 +420,7 @@ func CoreBidderNames() []BidderName { BidderOperaads, BidderOrbidder, BidderOutbrain, + BidderOwnAdx, BidderPangle, BidderPGAM, BidderPubmatic, diff --git a/openrtb_ext/imp_ownadx.go b/openrtb_ext/imp_ownadx.go new file mode 100644 index 00000000000..caac600b50e --- /dev/null +++ b/openrtb_ext/imp_ownadx.go @@ -0,0 +1,7 @@ +package openrtb_ext + +type ExtImpOwnAdx struct { + SspId string `json:"sspId"` + SeatId string `json:"seatId"` + TokenId string `json:"tokenId"` +} diff --git a/static/bidder-info/ownadx.yaml b/static/bidder-info/ownadx.yaml new file mode 100644 index 00000000000..37567db1144 --- /dev/null +++ b/static/bidder-info/ownadx.yaml @@ -0,0 +1,12 @@ +endpoint: "https://pbs.prebid-ownadx.com/bidder/bid/{{.AccountID}}/{{.ZoneID}}?token={{.SourceId}}" +maintainer: + email: prebid-team@techbravo.com +capabilities: + app: + mediaTypes: + - banner + - video + site: + mediaTypes: + - banner + - video diff --git a/static/bidder-params/ownadx.json b/static/bidder-params/ownadx.json new file mode 100644 index 00000000000..f529e74cb01 --- /dev/null +++ b/static/bidder-params/ownadx.json @@ -0,0 +1,27 @@ +{ + "$schema": "http://json-schema.org/draft-04/schema#", + "title": "OwnAdx Adapter Params", + "description": "A schema which validates params accepted by the OwnAdx adapter", + "type": "object", + + "properties": { + "sspId": { + "type": "string", + "description": "Ssp ID" + }, + "seatId": { + "type": "string", + "description": "Seat ID" + }, + "tokenId": { + "type": "string", + "description": "Token ID" + } + }, + + "oneOf": [ + { "required": ["sspId"] }, + { "required": ["feedId"] }, + { "required": ["token"] } + ] +}