Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
94 changes: 94 additions & 0 deletions adapters/oprx/oprx.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,94 @@
package oprx

import (
"fmt"
"net/http"

"github.com/prebid/openrtb/v20/openrtb2"
"github.com/prebid/prebid-server/v3/adapters"
"github.com/prebid/prebid-server/v3/config"
"github.com/prebid/prebid-server/v3/errortypes"
"github.com/prebid/prebid-server/v3/openrtb_ext"
"github.com/prebid/prebid-server/v3/util/jsonutil"
)

type adapter struct {
endpoint string
}

func Builder(bidderName openrtb_ext.BidderName, config config.Adapter, server config.Server) (adapters.Bidder, error) {
bidder := &adapter{
endpoint: config.Endpoint,
}
return bidder, nil
}

func (a *adapter) MakeRequests(request *openrtb2.BidRequest, requestInfo *adapters.ExtraRequestInfo) ([]*adapters.RequestData, []error) {
requestJSON, err := jsonutil.Marshal(request)
if err != nil {
return nil, []error{err}
}

requestData := &adapters.RequestData{
Method: "POST",
Uri: a.endpoint,
Body: requestJSON,
ImpIDs: openrtb_ext.GetImpIDs(request.Imp),
}

return []*adapters.RequestData{requestData}, nil
}

func (a *adapter) MakeBids(request *openrtb2.BidRequest, requestData *adapters.RequestData, responseData *adapters.ResponseData) (*adapters.BidderResponse, []error) {
if adapters.IsResponseStatusCodeNoContent(responseData) {
return nil, nil
}

if err := adapters.CheckResponseStatusCodeForErrors(responseData); err != nil {
return nil, []error{err}
}

if responseData.StatusCode != http.StatusOK {
err := &errortypes.BadServerResponse{
Message: fmt.Sprintf("Unexpected status code: %d. Run with request.debug = 1 for more info.", responseData.StatusCode),
}
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(request.Imp))
bidResponse.Currency = response.Cur
var errors []error
for _, seatBid := range response.SeatBid {
for i, bid := range seatBid.Bid {
bidType, err := getMediaTypeForBid(bid)
if err != nil {
errors = append(errors, err)
continue
}
bidResponse.Bids = append(bidResponse.Bids, &adapters.TypedBid{
Bid: &seatBid.Bid[i],
BidType: bidType,
})
}
}
return bidResponse, nil
}

func getMediaTypeForBid(bid openrtb2.Bid) (openrtb_ext.BidType, error) {
if bid.Ext != nil {
var bidExt openrtb_ext.ExtBid
err := jsonutil.Unmarshal(bid.Ext, &bidExt)
if err == nil && bidExt.Prebid != nil {
return openrtb_ext.ParseBidType(string(bidExt.Prebid.Type))
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Consider this as a suggestion. Prebid server expects the media type to be explicitly set in the adapter response. Therefore, recommends implementing a pattern where the adapter server sets the MType field in the response to accurately determine the media type for the impression.

}
}

return "", &errortypes.BadServerResponse{
Message: fmt.Sprintf("Failed to parse impression \"%s\" mediatype", bid.ImpID),
}
}
21 changes: 21 additions & 0 deletions adapters/oprx/oprx_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
package oprx

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.BidderOprx, config.Adapter{
Endpoint: "http://localhost:8080"},
config.Server{ExternalUrl: "http://hosturl.com", GvlID: 1, DataCenter: "2"})

if buildErr != nil {
t.Fatalf("Builder returned unexpected error %v", buildErr)
}

adapterstest.RunJSONBidderTest(t, "oprxtest", bidder)
}
121 changes: 121 additions & 0 deletions adapters/oprx/oprxtest/exemplary/banner.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,121 @@
{
Comment thread
Ivan-Z-Oprx marked this conversation as resolved.
"mockBidRequest": {
"id": "request-id",
"imp": [
{
"id": "imp-id",
"banner": {
"format": [
{
"w": 300,
"h": 250
}
]
},
"ext": {
"bidder": {
"key": "p123",
"placement_id": "my-placement-id",
"bid-floor": 0.5,
"npi": "my-npi",
"ndc": "my-ndc"
}
}
}
]
},
"httpCalls": [{
"expectedRequest": {
"uri": "http://localhost:8080",
"body": {
"id": "request-id",
"imp": [
{
"id": "imp-id",
"banner": {
"format": [
{
"w": 300,
"h": 250
}
]
},
"ext": {
"bidder": {
"key": "p123",
"placement_id": "my-placement-id",
"bid-floor": 0.5,
"npi": "my-npi",
"ndc": "my-ndc"
}
}
}
]
},
"impIDs": ["imp-id"]
},
"mockResponse": {
"status": 200,
"body": {
"id": "request-id",
"seatbid": [
{
"seat": "958",
"bid": [
{
"id": "bid-id",
"impid": "imp-id",
"price": 0.5,
"adid": "29681110",
"adm": "some-test-ad",
"adomain": [
"foo.com"
],
"crid": "29681110",
"h": 250,
"w": 300,
"dealid": "test deal",
"ext": {
"prebid": {
"type": "banner"
}
}
}
]
}
],
"bidid": "request-id",
"cur": "USD"
}
}
}],
"expectedBidResponses": [
{
"currency": "USD",
"bids": [
{
"bid": {
"id": "bid-id",
"impid": "imp-id",
"price": 0.5,
"adid": "29681110",
"adm": "some-test-ad",
"adomain": [
"foo.com"
],
"crid": "29681110",
"h": 250,
"w": 300,
"dealid": "test deal",
"ext": {
"prebid": {
"type": "banner"
}
}
},
"type": "banner"
}
]
}
]
}
Loading
Loading