-
Notifications
You must be signed in to change notification settings - Fork 896
New Adapter: Nexx360 #4286
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
New Adapter: Nexx360 #4286
Changes from all commits
0c9c031
b620c82
a6a8b9d
ddf8840
d383c49
70c6882
5a6f521
dfd21d7
54baa41
9959335
9a656bc
60e490d
bc990bd
cc882db
1ac372c
b2beef7
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,226 @@ | ||
| package nexx360 | ||
|
|
||
| import ( | ||
| "encoding/json" | ||
| "fmt" | ||
| "net/http" | ||
| "net/url" | ||
|
|
||
| "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" | ||
| "github.com/prebid/prebid-server/v3/version" | ||
| ) | ||
|
|
||
| type adapter struct { | ||
| endpoint string | ||
| } | ||
|
|
||
| type Ext struct { | ||
| Nexx360 json.RawMessage `json:"nexx360"` | ||
| } | ||
|
|
||
| type Nexx360Caller struct { | ||
| Name string `json:"name,omitempty"` | ||
| Version string `json:"version,omitempty"` | ||
| } | ||
|
|
||
| type ReqExt struct { | ||
| Nexx360 *ReqNexx360Ext `json:"nexx360,omitempty"` | ||
| } | ||
|
|
||
| type ReqNexx360Ext struct { | ||
| Caller []Nexx360Caller `json:"caller,omitempty"` | ||
| } | ||
|
|
||
| type Nexx360ResBidExt struct { | ||
| BidType string `json:"bidType,omitempty"` | ||
| } | ||
|
|
||
| func Builder(bidderName openrtb_ext.BidderName, config config.Adapter, server config.Server) (adapters.Bidder, error) { | ||
| return &adapter{endpoint: config.Endpoint}, nil | ||
| } | ||
|
|
||
| // CALLER Info used to track Prebid Server | ||
| // as one of the hops in the request to exchange | ||
|
|
||
| func getVersion() string { | ||
| if version.Ver != "" { | ||
| return version.Ver | ||
| } | ||
| return "n/a" | ||
| } | ||
|
|
||
| var CALLER = Nexx360Caller{"Prebid-Server", getVersion()} | ||
|
|
||
| func processImps(impList []openrtb2.Imp) (imp []openrtb2.Imp, tagId string, placement string, error error) { | ||
| var imps []openrtb2.Imp | ||
| for idx, imp := range impList { | ||
| var bidderExt adapters.ExtImpBidder | ||
| if err := jsonutil.Unmarshal(imp.Ext, &bidderExt); err != nil { | ||
| return nil, "", "", &errortypes.BadInput{ | ||
| Message: err.Error(), | ||
| } | ||
| } | ||
|
|
||
| impExt := Ext{ | ||
| Nexx360: bidderExt.Bidder, | ||
| } | ||
|
|
||
| impExtJSON, err := json.Marshal(impExt) | ||
| if err != nil { | ||
| return nil, "", "", &errortypes.BadInput{ | ||
| Message: err.Error(), | ||
| } | ||
| } | ||
|
|
||
| impCopy := imp | ||
| impCopy.Ext = impExtJSON | ||
| imps = append(imps, impCopy) | ||
| if idx == 0 { | ||
|
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I'm sorry I was gone for so long. One last ask: Can we please move the unmarshal of
Contributor
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. @guscarreon done :) |
||
| var nexx360Ext openrtb_ext.ExtImpNexx360 | ||
| if err := jsonutil.Unmarshal(bidderExt.Bidder, &nexx360Ext); err != nil { | ||
| return nil, "", "", &errortypes.BadInput{ | ||
| Message: err.Error(), | ||
| } | ||
| } | ||
|
Comment on lines
+84
to
+89
Collaborator
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I think these lines can be deleted. You're already unmarshaling
Contributor
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Done |
||
| tagId = nexx360Ext.TagId | ||
| placement = nexx360Ext.Placement | ||
| } | ||
| } | ||
|
|
||
| return imps, tagId, placement, nil | ||
| } | ||
|
|
||
| func makeReqExt() ([]byte, error) { | ||
| reqExt := ReqExt{ | ||
| Nexx360: &ReqNexx360Ext{ | ||
| Caller: []Nexx360Caller{CALLER}, | ||
| }, | ||
| } | ||
|
|
||
| return json.Marshal(reqExt) | ||
| } | ||
|
|
||
| func (a *adapter) MakeRequests(request *openrtb2.BidRequest, reqInfo *adapters.ExtraRequestInfo) ([]*adapters.RequestData, []error) { | ||
| var imp, tagId, placement, err = processImps(request.Imp) | ||
| if err != nil { | ||
| return nil, []error{err} | ||
| } | ||
|
|
||
| request.Imp = imp | ||
|
|
||
| urlBuilder, err := url.Parse(a.endpoint) | ||
| if err != nil { | ||
| return nil, []error{err} | ||
| } | ||
|
|
||
| query := url.Values{} | ||
|
|
||
| if placement != "" { | ||
| query.Add("placement", placement) | ||
| } | ||
|
|
||
| if tagId != "" { | ||
| query.Add("tag_id", tagId) | ||
| } | ||
| urlBuilder.RawQuery = query.Encode() | ||
|
|
||
| uri := urlBuilder.String() | ||
|
|
||
| reqExt, err := makeReqExt() | ||
| if err != nil { | ||
| return nil, []error{err} | ||
| } | ||
| request.Ext = reqExt | ||
|
|
||
| // Last Step | ||
| reqJSON, err := json.Marshal(request) | ||
| if err != nil { | ||
| return nil, []error{err} | ||
| } | ||
|
|
||
| headers := http.Header{} | ||
| headers.Add("Content-Type", "application/json") | ||
|
|
||
| adapter := &adapters.RequestData{ | ||
| Method: http.MethodPost, | ||
| Uri: uri, | ||
| Body: reqJSON, | ||
| Headers: headers, | ||
| ImpIDs: openrtb_ext.GetImpIDs(request.Imp), | ||
| } | ||
|
|
||
| return []*adapters.RequestData{adapter}, nil | ||
| } | ||
|
|
||
| // MakeBids make the bids for the bid response. | ||
| func (a *adapter) MakeBids(request *openrtb2.BidRequest, externalRequest *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{&errortypes.BadInput{ | ||
| Message: fmt.Sprintf("Unexpected http status code: %d", responseData.StatusCode), | ||
| }} | ||
| } | ||
|
|
||
| var response openrtb2.BidResponse | ||
|
|
||
| if err := jsonutil.Unmarshal(responseData.Body, &response); err != nil { | ||
| return nil, []error{err} | ||
|
Collaborator
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Please add a
Contributor
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Done |
||
| } | ||
|
|
||
| var Bids []*adapters.TypedBid | ||
| var errors []error | ||
| for _, seatBid := range response.SeatBid { | ||
| for i, bid := range seatBid.Bid { | ||
|
|
||
| bidType, err := getBidType(bid) | ||
| if err != nil { | ||
| errors = append(errors, err) | ||
| continue | ||
| } | ||
| Bids = append(Bids, &adapters.TypedBid{ | ||
| Bid: &seatBid.Bid[i], | ||
| BidType: bidType, | ||
| }) | ||
| } | ||
| } | ||
| if len(Bids) == 0 { | ||
| return nil, nil | ||
|
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Is there any reason you are entirely discarding the response from adapter and returning nil, instead of returning response itselt?
Contributor
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. This is kept as it causes issues with tests. |
||
| } | ||
| bidResponse := adapters.NewBidderResponseWithBidsCapacity(len(Bids)) | ||
| bidResponse.Bids = Bids | ||
| if response.Cur != "" { | ||
| bidResponse.Currency = response.Cur | ||
| } | ||
|
|
||
| return bidResponse, errors | ||
| } | ||
|
|
||
| func getBidType(bid openrtb2.Bid) (openrtb_ext.BidType, error) { | ||
| var bidExt Nexx360ResBidExt | ||
| err := jsonutil.Unmarshal(bid.Ext, &bidExt) | ||
|
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Any reason why
Contributor
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Those are our internal processes based on Open RTB 2.5, might be further updated |
||
| if err == nil { | ||
| if bidExt.BidType == "video" { | ||
| return openrtb_ext.BidTypeVideo, nil | ||
| } | ||
| if bidExt.BidType == "audio" { | ||
| return openrtb_ext.BidTypeAudio, nil | ||
|
Collaborator
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Please add an
Contributor
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Done |
||
| } | ||
| if bidExt.BidType == "native" { | ||
| return openrtb_ext.BidTypeNative, nil | ||
| } | ||
| if bidExt.BidType == "banner" { | ||
| return openrtb_ext.BidTypeBanner, nil | ||
| } | ||
| } | ||
| return "", &errortypes.BadServerResponse{ | ||
| Message: fmt.Sprintf("unable to fetch mediaType in multi-format: %s", bid.ImpID), | ||
| } | ||
| } | ||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,20 @@ | ||
| package nexx360 | ||
|
|
||
| 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.BidderNexx360, config.Adapter{ | ||
| Endpoint: "http://fast.nexx360.io/prebid-server"}, config.Server{ExternalUrl: "http://hosturl.com", GvlID: 1, DataCenter: "2"}) | ||
|
|
||
| if buildErr != nil { | ||
| t.Fatalf("Builder returned unexpected error %v", buildErr) | ||
| } | ||
|
|
||
| adapterstest.RunJSONBidderTest(t, "nexx360test", bidder) | ||
| } |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Please update one of your JSON tests to include a non-empty string version.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I don't get how to do this
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Oops I thought the version was on the incoming request but this is the PBS version. You don't need to add any additional test coverage.