diff --git a/adapters/adview/adview.go b/adapters/adview/adview.go index 88a236dc87f..d880cc4956a 100644 --- a/adapters/adview/adview.go +++ b/adapters/adview/adview.go @@ -19,6 +19,10 @@ type adapter struct { endpoint *template.Template } +type adviewBidExt struct { + BidType int `json:"formattype,omitempty"` +} + // Builder builds a new instance of the adview adapter for the given bidder with the given config. func Builder(bidderName openrtb_ext.BidderName, config config.Adapter, server config.Server) (adapters.Bidder, error) { endpointTemplate, err := template.New("endpointTemplate").Parse(config.Endpoint) @@ -33,63 +37,78 @@ func Builder(bidderName openrtb_ext.BidderName, config config.Adapter, server co } func (a *adapter) MakeRequests(request *openrtb2.BidRequest, requestInfo *adapters.ExtraRequestInfo) ([]*adapters.RequestData, []error) { - var bidderExt adapters.ExtImpBidder - imp := &request.Imp[0] - if err := json.Unmarshal(imp.Ext, &bidderExt); err != nil { - return nil, []error{&errortypes.BadInput{ - Message: fmt.Sprintf("invalid imp.ext, %s", err.Error()), - }} - } - //use adview - var advImpExt openrtb_ext.ExtImpAdView - if err := json.Unmarshal(bidderExt.Bidder, &advImpExt); err != nil { - return nil, []error{&errortypes.BadInput{ - Message: fmt.Sprintf("invalid bidderExt.Bidder, %s", err.Error()), - }} - } - imp.TagID = advImpExt.MasterTagID //tagid means posid - //for adview bid request - if imp.Banner != nil { - if len(imp.Banner.Format) != 0 { - bannerCopy := *imp.Banner - bannerCopy.H = &imp.Banner.Format[0].H - bannerCopy.W = &imp.Banner.Format[0].W - imp.Banner = &bannerCopy + var requests []*adapters.RequestData + var errors []error + + //must copy the original request. + requestCopy := *request + for _, imp := range request.Imp { + var bidderExt adapters.ExtImpBidder + if err := json.Unmarshal(imp.Ext, &bidderExt); err != nil { + errors = append(errors, &errortypes.BadInput{ + Message: fmt.Sprintf("invalid imp.ext, %s", err.Error()), + }) + continue + } + //use adview + var advImpExt openrtb_ext.ExtImpAdView + if err := json.Unmarshal(bidderExt.Bidder, &advImpExt); err != nil { + errors = append(errors, &errortypes.BadInput{ + Message: fmt.Sprintf("invalid bidderExt.Bidder, %s", err.Error()), + }) + continue } - } - // Check if imp comes with bid floor amount defined in a foreign currency - if imp.BidFloor > 0 && imp.BidFloorCur != "" && strings.ToUpper(imp.BidFloorCur) != "USD" { - // Convert to US dollars - convertedValue, err := requestInfo.ConvertCurrency(imp.BidFloor, imp.BidFloorCur, "USD") - if err != nil { - return nil, []error{err} + imp.TagID = advImpExt.MasterTagID //tagid means posid + //for adview bid request + if imp.Banner != nil { + if len(imp.Banner.Format) != 0 { + bannerCopy := *imp.Banner + bannerCopy.H = &imp.Banner.Format[0].H + bannerCopy.W = &imp.Banner.Format[0].W + imp.Banner = &bannerCopy + } } - // Update after conversion. All imp elements inside request.Imp are shallow copies - // therefore, their non-pointer values are not shared memory and are safe to modify. - imp.BidFloorCur = "USD" - imp.BidFloor = convertedValue - } - // Set the CUR of bid to USD after converting all floors - request.Cur = []string{"USD"} + // Check if imp comes with bid floor amount defined in a foreign currency + if imp.BidFloor > 0 && imp.BidFloorCur != "" && strings.ToUpper(imp.BidFloorCur) != "USD" { + // Convert to US dollars + convertedValue, err := requestInfo.ConvertCurrency(imp.BidFloor, imp.BidFloorCur, "USD") + if err != nil { + errors = append(errors, err) + continue + } + // Update after conversion. All imp elements inside request.Imp are shallow copies + // therefore, their non-pointer values are not shared memory and are safe to modify. + imp.BidFloorCur = "USD" + imp.BidFloor = convertedValue + } - url, err := a.buildEndpointURL(&advImpExt) - if err != nil { - return nil, []error{err} - } + // Set the CUR of bid to USD after converting all floors + requestCopy.Cur = []string{"USD"} + requestCopy.Imp = []openrtb2.Imp{imp} - reqJSON, err := json.Marshal(request) - if err != nil { - return nil, []error{err} - } + url, err := a.buildEndpointURL(&advImpExt) + if err != nil { + errors = append(errors, err) + continue + } + + reqJSON, err := json.Marshal(requestCopy) //request + if err != nil { + errors = append(errors, err) + continue + } - return []*adapters.RequestData{{ - Method: http.MethodPost, - Body: reqJSON, - Uri: url, - }}, nil + requestData := &adapters.RequestData{ + Method: http.MethodPost, + Uri: url, + Body: reqJSON, + } + requests = append(requests, requestData) + } + return requests, errors } func (a *adapter) MakeBids(request *openrtb2.BidRequest, requestData *adapters.RequestData, responseData *adapters.ResponseData) (*adapters.BidderResponse, []error) { @@ -117,12 +136,13 @@ func (a *adapter) MakeBids(request *openrtb2.BidRequest, requestData *adapters.R } bidResponse := adapters.NewBidderResponseWithBidsCapacity(len(request.Imp)) - bidResponse.Currency = "USD" //we just support USD for resp + //we just support USD for resp + bidResponse.Currency = "USD" var errors []error for _, seatBid := range response.SeatBid { for i, bid := range seatBid.Bid { - bidType, err := getMediaTypeForImp(bid.ImpID, request.Imp) + bidType, err := getMediaTypeForBid(bid) if err != nil { errors = append(errors, err) continue @@ -143,17 +163,15 @@ func (a *adapter) buildEndpointURL(params *openrtb_ext.ExtImpAdView) (string, er return macros.ResolveMacros(a.endpoint, endpointParams) } -func getMediaTypeForImp(impID string, imps []openrtb2.Imp) (openrtb_ext.BidType, error) { - mediaType := openrtb_ext.BidTypeBanner - for _, imp := range imps { - if imp.ID == impID { - if imp.Video != nil { - mediaType = openrtb_ext.BidTypeVideo - } else if imp.Native != nil { - mediaType = openrtb_ext.BidTypeNative - } - return mediaType, nil - } +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.MarkupNative: + return openrtb_ext.BidTypeNative, nil + default: + return "", fmt.Errorf("Unable to fetch mediaType in impID: %s, mType: %d", bid.ImpID, bid.MType) } - return mediaType, nil } diff --git a/adapters/adview/adviewtest/exemplary/banner-app-format.json b/adapters/adview/adviewtest/exemplary/banner-app-format.json index 0ab4951511e..f35f9db72c6 100644 --- a/adapters/adview/adviewtest/exemplary/banner-app-format.json +++ b/adapters/adview/adviewtest/exemplary/banner-app-format.json @@ -115,7 +115,11 @@ ], "crid": "20", "w": 320, - "h": 50 + "h": 50, + "mtype": 1, + "ext": { + "formattype": 0 + } } ], "type": "banner", @@ -148,7 +152,11 @@ ], "crid": "20", "w": 320, - "h": 50 + "h": 50, + "mtype": 1, + "ext": { + "formattype": 0 + } }, "type": "banner" } diff --git a/adapters/adview/adviewtest/exemplary/banner-app-resp-no-formattype.json b/adapters/adview/adviewtest/exemplary/banner-app-resp-no-formattype.json new file mode 100644 index 00000000000..e3b92913dc6 --- /dev/null +++ b/adapters/adview/adviewtest/exemplary/banner-app-resp-no-formattype.json @@ -0,0 +1,150 @@ +{ + "mockBidRequest": { + "id": "some-request-id", + "device": { + "ua": "test-user-agent", + "ip": "123.123.123.123", + "ifa":"00000000-0000-0000-0000-000000000000", + "language": "en", + "dnt": 0 + }, + "tmax": 1000, + "user": { + "buyeruid": "awesome-user" + }, + "app": { + "publisher": { + "id": "123456789" + }, + "cat": [ + "IAB22-1" + ], + "bundle": "com.app.awesome", + "name": "Awesome App", + "domain": "awesomeapp.com", + "id": "123456789" + }, + "imp": [ + { + "id": "some-impression-id", + "banner": { + "w": 320, + "h": 50 + }, + "ext": { + "bidder": { + "placementId": "posid00001", + "accountId": "accountid01" + } + } + } + ] + }, + "httpCalls": [ + { + "expectedRequest": { + "uri": "https://bid.adview.com/agent/thirdAdxService/accountid01", + "body": { + "id": "some-request-id", + "cur": ["USD"], + "device": { + "ua": "test-user-agent", + "ip": "123.123.123.123", + "ifa":"00000000-0000-0000-0000-000000000000", + "language": "en", + "dnt": 0 + }, + "imp": [ + { + "id": "some-impression-id", + "banner": { + "w": 320, + "h": 50 + }, + "tagid": "posid00001", + "ext": { + "bidder": { + "placementId": "posid00001", + "accountId": "accountid01" + } + } + } + ], + "app": { + "id": "123456789", + "name": "Awesome App", + "bundle": "com.app.awesome", + "domain": "awesomeapp.com", + "cat": [ + "IAB22-1" + ], + "publisher": { + "id": "123456789" + } + }, + "user": { + "buyeruid": "awesome-user" + }, + "tmax": 1000 + } + }, + "mockResponse": { + "status": 200, + "body": { + "id": "awesome-resp-id", + "seatbid": [ + { + "bid": [ + { + "id": "a3ae1b4e2fc24a4fb45540082e98e161", + "impid": "some-impression-id", + "price": 3.5, + "adm": "awesome-markup", + "adomain": [ + "awesome.com" + ], + "crid": "20", + "w": 320, + "h": 50, + "mtype": 1 + } + ], + "type": "banner", + "seat": "adview" + } + ], + "cur": "USD", + "ext": { + "responsetimemillis": { + "adview": 154 + }, + "tmaxrequest": 1000 + } + } + } + } + ], + "expectedBidResponses": [ + { + "currency": "USD", + "bids": [ + { + "bid": { + "id": "a3ae1b4e2fc24a4fb45540082e98e161", + "impid": "some-impression-id", + "price": 3.5, + "adm": "awesome-markup", + "adomain": [ + "awesome.com" + ], + "crid": "20", + "w": 320, + "h": 50, + "mtype": 1 + }, + "type": "banner" + } + ] + } + ] +} diff --git a/adapters/adview/adviewtest/exemplary/banner-app.json b/adapters/adview/adviewtest/exemplary/banner-app.json index 6aad1e8dc05..2c740504ab3 100644 --- a/adapters/adview/adviewtest/exemplary/banner-app.json +++ b/adapters/adview/adviewtest/exemplary/banner-app.json @@ -105,7 +105,11 @@ ], "crid": "20", "w": 320, - "h": 50 + "h": 50, + "mtype": 1, + "ext": { + "formattype": 0 + } } ], "type": "banner", @@ -138,7 +142,11 @@ ], "crid": "20", "w": 320, - "h": 50 + "h": 50, + "mtype": 1, + "ext": { + "formattype": 0 + } }, "type": "banner" } diff --git a/adapters/adview/adviewtest/exemplary/native-app.json b/adapters/adview/adviewtest/exemplary/native-app.json index 804494e5ff5..aea0f58d1b2 100644 --- a/adapters/adview/adviewtest/exemplary/native-app.json +++ b/adapters/adview/adviewtest/exemplary/native-app.json @@ -103,7 +103,11 @@ "adomain": [ "awesome.com" ], - "crid": "20" + "crid": "20", + "mtype": 4, + "ext": { + "formattype": 2 + } } ], "type": "native", @@ -132,9 +136,13 @@ "price": 3.5, "adm": "awesome-markup", "crid": "20", + "mtype": 4, "adomain": [ "awesome.com" - ] + ], + "ext": { + "formattype": 2 + } }, "type": "native" } diff --git a/adapters/adview/adviewtest/exemplary/video-app.json b/adapters/adview/adviewtest/exemplary/video-app.json index 57c9b85598b..8697fc0fdef 100644 --- a/adapters/adview/adviewtest/exemplary/video-app.json +++ b/adapters/adview/adviewtest/exemplary/video-app.json @@ -115,7 +115,11 @@ ], "crid": "20", "w": 1280, - "h": 720 + "h": 720, + "mtype": 2, + "ext": { + "formattype": 1 + } } ], "seat": "adview" @@ -147,7 +151,11 @@ "awesome.com" ], "w": 1280, - "h": 720 + "h": 720, + "mtype": 2, + "ext": { + "formattype": 1 + } }, "type": "video" }