github.com/prebid/prebid-server/v2@v2.18.0/adapters/zmaticoo/zmaticoo.go (about) 1 package zmaticoo 2 3 import ( 4 "encoding/json" 5 "fmt" 6 "net/http" 7 8 "github.com/prebid/openrtb/v20/openrtb2" 9 "github.com/prebid/prebid-server/v2/adapters" 10 "github.com/prebid/prebid-server/v2/config" 11 "github.com/prebid/prebid-server/v2/errortypes" 12 "github.com/prebid/prebid-server/v2/openrtb_ext" 13 ) 14 15 type adapter struct { 16 endpoint string 17 } 18 19 // Builder builds a new instance of the zmaticoo adapter for the given bidder with the given config. 20 func Builder(bidderName openrtb_ext.BidderName, config config.Adapter, server config.Server) (adapters.Bidder, error) { 21 return &adapter{ 22 endpoint: config.Endpoint, 23 }, nil 24 } 25 26 func (a *adapter) MakeRequests(request *openrtb2.BidRequest, reqInfo *adapters.ExtraRequestInfo) ([]*adapters.RequestData, []error) { 27 adapterRequest, errs := a.makeRequest(request) 28 if errs != nil { 29 return nil, errs 30 } 31 return []*adapters.RequestData{adapterRequest}, nil 32 33 } 34 35 func (a *adapter) makeRequest(request *openrtb2.BidRequest) (*adapters.RequestData, []error) { 36 errs := validateZmaticooExt(request) 37 if errs != nil { 38 return nil, errs 39 } 40 err := transform(request) 41 if err != nil { 42 return nil, append(errs, err) 43 } 44 reqBody, err := json.Marshal(request) 45 if err != nil { 46 return nil, append(errs, err) 47 } 48 headers := http.Header{} 49 headers.Add("Content-Type", "application/json;charset=utf-8") 50 return &adapters.RequestData{ 51 Method: "POST", 52 Uri: a.endpoint, 53 Body: reqBody, 54 Headers: headers, 55 ImpIDs: openrtb_ext.GetImpIDs(request.Imp), 56 }, errs 57 } 58 59 func transform(request *openrtb2.BidRequest) error { 60 for i, imp := range request.Imp { 61 if imp.Native != nil { 62 var nativeRequest map[string]interface{} 63 nativeCopyRequest := make(map[string]interface{}) 64 if err := json.Unmarshal([]byte(request.Imp[i].Native.Request), &nativeRequest); err != nil { 65 return err 66 } 67 _, exists := nativeRequest["native"] 68 if exists { 69 continue 70 } 71 nativeCopyRequest["native"] = nativeRequest 72 nativeReqByte, err := json.Marshal(nativeCopyRequest) 73 if err != nil { 74 return err 75 } 76 nativeCopy := *request.Imp[i].Native 77 nativeCopy.Request = string(nativeReqByte) 78 request.Imp[i].Native = &nativeCopy 79 } 80 } 81 return nil 82 } 83 84 func validateZmaticooExt(request *openrtb2.BidRequest) []error { 85 var extImpZmaticoo openrtb_ext.ExtImpZmaticoo 86 var errs []error 87 for _, imp := range request.Imp { 88 var extBidder adapters.ExtImpBidder 89 err := json.Unmarshal(imp.Ext, &extBidder) 90 if err != nil { 91 errs = append(errs, err) 92 continue 93 } 94 err = json.Unmarshal(extBidder.Bidder, &extImpZmaticoo) 95 if err != nil { 96 errs = append(errs, err) 97 continue 98 } 99 if extImpZmaticoo.ZoneId == "" || extImpZmaticoo.PubId == "" { 100 errs = append(errs, fmt.Errorf("imp.ext.pubId or imp.ext.zoneId required")) 101 continue 102 } 103 } 104 return errs 105 106 } 107 108 // MakeBids make the bids for the bid response. 109 func (a *adapter) MakeBids(internalRequest *openrtb2.BidRequest, externalRequest *adapters.RequestData, response *adapters.ResponseData) (*adapters.BidderResponse, []error) { 110 if adapters.IsResponseStatusCodeNoContent(response) { 111 return nil, nil 112 } 113 if err := adapters.CheckResponseStatusCodeForErrors(response); err != nil { 114 return nil, []error{&errortypes.BadInput{ 115 Message: fmt.Sprintf("Unexpected status code: %d.", response.StatusCode), 116 }} 117 } 118 var bidResp openrtb2.BidResponse 119 if err := json.Unmarshal(response.Body, &bidResp); err != nil { 120 return nil, []error{err} 121 } 122 var errs []error 123 bidResponse := adapters.NewBidderResponseWithBidsCapacity(len(internalRequest.Imp)) 124 for _, sb := range bidResp.SeatBid { 125 for i := range sb.Bid { 126 mediaType, err := getMediaTypeForBid(sb.Bid[i]) 127 if err != nil { 128 errs = append(errs, err) 129 continue 130 } 131 bidResponse.Bids = append(bidResponse.Bids, &adapters.TypedBid{ 132 Bid: &sb.Bid[i], 133 BidType: mediaType, 134 }) 135 } 136 } 137 return bidResponse, errs 138 } 139 140 func getMediaTypeForBid(bid openrtb2.Bid) (openrtb_ext.BidType, error) { 141 switch bid.MType { 142 case openrtb2.MarkupBanner: 143 return openrtb_ext.BidTypeBanner, nil 144 case openrtb2.MarkupNative: 145 return openrtb_ext.BidTypeNative, nil 146 case openrtb2.MarkupVideo: 147 return openrtb_ext.BidTypeVideo, nil 148 default: 149 return "", fmt.Errorf("unrecognized bid type in response from zmaticoo for bid %s", bid.ImpID) 150 } 151 }