github.com/prebid/prebid-server/v2@v2.18.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/v20/openrtb2" 11 "github.com/prebid/prebid-server/v2/adapters" 12 "github.com/prebid/prebid-server/v2/config" 13 "github.com/prebid/prebid-server/v2/errortypes" 14 "github.com/prebid/prebid-server/v2/macros" 15 "github.com/prebid/prebid-server/v2/openrtb_ext" 16 ) 17 18 type adapter 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 := &adapter{ 30 EndpointTemplate: template, 31 } 32 return bidder, nil 33 } 34 35 func (a *adapter) MakeRequests(request *openrtb2.BidRequest, reqInfo *adapters.ExtraRequestInfo) ([]*adapters.RequestData, []error) { 36 var adapterRequests []*adapters.RequestData 37 38 adapterRequest, errs := a.makeRequest(request) 39 if errs == nil { 40 adapterRequests = append(adapterRequests, adapterRequest) 41 } 42 43 return adapterRequests, errs 44 } 45 46 func (a *adapter) 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 := a.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 ImpIDs: openrtb_ext.GetImpIDs(request.Imp), 74 }, errs 75 } 76 77 func transform(request *openrtb2.BidRequest) { 78 for i, imp := range request.Imp { 79 if imp.Native != nil { 80 var nativeRequest map[string]interface{} 81 nativeCopyRequest := make(map[string]interface{}) 82 err := json.Unmarshal([]byte(request.Imp[i].Native.Request), &nativeRequest) 83 //just ignore the bad native request 84 if err == nil { 85 _, exists := nativeRequest["native"] 86 if exists { 87 continue 88 } 89 90 nativeCopyRequest["native"] = nativeRequest 91 nativeReqByte, err := json.Marshal(nativeCopyRequest) 92 //just ignore the bad native request 93 if err != nil { 94 continue 95 } 96 97 nativeCopy := *request.Imp[i].Native 98 nativeCopy.Request = string(nativeReqByte) 99 request.Imp[i].Native = &nativeCopy 100 } 101 } 102 } 103 } 104 105 func getYeahmobiExt(request *openrtb2.BidRequest) (*openrtb_ext.ExtImpYeahmobi, []error) { 106 var extImpYeahmobi openrtb_ext.ExtImpYeahmobi 107 var errs []error 108 109 for _, imp := range request.Imp { 110 var extBidder adapters.ExtImpBidder 111 err := json.Unmarshal(imp.Ext, &extBidder) 112 if err != nil { 113 errs = append(errs, err) 114 continue 115 } 116 err = json.Unmarshal(extBidder.Bidder, &extImpYeahmobi) 117 if err != nil { 118 errs = append(errs, err) 119 continue 120 } 121 break 122 } 123 124 return &extImpYeahmobi, errs 125 126 } 127 128 func (a *adapter) getEndpoint(ext *openrtb_ext.ExtImpYeahmobi) (string, error) { 129 return macros.ResolveMacros(a.EndpointTemplate, macros.EndpointTemplateParams{Host: "gw-" + url.QueryEscape(ext.ZoneId) + "-bid.yeahtargeter.com"}) 130 } 131 132 // MakeBids make the bids for the bid response. 133 func (a *adapter) MakeBids(internalRequest *openrtb2.BidRequest, externalRequest *adapters.RequestData, response *adapters.ResponseData) (*adapters.BidderResponse, []error) { 134 if response.StatusCode == http.StatusNoContent { 135 return nil, nil 136 } 137 138 if response.StatusCode == http.StatusBadRequest { 139 return nil, []error{&errortypes.BadInput{ 140 Message: fmt.Sprintf("Unexpected status code: %d.", response.StatusCode), 141 }} 142 } 143 144 if response.StatusCode != http.StatusOK { 145 return nil, []error{&errortypes.BadServerResponse{ 146 Message: fmt.Sprintf("Unexpected status code: %d.", response.StatusCode), 147 }} 148 } 149 150 var bidResp openrtb2.BidResponse 151 152 if err := json.Unmarshal(response.Body, &bidResp); err != nil { 153 return nil, []error{err} 154 } 155 156 bidResponse := adapters.NewBidderResponseWithBidsCapacity(1) 157 158 for _, sb := range bidResp.SeatBid { 159 for i := range sb.Bid { 160 var mediaType = getBidType(sb.Bid[i].ImpID, internalRequest.Imp) 161 bidResponse.Bids = append(bidResponse.Bids, &adapters.TypedBid{ 162 Bid: &sb.Bid[i], 163 BidType: mediaType, 164 }) 165 } 166 } 167 return bidResponse, nil 168 169 } 170 171 func getBidType(impId string, imps []openrtb2.Imp) openrtb_ext.BidType { 172 bidType := openrtb_ext.BidTypeBanner 173 for _, imp := range imps { 174 if imp.ID == impId { 175 if imp.Banner != nil { 176 break 177 } 178 if imp.Video != nil { 179 bidType = openrtb_ext.BidTypeVideo 180 break 181 } 182 if imp.Native != nil { 183 bidType = openrtb_ext.BidTypeNative 184 break 185 } 186 187 } 188 } 189 return bidType 190 }