github.com/prebid/prebid-server/v2@v2.18.0/adapters/emtv/emtv.go (about) 1 package emtv 2 3 import ( 4 "encoding/json" 5 "errors" 6 "fmt" 7 "net/http" 8 9 "github.com/prebid/openrtb/v20/openrtb2" 10 "github.com/prebid/prebid-server/v2/adapters" 11 "github.com/prebid/prebid-server/v2/config" 12 "github.com/prebid/prebid-server/v2/errortypes" 13 "github.com/prebid/prebid-server/v2/openrtb_ext" 14 ) 15 16 type adapter struct { 17 endpoint string 18 } 19 20 type reqBodyExt struct { 21 EmtvBidderExt reqBodyExtBidder `json:"bidder"` 22 } 23 24 type reqBodyExtBidder struct { 25 Type string `json:"type"` 26 PlacementID string `json:"placementId,omitempty"` 27 EndpointID string `json:"endpointId,omitempty"` 28 } 29 30 func Builder(bidderName openrtb_ext.BidderName, config config.Adapter, server config.Server) (adapters.Bidder, error) { 31 bidder := &adapter{ 32 endpoint: config.Endpoint, 33 } 34 return bidder, nil 35 } 36 37 func (a *adapter) MakeRequests(request *openrtb2.BidRequest, reqInfo *adapters.ExtraRequestInfo) ([]*adapters.RequestData, []error) { 38 var err error 39 var adapterRequests []*adapters.RequestData 40 41 reqCopy := *request 42 for _, imp := range request.Imp { 43 reqCopy.Imp = []openrtb2.Imp{imp} 44 45 var bidderExt adapters.ExtImpBidder 46 var emtvExt openrtb_ext.ImpExtEmtv 47 48 if err = json.Unmarshal(reqCopy.Imp[0].Ext, &bidderExt); err != nil { 49 return nil, []error{err} 50 } 51 if err = json.Unmarshal(bidderExt.Bidder, &emtvExt); err != nil { 52 return nil, []error{err} 53 } 54 55 impExt := reqBodyExt{EmtvBidderExt: reqBodyExtBidder{}} 56 57 if emtvExt.PlacementID != "" { 58 impExt.EmtvBidderExt.PlacementID = emtvExt.PlacementID 59 impExt.EmtvBidderExt.Type = "publisher" 60 } else if emtvExt.EndpointID != "" { 61 impExt.EmtvBidderExt.EndpointID = emtvExt.EndpointID 62 impExt.EmtvBidderExt.Type = "network" 63 } else { 64 continue 65 } 66 67 finalyImpExt, err := json.Marshal(impExt) 68 if err != nil { 69 return nil, []error{err} 70 } 71 72 reqCopy.Imp[0].Ext = finalyImpExt 73 74 adapterReq, err := a.makeRequest(&reqCopy) 75 if err != nil { 76 return nil, []error{err} 77 } 78 79 if adapterReq != nil { 80 adapterRequests = append(adapterRequests, adapterReq) 81 } 82 } 83 84 if len(adapterRequests) == 0 { 85 return nil, []error{errors.New("found no valid impressions")} 86 } 87 88 return adapterRequests, nil 89 } 90 91 func (a *adapter) makeRequest(request *openrtb2.BidRequest) (*adapters.RequestData, error) { 92 reqJSON, err := json.Marshal(request) 93 if err != nil { 94 return nil, err 95 } 96 97 headers := http.Header{} 98 headers.Add("Content-Type", "application/json;charset=utf-8") 99 headers.Add("Accept", "application/json") 100 return &adapters.RequestData{ 101 Method: "POST", 102 Uri: a.endpoint, 103 Body: reqJSON, 104 Headers: headers, 105 ImpIDs: openrtb_ext.GetImpIDs(request.Imp), 106 }, nil 107 } 108 109 func (a *adapter) MakeBids(request *openrtb2.BidRequest, requestData *adapters.RequestData, responseData *adapters.ResponseData) (*adapters.BidderResponse, []error) { 110 if adapters.IsResponseStatusCodeNoContent(responseData) { 111 return nil, nil 112 } 113 114 if err := adapters.CheckResponseStatusCodeForErrors(responseData); err != nil { 115 return nil, []error{err} 116 } 117 118 var response openrtb2.BidResponse 119 if err := json.Unmarshal(responseData.Body, &response); err != nil { 120 return nil, []error{err} 121 } 122 123 bidResponse := adapters.NewBidderResponseWithBidsCapacity(len(request.Imp)) 124 bidResponse.Currency = response.Cur 125 126 impsMappedByID := make(map[string]openrtb2.Imp, len(request.Imp)) 127 for i, imp := range request.Imp { 128 impsMappedByID[request.Imp[i].ID] = imp 129 } 130 131 for _, seatBid := range response.SeatBid { 132 for i := range seatBid.Bid { 133 bidType, err := getMediaTypeForImp(seatBid.Bid[i].ImpID, request.Imp, impsMappedByID) 134 if err != nil { 135 return nil, []error{err} 136 } 137 138 b := &adapters.TypedBid{ 139 Bid: &seatBid.Bid[i], 140 BidType: bidType, 141 } 142 bidResponse.Bids = append(bidResponse.Bids, b) 143 } 144 } 145 return bidResponse, nil 146 } 147 148 func getMediaTypeForImp(impID string, imps []openrtb2.Imp, impMap map[string]openrtb2.Imp) (openrtb_ext.BidType, error) { 149 if index, found := impMap[impID]; found { 150 if index.Banner != nil { 151 return openrtb_ext.BidTypeBanner, nil 152 } 153 if index.Video != nil { 154 return openrtb_ext.BidTypeVideo, nil 155 } 156 if index.Native != nil { 157 return openrtb_ext.BidTypeNative, nil 158 } 159 } 160 161 return "", &errortypes.BadInput{ 162 Message: fmt.Sprintf("Failed to find impression \"%s\"", impID), 163 } 164 }