diff --git a/adapters/gumgum/gumgum.go b/adapters/gumgum/gumgum.go index 84a008d1891..490979091a4 100644 --- a/adapters/gumgum/gumgum.go +++ b/adapters/gumgum/gumgum.go @@ -8,12 +8,16 @@ import ( "github.com/prebid/prebid-server/errortypes" "github.com/prebid/prebid-server/openrtb_ext" "net/http" + "strconv" + "strings" ) +// GumGumAdapter implements Bidder interface. type GumGumAdapter struct { URI string } +// MakeRequests makes the HTTP requests which should be made to fetch bids. func (g *GumGumAdapter) MakeRequests(request *openrtb.BidRequest, reqInfo *adapters.ExtraRequestInfo) ([]*adapters.RequestData, []error) { var validImps []openrtb.Imp var trackingId string @@ -26,15 +30,21 @@ func (g *GumGumAdapter) MakeRequests(request *openrtb.BidRequest, reqInfo *adapt zone, err := preprocess(&imp) if err != nil { errs = append(errs, err) - } else { - if request.Imp[i].Banner != nil { - bannerCopy := *request.Imp[i].Banner - if bannerCopy.W == nil && bannerCopy.H == nil && len(bannerCopy.Format) > 0 { - format := bannerCopy.Format[0] - bannerCopy.W = &(format.W) - bannerCopy.H = &(format.H) - } - request.Imp[i].Banner = &bannerCopy + } else if request.Imp[i].Banner != nil { + bannerCopy := *request.Imp[i].Banner + if bannerCopy.W == nil && bannerCopy.H == nil && len(bannerCopy.Format) > 0 { + format := bannerCopy.Format[0] + bannerCopy.W = &(format.W) + bannerCopy.H = &(format.H) + } + request.Imp[i].Banner = &bannerCopy + validImps = append(validImps, request.Imp[i]) + trackingId = zone + } else if request.Imp[i].Video != nil { + err := validateVideoParams(request.Imp[i].Video) + if err != nil { + errs = append(errs, err) + } else { validImps = append(validImps, request.Imp[i]) trackingId = zone } @@ -70,6 +80,7 @@ func (g *GumGumAdapter) MakeRequests(request *openrtb.BidRequest, reqInfo *adapt }}, errs } +// MakeBids unpacks the server's response into Bids. func (g *GumGumAdapter) MakeBids(internalRequest *openrtb.BidRequest, externalRequest *adapters.RequestData, response *adapters.ResponseData) (*adapters.BidderResponse, []error) { if response.StatusCode == http.StatusNoContent { return nil, nil @@ -98,12 +109,19 @@ func (g *GumGumAdapter) MakeBids(internalRequest *openrtb.BidRequest, externalRe for _, sb := range bidResp.SeatBid { for i := range sb.Bid { + mediaType := getMediaTypeForImpID(sb.Bid[i].ImpID, internalRequest.Imp) + if mediaType == openrtb_ext.BidTypeVideo { + price := strconv.FormatFloat(sb.Bid[i].Price, 'f', -1, 64) + sb.Bid[i].AdM = strings.Replace(sb.Bid[i].AdM, "${AUCTION_PRICE}", price, -1) + } + bidResponse.Bids = append(bidResponse.Bids, &adapters.TypedBid{ Bid: &sb.Bid[i], - BidType: openrtb_ext.BidTypeBanner, + BidType: mediaType, }) } } + return bidResponse, errs } @@ -128,6 +146,25 @@ func preprocess(imp *openrtb.Imp) (string, error) { return zone, nil } +func getMediaTypeForImpID(impID string, imps []openrtb.Imp) openrtb_ext.BidType { + for _, imp := range imps { + if imp.ID == impID && imp.Banner != nil { + return openrtb_ext.BidTypeBanner + } + } + return openrtb_ext.BidTypeVideo +} + +func validateVideoParams(video *openrtb.Video) (err error) { + if video.W == 0 || video.H == 0 || video.MinDuration == 0 || video.MaxDuration == 0 || video.Placement == 0 || video.Linearity == 0 { + return &errortypes.BadInput{ + Message: "Invalid or missing video field(s)", + } + } + return nil +} + +// NewGumGumBidder configures bidder endpoint. func NewGumGumBidder(endpoint string) *GumGumAdapter { return &GumGumAdapter{ URI: endpoint, diff --git a/adapters/gumgum/gumgumtest/exemplary/video.json b/adapters/gumgum/gumgumtest/exemplary/video.json new file mode 100644 index 00000000000..ea76c733f34 --- /dev/null +++ b/adapters/gumgum/gumgumtest/exemplary/video.json @@ -0,0 +1,106 @@ +{ + "mockBidRequest": { + "id": "test-request-id", + "imp": [ + { + "id": "test-imp-id", + "video": { + "mimes": [ + "video/mp4" + ], + "minduration": 1, + "maxduration": 2, + "protocols": [ + 1, + 2 + ], + "w": 640, + "h": 480, + "startdelay": 1, + "placement": 1, + "linearity": 1 + }, + "ext": { + "bidder": { + "zone": "ggumtest" + } + } + } + ] + }, + "httpCalls": [ + { + "expectedRequest": { + "uri": "https://g2.gumgum.com/providers/prbds2s/bid", + "body": { + "id": "test-request-id", + "imp": [ + { + "id": "test-imp-id", + "video": { + "mimes": [ + "video/mp4" + ], + "minduration": 1, + "maxduration": 2, + "protocols": [ + 1, + 2 + ], + "w": 640, + "h": 480, + "startdelay": 1, + "placement": 1, + "linearity": 1 + }, + "ext": { + "bidder": { + "zone": "ggumtest" + } + } + } + ] + } + }, + "mockResponse": { + "status": 200, + "body": { + "seatbid": [ + { + "bid": [ + { + "id": "15da721e-940a-4db6-8621-a1f93140b21b", + "impid": "video1", + "price": 15, + "adid": "59082", + "adm": "\n \n \n GumGum Video\n \n \n \n \n \n \n \n \n \n 00:00:15\n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n", + "cid": "3579", + "crid": "59082" + } + ] + } + ] + } + } + } + ], + "expectedBidResponses": [ + { + "currency": "USD", + "bids": [ + { + "bid": { + "id": "15da721e-940a-4db6-8621-a1f93140b21b", + "impid": "video1", + "price": 15, + "adid": "59082", + "adm": "\n \n \n GumGum Video\n \n \n \n \n \n \n \n \n \n 00:00:15\n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n", + "cid": "3579", + "crid": "59082" + }, + "type": "video" + } + ] + } + ] +} \ No newline at end of file diff --git a/adapters/gumgum/gumgumtest/params/race/video.json b/adapters/gumgum/gumgumtest/params/race/video.json new file mode 100644 index 00000000000..3ed284384d3 --- /dev/null +++ b/adapters/gumgum/gumgumtest/params/race/video.json @@ -0,0 +1,3 @@ +{ + "zone": "dc9d6be1" +} \ No newline at end of file diff --git a/adapters/gumgum/gumgumtest/supplemental/missing-video-params.json b/adapters/gumgum/gumgumtest/supplemental/missing-video-params.json new file mode 100644 index 00000000000..b2475cd7bb4 --- /dev/null +++ b/adapters/gumgum/gumgumtest/supplemental/missing-video-params.json @@ -0,0 +1,36 @@ +{ + "mockBidRequest": { + "id": "test-request-id", + "imp": [ + { + "id": "test-imp-id", + "video": { + "mimes": [ + "video/mp4" + ], + "protocols": [ + 1, + 2 + ], + "w": 640, + "h": 480, + "startdelay": 1, + "placement": 1, + "linearity": 1 + }, + "ext": { + "bidder": { + "zone": "ggumtest" + } + } + } + ] + }, + "expectedMakeRequestsErrors": [ + { + "value": "Invalid or missing video field(s)", + "comparison": "literal" + } + ] + } + \ No newline at end of file diff --git a/static/bidder-info/gumgum.yaml b/static/bidder-info/gumgum.yaml index 0feca7cdf73..6ba563b4c1c 100644 --- a/static/bidder-info/gumgum.yaml +++ b/static/bidder-info/gumgum.yaml @@ -4,3 +4,4 @@ capabilities: site: mediaTypes: - banner + - video \ No newline at end of file