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  }