From d33b948aae7e3cd3d5a2936e0cb9d8bf9658b93b Mon Sep 17 00:00:00 2001 From: Misha S Date: Thu, 1 Jun 2023 14:08:46 +0300 Subject: [PATCH] TypeA Rise adapter --- adapters/rise/rise.go | 125 +++++++++++ adapters/rise/rise_test.go | 24 ++ .../exemplary/banner-and-video-app.json | 211 ++++++++++++++++++ .../exemplary/banner-and-video-gdpr.json | 182 +++++++++++++++ .../exemplary/banner-and-video-site.json | 190 ++++++++++++++++ .../risetest/exemplary/banner-and-video.json | 189 ++++++++++++++++ .../risetest/exemplary/simple-banner.json | 115 ++++++++++ .../rise/risetest/exemplary/simple-video.json | 110 +++++++++ .../risetest/supplemental/bad-request.json | 79 +++++++ .../risetest/supplemental/missing-bidder.json | 35 +++ .../supplemental/missing-extension.json | 34 +++ .../risetest/supplemental/missing-mtype.json | 117 ++++++++++ .../supplemental/missing-publisher-id.json | 38 ++++ exchange/adapter_builders.go | 2 + openrtb_ext/bidders.go | 2 + openrtb_ext/imp_rise.go | 6 + static/bidder-info/rise.yaml | 18 ++ static/bidder-params/rise.json | 13 ++ 18 files changed, 1490 insertions(+) create mode 100644 adapters/rise/rise.go create mode 100644 adapters/rise/rise_test.go create mode 100644 adapters/rise/risetest/exemplary/banner-and-video-app.json create mode 100644 adapters/rise/risetest/exemplary/banner-and-video-gdpr.json create mode 100644 adapters/rise/risetest/exemplary/banner-and-video-site.json create mode 100644 adapters/rise/risetest/exemplary/banner-and-video.json create mode 100644 adapters/rise/risetest/exemplary/simple-banner.json create mode 100644 adapters/rise/risetest/exemplary/simple-video.json create mode 100644 adapters/rise/risetest/supplemental/bad-request.json create mode 100644 adapters/rise/risetest/supplemental/missing-bidder.json create mode 100644 adapters/rise/risetest/supplemental/missing-extension.json create mode 100644 adapters/rise/risetest/supplemental/missing-mtype.json create mode 100644 adapters/rise/risetest/supplemental/missing-publisher-id.json create mode 100644 openrtb_ext/imp_rise.go create mode 100644 static/bidder-info/rise.yaml create mode 100644 static/bidder-params/rise.json diff --git a/adapters/rise/rise.go b/adapters/rise/rise.go new file mode 100644 index 00000000000..ce695a6ba31 --- /dev/null +++ b/adapters/rise/rise.go @@ -0,0 +1,125 @@ +package rise + +import ( + "encoding/json" + "errors" + "fmt" + "github.com/prebid/prebid-server/util/httputil" + "net/http" + "strings" + + "github.com/prebid/openrtb/v19/openrtb2" + "github.com/prebid/prebid-server/adapters" + "github.com/prebid/prebid-server/config" + "github.com/prebid/prebid-server/openrtb_ext" +) + +// adapter is a Rise implementation of the adapters.Bidder interface. +type adapter struct { + endpointURL string +} + +func Builder(_ openrtb_ext.BidderName, config config.Adapter, _ config.Server) (adapters.Bidder, error) { + return &adapter{ + endpointURL: config.Endpoint, + }, nil +} + +// MakeRequests prepares the HTTP requests which should be made to fetch bids. +func (a *adapter) MakeRequests(openRTBRequest *openrtb2.BidRequest, _ *adapters.ExtraRequestInfo) (requestsToBidder []*adapters.RequestData, errs []error) { + publisherID, err := extractPublisherID(openRTBRequest) + if err != nil { + errs = append(errs, fmt.Errorf("extractPublisherID: %w", err)) + return nil, errs + } + + openRTBRequestJSON, err := json.Marshal(openRTBRequest) + if err != nil { + errs = append(errs, fmt.Errorf("marshal bidRequest: %w", err)) + return nil, errs + } + + headers := http.Header{} + headers.Add("Content-Type", "application/json;charset=utf-8") + + return append(requestsToBidder, &adapters.RequestData{ + Method: http.MethodPost, + Uri: a.endpointURL + "?publisher_id=" + publisherID, + Body: openRTBRequestJSON, + Headers: headers, + }), nil +} + +// MakeBids unpacks the server's response into Bids. +func (a *adapter) MakeBids(request *openrtb2.BidRequest, _ *adapters.RequestData, responseData *adapters.ResponseData) (*adapters.BidderResponse, []error) { + if httputil.IsResponseStatusCodeNoContent(responseData) { + return nil, nil + } + + if err := httputil.CheckResponseStatusCodeForErrors(responseData); err != nil { + return nil, []error{err} + } + + var response openrtb2.BidResponse + if err := json.Unmarshal(responseData.Body, &response); err != nil { + return nil, []error{err} + } + + bidResponse := adapters.NewBidderResponseWithBidsCapacity(len(request.Imp)) + bidResponse.Currency = response.Cur + + var errs []error + + for _, seatBid := range response.SeatBid { + for i, bid := range seatBid.Bid { + bidType, err := getMediaTypeForBid(bid) + if err != nil { + errs = append(errs, err) + continue + } + + bidResponse.Bids = append(bidResponse.Bids, &adapters.TypedBid{ + Bid: &seatBid.Bid[i], + BidType: bidType, + }) + } + } + + return bidResponse, errs +} + +func extractPublisherID(openRTBRequest *openrtb2.BidRequest) (string, error) { + var err error + for _, imp := range openRTBRequest.Imp { + var bidderExt adapters.ExtImpBidder + if err = json.Unmarshal(imp.Ext, &bidderExt); err != nil { + return "", fmt.Errorf("unmarshal bidderExt: %w", err) + } + + var impExt openrtb_ext.ImpExtRise + if err = json.Unmarshal(bidderExt.Bidder, &impExt); err != nil { + return "", fmt.Errorf("unmarshal ImpExtRise: %w", err) + } + + if impExt.PublisherID != "" { + return strings.TrimSpace(impExt.PublisherID), nil + } + } + + return "", errors.New("no publisherID supplied") +} + +func getMediaTypeForBid(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("unsupported MType %d", bid.MType) + } +} diff --git a/adapters/rise/rise_test.go b/adapters/rise/rise_test.go new file mode 100644 index 00000000000..1ba3f8a865d --- /dev/null +++ b/adapters/rise/rise_test.go @@ -0,0 +1,24 @@ +package rise + +import ( + "testing" + + "github.com/prebid/prebid-server/adapters/adapterstest" + "github.com/prebid/prebid-server/config" + "github.com/prebid/prebid-server/openrtb_ext" +) + +const testsDir = "risetest" +const testsBidderEndpoint = "http://localhost/prebid_server" + +func TestJsonSamples(t *testing.T) { + bidder, buildErr := Builder( + openrtb_ext.BidderRise, + config.Adapter{Endpoint: testsBidderEndpoint}, + config.Server{ExternalUrl: "http://hosturl.com", GvlID: 1, DataCenter: "2"}) + if buildErr != nil { + t.Fatalf("Builder returned unexpected error %v", buildErr) + } + + adapterstest.RunJSONBidderTest(t, testsDir, bidder) +} diff --git a/adapters/rise/risetest/exemplary/banner-and-video-app.json b/adapters/rise/risetest/exemplary/banner-and-video-app.json new file mode 100644 index 00000000000..9eb79156403 --- /dev/null +++ b/adapters/rise/risetest/exemplary/banner-and-video-app.json @@ -0,0 +1,211 @@ +{ + "mockBidRequest": { + "id": "test-request-id", + "imp": [ + { + "id": "test-imp-id", + "banner": { + "format": [ + { + "w": 300, + "h": 250 + }, + { + "w": 300, + "h": 300 + } + ] + }, + "ext": { + "bidder": { + "publisher_id": "72721", + "path": "mvo", + "zone": "1r" + } + } + }, + { + "id": "test-imp-video-id", + "video": { + "mimes": ["video/mp4"], + "minduration": 1, + "maxduration": 2, + "protocols": [1, 2, 5], + "w": 1020, + "h": 780, + "startdelay": 1, + "placement": 1, + "playbackmethod": [2], + "delivery": [1], + "api": [1, 2, 3, 4] + }, + "ext": { + "bidder": { + "publisher_id": "72721", + "path": "mvo", + "zone": "1r" + } + } + } + ], + "app": { + "id": "agltb3B1Yi1pbmNyDAsSA0FwcBiJkfIUDA", + "name": "Yahoo Weather", + "bundle": "12345", + "storeurl": "https://itunes.apple.com/id628677149", + "cat": ["IAB15", "IAB15-10"], + "ver": "1.0.2", + "publisher": { + "id": "1" + } + }, + "device": { + "dnt": 0, + "ua": "Mozilla/5.0 (iPhone; CPU iPhone OS 6_1 like Mac OS X) AppleWebKit / 534.46(KHTML, like Gecko) Version / 5.1 Mobile / 9 A334 Safari / 7534.48 .3", + "ip": "123.145.167.189", + "ifa": "AA000DFE74168477C70D291f574D344790E0BB11", + "carrier": "VERIZON", + "language": "en", + "make": "Apple", + "model": "iPhone", + "os": "iOS", + "osv": "6.1", + "js": 1, + "connectiontype": 3, + "devicetype": 1 + } + }, + "httpCalls": [ + { + "expectedRequest": { + "uri": "http://localhost/prebid_server?publisher_id=72721", + "body": { + "id": "test-request-id", + "imp": [ + { + "id": "test-imp-id", + "banner": { + "format": [ + { + "w": 300, + "h": 250 + }, + { + "w": 300, + "h": 300 + } + ] + }, + "ext": { + "bidder": { + "publisher_id": "72721", + "zone": "1r", + "path": "mvo" + } + } + }, + { + "id": "test-imp-video-id", + "video": { + "mimes": ["video/mp4"], + "minduration": 1, + "maxduration": 2, + "protocols": [1, 2, 5], + "w": 1020, + "h": 780, + "startdelay": 1, + "placement": 1, + "playbackmethod": [2], + "delivery": [1], + "api": [1, 2, 3, 4] + }, + "ext": { + "bidder": { + "publisher_id": "72721", + "zone": "1r", + "path": "mvo" + } + } + } + ], + "app": { + "id": "agltb3B1Yi1pbmNyDAsSA0FwcBiJkfIUDA", + "name": "Yahoo Weather", + "bundle": "12345", + "storeurl": "https://itunes.apple.com/id628677149", + "cat": ["IAB15", "IAB15-10"], + "ver": "1.0.2", + "publisher": { + "id": "1" + } + }, + "device": { + "ua": "Mozilla/5.0 (iPhone; CPU iPhone OS 6_1 like Mac OS X) AppleWebKit / 534.46(KHTML, like Gecko) Version / 5.1 Mobile / 9 A334 Safari / 7534.48 .3", + "ip": "123.145.167.189", + "devicetype": 1, + "make": "Apple", + "model": "iPhone", + "os": "iOS", + "osv": "6.1", + "js": 1, + "dnt": 0, + "language": "en", + "carrier": "VERIZON", + "connectiontype": 3, + "ifa": "AA000DFE74168477C70D291f574D344790E0BB11" + } + } + }, + "mockResponse": { + "status": 200, + "body": { + "id": "test-request-id", + "seatbid": [ + { + "seat": "958", + "bid": [ + { + "id": "7706636740145184841", + "impid": "test-imp-video-id", + "price": 0.5, + "adid": "29681110", + "adm": "some-test-ad", + "adomain": ["yahoo.com"], + "cid": "958", + "crid": "29681110", + "h": 576, + "w": 1024, + "mtype": 2 + } + ] + } + ], + "bidid": "5778926625248726496", + "cur": "USD" + } + } + } + ], + "expectedBidResponses": [ + { + "bids": [ + { + "bid": { + "id": "7706636740145184841", + "impid": "test-imp-video-id", + "price": 0.5, + "adm": "some-test-ad", + "adid": "29681110", + "adomain": ["yahoo.com"], + "cid": "958", + "crid": "29681110", + "w": 1024, + "h": 576, + "mtype": 2 + }, + "type": "video" + } + ] + } + ] +} diff --git a/adapters/rise/risetest/exemplary/banner-and-video-gdpr.json b/adapters/rise/risetest/exemplary/banner-and-video-gdpr.json new file mode 100644 index 00000000000..dfdf54a8c67 --- /dev/null +++ b/adapters/rise/risetest/exemplary/banner-and-video-gdpr.json @@ -0,0 +1,182 @@ +{ + "mockBidRequest": { + "id": "test-request-id", + "imp": [ + { + "id": "test-imp-id", + "banner": { + "format": [ + { + "w": 300, + "h": 250 + }, + { + "w": 300, + "h": 300 + } + ] + }, + "ext": { + "bidder": { + "publisher_id": "72721", + "path": "mvo", + "zone": "1r" + } + } + }, + { + "id": "test-imp-video-id", + "video": { + "mimes": ["video/mp4"], + "minduration": 1, + "maxduration": 2, + "protocols": [1, 2, 5], + "w": 1020, + "h": 780, + "startdelay": 1, + "placement": 1, + "playbackmethod": [2], + "delivery": [1], + "api": [1, 2, 3, 4] + }, + "ext": { + "bidder": { + "publisher_id": "72721", + "path": "mvo", + "zone": "1r" + } + } + } + ], + "user": { + "id": "eyJ0ZW1wVUlEcyI6eyJhZGZvcm0iOnsidWlkIjoiMzA5MTMwOTUxNjQ5NDA1MjcxIiwiZXhwaXJlcyI6IjIwMTgtMDYtMjBUMTE6NDA6MzUuODAwNTE0NzQ3KzA1OjMwIn0sImFkbnhzIjp7InVpZCI6IjM1MTUzMjg2MTAyNjMxNjQ0ODQiLCJleHBpcmVzIjoiMjAxOC0wNi0xOFQxODoxMjoxNy4wMTExMzg2MDgrMDU6MzAifX0sImJkYXkiOiIyMDE4LTA2LTA0VDE4OjEyOjE3LjAxMTEzMDg3NSswNTozMCJ9", + "ext": { + "consent": "BOPVK28OPVK28ABABAENA8-AAAADkCNQCGoQAAQ" + } + }, + "regs": { + "ext": { + "gdpr": 1 + } + } + }, + "httpCalls": [ + { + "expectedRequest": { + "uri": "http://localhost/prebid_server?publisher_id=72721", + "body": { + "id": "test-request-id", + "imp": [ + { + "id": "test-imp-id", + "banner": { + "format": [ + { + "w": 300, + "h": 250 + }, + { + "w": 300, + "h": 300 + } + ] + }, + "ext": { + "bidder": { + "publisher_id": "72721", + "zone": "1r", + "path": "mvo" + } + } + }, + { + "id": "test-imp-video-id", + "video": { + "mimes": ["video/mp4"], + "minduration": 1, + "maxduration": 2, + "protocols": [1, 2, 5], + "w": 1020, + "h": 780, + "startdelay": 1, + "placement": 1, + "playbackmethod": [2], + "delivery": [1], + "api": [1, 2, 3, 4] + }, + "ext": { + "bidder": { + "publisher_id": "72721", + "zone": "1r", + "path": "mvo" + } + } + } + ], + "user": { + "id": "eyJ0ZW1wVUlEcyI6eyJhZGZvcm0iOnsidWlkIjoiMzA5MTMwOTUxNjQ5NDA1MjcxIiwiZXhwaXJlcyI6IjIwMTgtMDYtMjBUMTE6NDA6MzUuODAwNTE0NzQ3KzA1OjMwIn0sImFkbnhzIjp7InVpZCI6IjM1MTUzMjg2MTAyNjMxNjQ0ODQiLCJleHBpcmVzIjoiMjAxOC0wNi0xOFQxODoxMjoxNy4wMTExMzg2MDgrMDU6MzAifX0sImJkYXkiOiIyMDE4LTA2LTA0VDE4OjEyOjE3LjAxMTEzMDg3NSswNTozMCJ9", + "ext": { + "consent": "BOPVK28OPVK28ABABAENA8-AAAADkCNQCGoQAAQ" + } + }, + "regs": { + "ext": { + "gdpr": 1 + } + } + } + }, + "mockResponse": { + "status": 200, + "body": { + "id": "test-request-id", + "seatbid": [ + { + "seat": "958", + "bid": [ + { + "id": "7706636740145184841", + "impid": "test-imp-video-id", + "price": 0.5, + "adid": "29681110", + "adm": "some-test-ad", + "adomain": ["yahoo.com"], + "cid": "958", + "crid": "29681110", + "h": 576, + "w": 1024, + "mtype": 2 + } + ] + } + ], + "bidid": "5778926625248726496", + "cur": "USD" + } + } + } + ], + + "expectedBidResponses": [ + { + "bids": [ + { + "bid": { + "id": "7706636740145184841", + "impid": "test-imp-video-id", + "price": 0.5, + "adm": "some-test-ad", + "adid": "29681110", + "adomain": ["yahoo.com"], + "cid": "958", + "crid": "29681110", + "w": 1024, + "h": 576, + "mtype": 2 + }, + "type": "video" + } + ] + } + ] +} diff --git a/adapters/rise/risetest/exemplary/banner-and-video-site.json b/adapters/rise/risetest/exemplary/banner-and-video-site.json new file mode 100644 index 00000000000..fda9efdbdfc --- /dev/null +++ b/adapters/rise/risetest/exemplary/banner-and-video-site.json @@ -0,0 +1,190 @@ +{ + "mockBidRequest": { + "id": "test-request-id", + "imp": [ + { + "id": "test-imp-id", + "banner": { + "format": [ + { + "w": 300, + "h": 250 + }, + { + "w": 300, + "h": 300 + } + ] + }, + "ext": { + "bidder": { + "publisher_id": "72721", + "path": "mvo", + "zone": "1r" + } + } + }, + { + "id": "test-imp-video-id", + "video": { + "mimes": ["video/mp4"], + "minduration": 1, + "maxduration": 2, + "protocols": [1, 2, 5], + "w": 1020, + "h": 780, + "startdelay": 1, + "placement": 1, + "playbackmethod": [2], + "delivery": [1], + "api": [1, 2, 3, 4] + }, + "ext": { + "bidder": { + "publisher_id": "72721", + "path": "mvo", + "zone": "1r" + } + } + } + ], + "site": { + "id": "102855", + "cat": ["IAB3-1"], + "domain": "www.foobar.com", + "page": "http://www.foobar.com/1234.html ", + "publisher": { + "id": "8953", + "name": "foobar.com", + "cat": ["IAB3-1"], + "domain": "foobar.com" + } + }, + "device": { + "ua": "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_6_8) AppleWebKit/537.13 (KHTML, like Gecko) Version / 5.1 .7 Safari / 534.57 .2", + "ip": "123.145.167.10" + } + }, + "httpCalls": [ + { + "expectedRequest": { + "uri": "http://localhost/prebid_server?publisher_id=72721", + "body": { + "id": "test-request-id", + "imp": [ + { + "id": "test-imp-id", + "banner": { + "format": [ + { + "w": 300, + "h": 250 + }, + { + "w": 300, + "h": 300 + } + ] + }, + "ext": { + "bidder": { + "publisher_id": "72721", + "zone": "1r", + "path": "mvo" + } + } + }, + { + "id": "test-imp-video-id", + "video": { + "mimes": ["video/mp4"], + "minduration": 1, + "maxduration": 2, + "protocols": [1, 2, 5], + "w": 1020, + "h": 780, + "startdelay": 1, + "placement": 1, + "playbackmethod": [2], + "delivery": [1], + "api": [1, 2, 3, 4] + }, + "ext": { + "bidder": { + "publisher_id": "72721", + "zone": "1r", + "path": "mvo" + } + } + } + ], + "site": { + "id": "102855", + "cat": ["IAB3-1"], + "domain": "www.foobar.com", + "page": "http://www.foobar.com/1234.html ", + "publisher": { + "id": "8953", + "name": "foobar.com", + "cat": ["IAB3-1"], + "domain": "foobar.com" + } + }, + "device": { + "ua": "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_6_8) AppleWebKit/537.13 (KHTML, like Gecko) Version / 5.1 .7 Safari / 534.57 .2", + "ip": "123.145.167.10" + } + } + }, + "mockResponse": { + "status": 200, + "body": { + "id": "test-request-id", + "seatbid": [ + { + "seat": "958", + "bid": [ + { + "id": "7706636740145184841", + "impid": "test-imp-video-id", + "price": 0.5, + "adid": "29681110", + "adm": "some-test-ad", + "adomain": ["yahoo.com"], + "cid": "958", + "crid": "29681110", + "h": 576, + "w": 1024, + "mtype": 2 + } + ] + } + ], + "bidid": "5778926625248726496", + "cur": "USD" + } + } + } + ], + + "expectedBidResponses": [ + { + "bids": [{ + "bid": { + "id": "7706636740145184841", + "impid": "test-imp-video-id", + "price": 0.5, + "adm": "some-test-ad", + "adid": "29681110", + "adomain": ["yahoo.com"], + "cid": "958", + "crid": "29681110", + "w": 1024, + "h": 576, + "mtype": 2 + }, + "type": "video" + }] + } + ] +} diff --git a/adapters/rise/risetest/exemplary/banner-and-video.json b/adapters/rise/risetest/exemplary/banner-and-video.json new file mode 100644 index 00000000000..2a2e3f681a1 --- /dev/null +++ b/adapters/rise/risetest/exemplary/banner-and-video.json @@ -0,0 +1,189 @@ +{ + "mockBidRequest": { + "id": "test-request-id", + "imp": [ + { + "id": "test-imp-id", + "banner": { + "format": [ + { + "w": 300, + "h": 250 + }, + { + "w": 300, + "h": 300 + } + ] + }, + "ext": { + "bidder": { + "path": "mvo", + "zone": "1r" + } + } + }, + { + "id": "test-imp-video-id", + "video": { + "mimes": [ + "video/mp4" + ], + "minduration": 1, + "maxduration": 2, + "protocols": [ + 1, + 2, + 5 + ], + "w": 1020, + "h": 780, + "startdelay": 1, + "placement": 1, + "playbackmethod": [ + 2 + ], + "delivery": [ + 1 + ], + "api": [ + 1, + 2, + 3, + 4 + ] + }, + "ext": { + "bidder": { + "publisher_id": "72721", + "path": "mvo", + "zone": "1r" + } + } + } + ] + }, + "httpCalls": [ + { + "expectedRequest": { + "uri": "http://localhost/prebid_server?publisher_id=72721", + "body": { + "id": "test-request-id", + "imp": [ + { + "id": "test-imp-id", + "banner": { + "format": [ + { + "w": 300, + "h": 250 + }, + { + "w": 300, + "h": 300 + } + ] + }, + "ext": { + "bidder": { + "zone": "1r", + "path": "mvo" + } + } + }, + { + "id": "test-imp-video-id", + "video": { + "mimes": [ + "video/mp4" + ], + "minduration": 1, + "maxduration": 2, + "protocols": [ + 1, + 2, + 5 + ], + "w": 1020, + "h": 780, + "startdelay": 1, + "placement": 1, + "playbackmethod": [ + 2 + ], + "delivery": [ + 1 + ], + "api": [ + 1, + 2, + 3, + 4 + ] + }, + "ext": { + "bidder": { + "publisher_id": "72721", + "zone": "1r", + "path": "mvo" + } + } + } + ] + } + }, + "mockResponse": { + "status": 200, + "body": { + "id": "test-request-id", + "seatbid": [ + { + "seat": "958", + "bid": [ + { + "id": "7706636740145184841", + "impid": "test-imp-video-id", + "price": 0.500000, + "adid": "29681110", + "adm": "some-test-ad", + "adomain": [ + "yahoo.com" + ], + "cid": "958", + "crid": "29681110", + "h": 576, + "w": 1024, + "mtype": 1 + } + ] + } + ], + "bidid": "5778926625248726496", + "cur": "USD" + } + } + } + ], + "expectedBidResponses": [ + { + "bids": [{ + "bid": { + "id": "7706636740145184841", + "impid": "test-imp-video-id", + "price": 0.5, + "adm": "some-test-ad", + "adid": "29681110", + "adomain": [ + "yahoo.com" + ], + "cid": "958", + "crid": "29681110", + "w": 1024, + "h": 576, + "mtype": 1 + }, + "type": "banner" + }] + } + ] +} diff --git a/adapters/rise/risetest/exemplary/simple-banner.json b/adapters/rise/risetest/exemplary/simple-banner.json new file mode 100644 index 00000000000..13e965d1e2f --- /dev/null +++ b/adapters/rise/risetest/exemplary/simple-banner.json @@ -0,0 +1,115 @@ +{ + "mockBidRequest": { + "id": "test-request-id", + "imp": [ + { + "id": "test-imp-id", + "banner": { + "format": [ + { + "w": 300, + "h": 250 + }, + { + "w": 300, + "h": 300 + } + ] + }, + "ext": { + "bidder": { + "publisher_id": "72721", + "path": "mvo", + "zone": "1r" + } + } + } + ] + }, + "httpCalls": [ + { + "expectedRequest": { + "uri": "http://localhost/prebid_server?publisher_id=72721", + "body": { + "id": "test-request-id", + "imp": [ + { + "id": "test-imp-id", + "banner": { + "format": [ + { + "w": 300, + "h": 250 + }, + { + "w": 300, + "h": 300 + } + ] + }, + "ext": { + "bidder": { + "publisher_id": "72721", + "zone": "1r", + "path": "mvo" + } + } + } + ] + } + }, + "mockResponse": { + "status": 200, + "body": { + "id": "test-request-id", + "seatbid": [ + { + "seat": "Rhythmone", + "bid": [ + { + "id": "7706636740145184841", + "impid": "test-imp-id", + "price": 0.500000, + "adid": "29681110", + "adm": "some-test-ad", + "adomain": [ + "yahoo.com" + ], + "cid": "958", + "crid": "29681110", + "h": 250, + "w": 300, + "mtype": 1 + } + ] + } + ], + "bidid": "5778926625248726496", + "cur": "USD" + } + } + } + ], + "expectedBidResponses": [ + { + "bids": [{ + "bid": { + "id": "7706636740145184841", + "impid": "test-imp-id", + "price": 0.5, + "adm": "some-test-ad", + "adid": "29681110", + "adomain": [ + "yahoo.com" + ], + "cid": "958", + "crid": "29681110", + "w": 300, + "h": 250, + "mtype": 1 + }, + "type": "banner" + }] + } + ] +} diff --git a/adapters/rise/risetest/exemplary/simple-video.json b/adapters/rise/risetest/exemplary/simple-video.json new file mode 100644 index 00000000000..16ca8ac72dc --- /dev/null +++ b/adapters/rise/risetest/exemplary/simple-video.json @@ -0,0 +1,110 @@ +{ + "mockBidRequest": { + "id": "test-request-id", + "imp": [ + { + "id": "test-imp-id", + "video": { + "mimes": [ + "video/mp4" + ], + "minduration": 1, + "maxduration": 2, + "protocols": [1,3,5], + "w": 1020, + "h": 780, + "startdelay": 1, + "placement": 1, + "playbackmethod": [2], + "delivery": [1], + "api": [1,2,3,4] + }, + "ext": { + "bidder": { + "publisher_id": "72721", + "path": "mvo", + "zone": "1r" + } + } + } + ] + }, + "httpCalls": [ + { + "expectedRequest": { + "uri": "http://localhost/prebid_server?publisher_id=72721", + "body": { + "id": "test-request-id", + "imp": [ + { + "id": "test-imp-id", + "video": { + "mimes": [ + "video/mp4" + ], + "minduration": 1, + "maxduration": 2, + "protocols": [1,3,5], + "w": 1020, + "h": 780, + "startdelay": 1, + "placement": 1, + "playbackmethod": [2], + "delivery": [1], + "api": [1,2,3,4] + }, + "ext": { + "bidder": { + "publisher_id": "72721", + "zone": "1r", + "path": "mvo" + } + } + } + ] + } + }, + "mockResponse": { + "status": 200, + "body": { + "id": "test-request-id", + "cur": "USD", + "seatbid": [ + { + "seat": "Rhythmone", + "bid": [ + { + "id": "8ee514f1-b2b8-4abb-89fd-084437d1e800", + "impid": "test-imp-id", + "price": 0.500000, + "adm": "some-test-ad", + "crid": "crid_10", + "w": 1024, + "h": 576, + "mtype": 2 + } + ] + } + ] + } + } + } + ], + "expectedBidResponses": [ + { + "bids": [{ + "bid": { + "id": "8ee514f1-b2b8-4abb-89fd-084437d1e800", + "impid": "test-imp-id", + "price": 0.5, + "adm": "some-test-ad", + "crid": "crid_10", + "w": 1024, + "h": 576, + "mtype": 2 + }, + "type": "video" + }] + } + ] +} diff --git a/adapters/rise/risetest/supplemental/bad-request.json b/adapters/rise/risetest/supplemental/bad-request.json new file mode 100644 index 00000000000..f2ba84b1c78 --- /dev/null +++ b/adapters/rise/risetest/supplemental/bad-request.json @@ -0,0 +1,79 @@ +{ + "mockBidRequest": { + "id": "test-request-id", + "imp": [ + { + "id": "test-imp-id", + "video": { + "mimes": [ + "video/mp4" + ], + "minduration": 1, + "maxduration": 2, + "protocols": [1,3,5], + "w": 1020, + "h": 780, + "startdelay": 1, + "placement": 1, + "playbackmethod": [2], + "delivery": [1], + "api": [1,2,3,4] + }, + "ext": { + "bidder": { + "publisher_id": "72721", + "path": "mvo", + "zone": "1r" + } + } + } + ] + }, + "httpCalls": [ + { + "expectedRequest": { + "uri": "http://localhost/prebid_server?publisher_id=72721", + "body": { + "id": "test-request-id", + "imp": [ + { + "id": "test-imp-id", + "video": { + "mimes": [ + "video/mp4" + ], + "minduration": 1, + "maxduration": 2, + "protocols": [1,3,5], + "w": 1020, + "h": 780, + "startdelay": 1, + "placement": 1, + "playbackmethod": [2], + "delivery": [1], + "api": [1,2,3,4] + }, + "ext": { + "bidder": { + "publisher_id": "72721", + "zone": "1r", + "path": "mvo" + } + } + } + ] + } + }, + "mockResponse": { + "status": 400, + "body": {} + } + } + ], + "expectedMakeBidsErrors": [ + { + "value": "Unexpected status code: 400. Run with request.debug = 1 for more info", + "comparison": "literal" + } + ] +} diff --git a/adapters/rise/risetest/supplemental/missing-bidder.json b/adapters/rise/risetest/supplemental/missing-bidder.json new file mode 100644 index 00000000000..2bda5161c67 --- /dev/null +++ b/adapters/rise/risetest/supplemental/missing-bidder.json @@ -0,0 +1,35 @@ +{ + "mockBidRequest": { + "id": "test-request-id", + "imp": [ + { + "id": "test-missing-ext-id", + "video": { + "mimes": [ + "video/mp4" + ], + "minduration": 1, + "maxduration": 2, + "maxextended": 30, + "minbitrate": 300, + "maxbitrate": 1500, + "protocols": [1,2,5], + "w": 1020, + "h": 780, + "startdelay": 1, + "placement": 1, + "playbackmethod": [2], + "delivery": [1], + "api": [1,2,3,4] + }, + "ext": {} + } + ] + }, + "expectedMakeRequestsErrors": [ + { + "value": "extractPublisherID: unmarshal ImpExtRise: unexpected end of JSON input", + "comparison": "literal" + } + ] +} diff --git a/adapters/rise/risetest/supplemental/missing-extension.json b/adapters/rise/risetest/supplemental/missing-extension.json new file mode 100644 index 00000000000..db8dbdf74d9 --- /dev/null +++ b/adapters/rise/risetest/supplemental/missing-extension.json @@ -0,0 +1,34 @@ +{ + "mockBidRequest": { + "id": "test-request-id", + "imp": [ + { + "id": "test-missing-ext-id", + "video": { + "mimes": [ + "video/mp4" + ], + "minduration": 1, + "maxduration": 2, + "maxextended": 30, + "minbitrate": 300, + "maxbitrate": 1500, + "protocols": [1,2,5], + "w": 1020, + "h": 780, + "startdelay": 1, + "placement": 1, + "playbackmethod": [2], + "delivery": [1], + "api": [1,2,3,4] + } + } + ] + }, + "expectedMakeRequestsErrors": [ + { + "value": "extractPublisherID: unmarshal bidderExt: unexpected end of JSON input", + "comparison": "literal" + } + ] +} diff --git a/adapters/rise/risetest/supplemental/missing-mtype.json b/adapters/rise/risetest/supplemental/missing-mtype.json new file mode 100644 index 00000000000..c46cb2f442e --- /dev/null +++ b/adapters/rise/risetest/supplemental/missing-mtype.json @@ -0,0 +1,117 @@ +{ + "mockBidRequest": { + "id": "test-request-id", + "imp": [ + { + "id": "test-imp-id", + "video": { + "mimes": [ + "video/mp4" + ], + "minduration": 1, + "maxduration": 2, + "protocols": [1,3,5], + "w": 1020, + "h": 780, + "startdelay": 1, + "placement": 1, + "playbackmethod": [2], + "delivery": [1], + "api": [1,2,3,4] + }, + "ext": { + "bidder": { + "publisher_id": "72721", + "path": "mvo", + "zone": "1r" + } + } + } + ] + }, + "httpCalls": [ + { + "expectedRequest": { + "uri": "http://localhost/prebid_server?publisher_id=72721", + "body": { + "id": "test-request-id", + "imp": [ + { + "id": "test-imp-id", + "video": { + "mimes": [ + "video/mp4" + ], + "minduration": 1, + "maxduration": 2, + "protocols": [1,3,5], + "w": 1020, + "h": 780, + "startdelay": 1, + "placement": 1, + "playbackmethod": [2], + "delivery": [1], + "api": [1,2,3,4] + }, + "ext": { + "bidder": { + "publisher_id": "72721", + "zone": "1r", + "path": "mvo" + } + } + } + ] + } + }, + "mockResponse": { + "status": 200, + "body": { + "id": "test-request-id", + "cur": "USD", + "seatbid": [ + { + "seat": "Rhythmone", + "bid": [ + { + "id": "8ee514f1-b2b8-4abb-89fd-084437d1e800", + "impid": "test-imp-id", + "price": 0.500000, + "adm": "some-test-ad", + "crid": "crid_10", + "w": 1024, + "h": 576 + } + ] + }, + { + "seat": "Rhythmone", + "bid": [ + { + "id": "8ee514f1-b2b8-4abb-89fd-084437d1e800", + "impid": "test-imp-id", + "price": 0.500000, + "adm": "some-test-ad", + "crid": "crid_10", + "w": 1024, + "h": 576, + "mtype": 7 + } + ] + } + ] + } + } + } + ], + "expectedMakeBidsErrors": [ + { + "value": "unsupported MType 0", + "comparison": "literal" + }, + { + "value": "unsupported MType 7", + "comparison": "literal" + } + ] +} diff --git a/adapters/rise/risetest/supplemental/missing-publisher-id.json b/adapters/rise/risetest/supplemental/missing-publisher-id.json new file mode 100644 index 00000000000..3a14b213160 --- /dev/null +++ b/adapters/rise/risetest/supplemental/missing-publisher-id.json @@ -0,0 +1,38 @@ +{ + "mockBidRequest": { + "id": "test-request-id", + "imp": [ + { + "id": "test-missing-ext-id", + "video": { + "mimes": [ + "video/mp4" + ], + "minduration": 1, + "maxduration": 2, + "maxextended": 30, + "minbitrate": 300, + "maxbitrate": 1500, + "protocols": [1,2,5], + "w": 1020, + "h": 780, + "startdelay": 1, + "placement": 1, + "playbackmethod": [2], + "delivery": [1], + "api": [1,2,3,4] + }, + "ext": { + "bidder": { + "publisher_id": "" + }} + } + ] + }, + "expectedMakeRequestsErrors": [ + { + "value": "extractPublisherID: no publisherID supplied", + "comparison": "literal" + } + ] +} diff --git a/exchange/adapter_builders.go b/exchange/adapter_builders.go index ef45f71e34a..d67922c9532 100755 --- a/exchange/adapter_builders.go +++ b/exchange/adapter_builders.go @@ -131,6 +131,7 @@ import ( "github.com/prebid/prebid-server/adapters/revcontent" "github.com/prebid/prebid-server/adapters/rhythmone" "github.com/prebid/prebid-server/adapters/richaudience" + "github.com/prebid/prebid-server/adapters/rise" "github.com/prebid/prebid-server/adapters/rtbhouse" "github.com/prebid/prebid-server/adapters/rubicon" salunamedia "github.com/prebid/prebid-server/adapters/sa_lunamedia" @@ -318,6 +319,7 @@ func newAdapterBuilders() map[openrtb_ext.BidderName]adapters.Builder { openrtb_ext.BidderRevcontent: revcontent.Builder, openrtb_ext.BidderRhythmone: rhythmone.Builder, openrtb_ext.BidderRichaudience: richaudience.Builder, + openrtb_ext.BidderRise: rise.Builder, openrtb_ext.BidderRTBHouse: rtbhouse.Builder, openrtb_ext.BidderRubicon: rubicon.Builder, openrtb_ext.BidderSeedingAlliance: seedingAlliance.Builder, diff --git a/openrtb_ext/bidders.go b/openrtb_ext/bidders.go index 145e66f3f5f..5def556c17f 100644 --- a/openrtb_ext/bidders.go +++ b/openrtb_ext/bidders.go @@ -225,6 +225,7 @@ const ( BidderRevcontent BidderName = "revcontent" BidderRhythmone BidderName = "rhythmone" BidderRichaudience BidderName = "richaudience" + BidderRise BidderName = "rise" BidderRTBHouse BidderName = "rtbhouse" BidderRubicon BidderName = "rubicon" BidderSeedingAlliance BidderName = "seedingAlliance" @@ -415,6 +416,7 @@ func CoreBidderNames() []BidderName { BidderRevcontent, BidderRhythmone, BidderRichaudience, + BidderRise, BidderRTBHouse, BidderRubicon, BidderSeedingAlliance, diff --git a/openrtb_ext/imp_rise.go b/openrtb_ext/imp_rise.go new file mode 100644 index 00000000000..4bdd302ee99 --- /dev/null +++ b/openrtb_ext/imp_rise.go @@ -0,0 +1,6 @@ +package openrtb_ext + +// ImpExtRise defines the contract for bidrequest.imp[i].ext.prebid.bidder.rise +type ImpExtRise struct { + PublisherID string `json:"publisher_id"` +} diff --git a/static/bidder-info/rise.yaml b/static/bidder-info/rise.yaml new file mode 100644 index 00000000000..d429e8780a7 --- /dev/null +++ b/static/bidder-info/rise.yaml @@ -0,0 +1,18 @@ +endpoint: "https://pbs.yellowblue.io/pbs" +maintainer: + email: rise-prog-dev@risecodes.com +gvlVendorID: 1043 +modifyingVastXmlAllowed: false +capabilities: + app: + mediaTypes: + - banner + - video + site: + mediaTypes: + - banner + - video +userSync: + iframe: + url: https://pbs-cs.yellowblue.io/pbs-iframe?gdpr={{.GDPR}}&gdpr_consent={{.GDPRConsent}}&us_privacy={{.USPrivacy}}&redirect={{.RedirectURL}} + userMacro: "[PBS_UID]" diff --git a/static/bidder-params/rise.json b/static/bidder-params/rise.json new file mode 100644 index 00000000000..8e745d89fd0 --- /dev/null +++ b/static/bidder-params/rise.json @@ -0,0 +1,13 @@ +{ + "$schema": "http://json-schema.org/draft-04/schema#", + "title": "Rise Adapter Params", + "description": "A schema which validates params accepted by the Rise adapter", + "type": "object", + "properties": { + "publisher_id": { + "type": "string", + "description": "The publisher ID" + } + }, + "required": ["publisher_id"] +}