github.com/prebid/prebid-server@v0.275.0/adapters/yeahmobi/yeahmobi.go (about) 1 package yeahmobi 2 3 import ( 4 "encoding/json" 5 "fmt" 6 "net/http" 7 "net/url" 8 "text/template" 9 10 "github.com/prebid/openrtb/v19/openrtb2" 11 "github.com/prebid/prebid-server/adapters" 12 "github.com/prebid/prebid-server/config" 13 "github.com/prebid/prebid-server/errortypes" 14 "github.com/prebid/prebid-server/macros" 15 "github.com/prebid/prebid-server/openrtb_ext" 16 ) 17 18 type YeahmobiAdapter struct { 19 EndpointTemplate *template.Template 20 } 21 22 // Builder builds a new instance of the Yeahmobi adapter for the given bidder with the given config. 23 func Builder(bidderName openrtb_ext.BidderName, config config.Adapter, server config.Server) (adapters.Bidder, error) { 24 template, err := template.New("endpointTemplate").Parse(config.Endpoint) 25 if err != nil { 26 return nil, fmt.Errorf("unable to parse endpoint url template: %v", err) 27 } 28 29 bidder := &YeahmobiAdapter{ 30 EndpointTemplate: template, 31 } 32 return bidder, nil 33 } 34 35 func (adapter *YeahmobiAdapter) MakeRequests(request *openrtb2.BidRequest, reqInfo *adapters.ExtraRequestInfo) ([]*adapters.RequestData, []error) { 36 var adapterRequests []*adapters.RequestData 37 38 adapterRequest, errs := adapter.makeRequest(request) 39 if errs == nil { 40 adapterRequests = append(adapterRequests, adapterRequest) 41 } 42 43 return adapterRequests, errs 44 } 45 46 func (adapter *YeahmobiAdapter) makeRequest(request *openrtb2.BidRequest) (*adapters.RequestData, []error) { 47 var errs []error 48 49 yeahmobiExt, errs := getYeahmobiExt(request) 50 51 if yeahmobiExt == nil { 52 return nil, errs 53 } 54 endPoint, err := adapter.getEndpoint(yeahmobiExt) 55 if err != nil { 56 return nil, append(errs, err) 57 } 58 transform(request) 59 reqBody, err := json.Marshal(request) 60 61 if err != nil { 62 return nil, append(errs, err) 63 } 64 65 headers := http.Header{} 66 headers.Add("Content-Type", "application/json;charset=utf-8") 67 68 return &adapters.RequestData{ 69 Method: "POST", 70 Uri: endPoint, 71 Body: reqBody, 72 Headers: headers, 73 }, errs 74 } 75 76 func transform(request *openrtb2.BidRequest) { 77 for i, imp := range request.Imp { 78 if imp.Native != nil { 79 var nativeRequest map[string]interface{} 80 nativeCopyRequest := make(map[string]interface{}) 81 err := json.Unmarshal([]byte(request.Imp[i].Native.Request), &nativeRequest) 82 //just ignore the bad native request 83 if err == nil { 84 _, exists := nativeRequest["native"] 85 if exists { 86 continue 87 } 88 89 nativeCopyRequest["native"] = nativeRequest 90 nativeReqByte, err := json.Marshal(nativeCopyRequest) 91 //just ignore the bad native request 92 if err != nil { 93 continue 94 } 95 96 nativeCopy := *request.Imp[i].Native 97 nativeCopy.Request = string(nativeReqByte) 98 request.Imp[i].Native = &nativeCopy 99 } 100 } 101 } 102 } 103 104 func getYeahmobiExt(request *openrtb2.BidRequest) (*openrtb_ext.ExtImpYeahmobi, []error) { 105 var extImpYeahmobi openrtb_ext.ExtImpYeahmobi 106 var errs []error 107 108 for _, imp := range request.Imp { 109 var extBidder adapters.ExtImpBidder 110 err := json.Unmarshal(imp.Ext, &extBidder) 111 if err != nil { 112 errs = append(errs, err) 113 continue 114 } 115 err = json.Unmarshal(extBidder.Bidder, &extImpYeahmobi) 116 if err != nil { 117 errs = append(errs, err) 118 continue 119 } 120 break 121 } 122 123 return &extImpYeahmobi, errs 124 125 } 126 127 func (adapter *YeahmobiAdapter) getEndpoint(ext *openrtb_ext.ExtImpYeahmobi) (string, error) { 128 return macros.ResolveMacros(adapter.EndpointTemplate, macros.EndpointTemplateParams{Host: "gw-" + url.QueryEscape(ext.ZoneId) + "-bid.yeahtargeter.com"}) 129 } 130 131 // MakeBids make the bids for the bid response. 132 func (a *YeahmobiAdapter) MakeBids(internalRequest *openrtb2.BidRequest, externalRequest *adapters.RequestData, response *adapters.ResponseData) (*adapters.BidderResponse, []error) { 133 if response.StatusCode == http.StatusNoContent { 134 return nil, nil 135 } 136 137 if response.StatusCode == http.StatusBadRequest { 138 return nil, []error{&errortypes.BadInput{ 139 Message: fmt.Sprintf("Unexpected status code: %d.", response.StatusCode), 140 }} 141 } 142 143 if response.StatusCode != http.StatusOK { 144 return nil, []error{&errortypes.BadServerResponse{ 145 Message: fmt.Sprintf("Unexpected status code: %d.", response.StatusCode), 146 }} 147 } 148 149 var bidResp openrtb2.BidResponse 150 151 if err := json.Unmarshal(response.Body, &bidResp); err != nil { 152 return nil, []error{err} 153 } 154 155 bidResponse := adapters.NewBidderResponseWithBidsCapacity(1) 156 157 for _, sb := range bidResp.SeatBid { 158 for i := range sb.Bid { 159 var mediaType = getBidType(sb.Bid[i].ImpID, internalRequest.Imp) 160 bidResponse.Bids = append(bidResponse.Bids, &adapters.TypedBid{ 161 Bid: &sb.Bid[i], 162 BidType: mediaType, 163 }) 164 } 165 } 166 return bidResponse, nil 167 168 } 169 170 func getBidType(impId string, imps []openrtb2.Imp) openrtb_ext.BidType { 171 bidType := openrtb_ext.BidTypeBanner 172 for _, imp := range imps { 173 if imp.ID == impId { 174 if imp.Banner != nil { 175 break 176 } 177 if imp.Video != nil { 178 bidType = openrtb_ext.BidTypeVideo 179 break 180 } 181 if imp.Native != nil { 182 bidType = openrtb_ext.BidTypeNative 183 break 184 } 185 186 } 187 } 188 return bidType 189 }