diff --git a/adapters/nativo/nativo.go b/adapters/nativo/nativo.go new file mode 100644 index 00000000000..a3bc33bb0df --- /dev/null +++ b/adapters/nativo/nativo.go @@ -0,0 +1,95 @@ +package nativo + +import ( + "encoding/json" + "fmt" + "net/http" + + "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" +) + +type adapter struct { + endpoint string +} + +// Builder builds a new instance of the Nativo adapter for the given bidder with the given config. +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, _ *adapters.ExtraRequestInfo) ([]*adapters.RequestData, []error) { + requestJSON, err := json.Marshal(request) + if err != nil { + return nil, []error{err} + } + + headers := http.Header{} + headers.Add("Content-Type", "application/json;charset=utf-8") + + requestData := &adapters.RequestData{ + Method: "POST", + Uri: a.endpoint, + Body: requestJSON, + Headers: headers, + } + + return []*adapters.RequestData{requestData}, nil +} + +func (a *adapter) MakeBids(request *openrtb2.BidRequest, externalRequest *adapters.RequestData, response *adapters.ResponseData) (*adapters.BidderResponse, []error) { + if adapters.IsResponseStatusCodeNoContent(response) { + return nil, nil + } + + if err := adapters.CheckResponseStatusCodeForErrors(response); err != nil { + return nil, []error{err} + } + + var bidResp openrtb2.BidResponse + + if err := json.Unmarshal(response.Body, &bidResp); err != nil { + return nil, []error{err} + } + + bidResponse := adapters.NewBidderResponse() + + var errs []error + for _, seatBid := range bidResp.SeatBid { + for i := range seatBid.Bid { + bidType, err := getMediaTypeForImp(seatBid.Bid[i].ImpID, request.Imp) + if err != nil { + errs = append(errs, err) + continue + } + + b := &adapters.TypedBid{ + Bid: &seatBid.Bid[i], + BidType: bidType, + } + + bidResponse.Bids = append(bidResponse.Bids, b) + } + } + return bidResponse, errs +} + +func getMediaTypeForImp(impID string, imps []openrtb2.Imp) (openrtb_ext.BidType, error) { + for _, imp := range imps { + if imp.ID == impID { + if imp.Native != nil { + return openrtb_ext.BidTypeNative, nil + } else if imp.Video != nil { + return openrtb_ext.BidTypeVideo, nil + } else if imp.Banner != nil { + return openrtb_ext.BidTypeBanner, nil + } + } + } + return "", fmt.Errorf("Unrecognized impression type in response from nativo: %s", impID) +} diff --git a/exchange/adapter_builders.go b/exchange/adapter_builders.go index 3818a16a03a..a4894c68cee 100755 --- a/exchange/adapter_builders.go +++ b/exchange/adapter_builders.go @@ -118,6 +118,7 @@ import ( "github.com/prebid/prebid-server/adapters/mobilefuse" "github.com/prebid/prebid-server/adapters/motorik" "github.com/prebid/prebid-server/adapters/nanointeractive" + "github.com/prebid/prebid-server/adapters/nativo" "github.com/prebid/prebid-server/adapters/nextmillennium" "github.com/prebid/prebid-server/adapters/ninthdecimal" "github.com/prebid/prebid-server/adapters/nobid" @@ -309,6 +310,7 @@ func newAdapterBuilders() map[openrtb_ext.BidderName]adapters.Builder { openrtb_ext.BidderMobfoxpb: mobfoxpb.Builder, openrtb_ext.BidderMobileFuse: mobilefuse.Builder, openrtb_ext.BidderMotorik: motorik.Builder, + openrtb_ext.BidderNativo: nativo.Builder, openrtb_ext.BidderNanoInteractive: nanointeractive.Builder, openrtb_ext.BidderNextMillennium: nextmillennium.Builder, openrtb_ext.BidderNinthDecimal: ninthdecimal.Builder, diff --git a/openrtb_ext/bidders.go b/openrtb_ext/bidders.go index b3e57f17b44..fd0b274cf43 100644 --- a/openrtb_ext/bidders.go +++ b/openrtb_ext/bidders.go @@ -210,6 +210,7 @@ const ( BidderMobfoxpb BidderName = "mobfoxpb" BidderMobileFuse BidderName = "mobilefuse" BidderMotorik BidderName = "motorik" + BidderNativo BidderName = "nativo" BidderNanoInteractive BidderName = "nanointeractive" BidderNextMillennium BidderName = "nextmillennium" BidderNinthDecimal BidderName = "ninthdecimal" @@ -418,6 +419,7 @@ func CoreBidderNames() []BidderName { BidderMobfoxpb, BidderMobileFuse, BidderMotorik, + BidderNativo, BidderNanoInteractive, BidderNextMillennium, BidderNinthDecimal, diff --git a/openrtb_ext/imp.go b/openrtb_ext/imp.go index d0c07ef4e77..ccc779120fe 100644 --- a/openrtb_ext/imp.go +++ b/openrtb_ext/imp.go @@ -2,6 +2,8 @@ package openrtb_ext import ( "encoding/json" + + "github.com/prebid/openrtb/v19/openrtb2" ) // AuctionEnvironmentType is a Google Privacy Sandbox flag indicating where the auction may take place @@ -84,3 +86,12 @@ type ExtStoredBidResponse struct { type Options struct { EchoVideoAttrs bool `json:"echovideoattrs"` } + +// GetImpIDs returns slice of all impression Ids from impList +func GetImpIDs(imps []openrtb2.Imp) []string { + impIDs := make([]string, len(imps)) + for i := range imps { + impIDs[i] = imps[i].ID + } + return impIDs +} diff --git a/static/bidder-info/nativo.yaml b/static/bidder-info/nativo.yaml new file mode 100644 index 00000000000..308fc6388db --- /dev/null +++ b/static/bidder-info/nativo.yaml @@ -0,0 +1,22 @@ +endpoint: "https://exchange.postrelease.com/esi?ntv_epid=7" +maintainer: + email: "prebiddev@nativo.com" +gvlVendorID: 263 +capabilities: + app: + mediaTypes: + - banner + - video + - native + site: + mediaTypes: + - banner + - video + - native +userSync: + redirect: + url: https://jadserve.postrelease.com/suid/101787?gdpr={{.GDPR}}&gdpr_consent={{.GDPRConsent}}&us_privacy={{.USPrivacy}}&ntv_gpp_consent={{.GPP}}&ntv_r={{.RedirectURL}} + userMacro: NTV_USER_ID +openrtb: + version: 2.6 + gpp-supported: true \ No newline at end of file diff --git a/static/bidder-params/nativo.json b/static/bidder-params/nativo.json new file mode 100644 index 00000000000..0a8139a0838 --- /dev/null +++ b/static/bidder-params/nativo.json @@ -0,0 +1,7 @@ +{ + "$schema": "http://json-schema.org/draft-04/schema#", + "title": "Nativo Adapter Params", + "description": "A schema which validates params accepted by the Nativo adapter", + "type": "object", + "properties": {} +} \ No newline at end of file