github.com/prebid/prebid-server/v2@v2.18.0/adservertargeting/requestlookup.go (about)

     1  package adservertargeting
     2  
     3  import (
     4  	"encoding/json"
     5  	"fmt"
     6  	"net/url"
     7  	"strings"
     8  
     9  	"github.com/buger/jsonparser"
    10  	"github.com/pkg/errors"
    11  	"github.com/prebid/prebid-server/v2/openrtb_ext"
    12  )
    13  
    14  func getAdServerTargeting(reqWrapper *openrtb_ext.RequestWrapper) ([]openrtb_ext.AdServerTarget, error) {
    15  	reqExt, err := reqWrapper.GetRequestExt()
    16  	if err != nil {
    17  		return nil, err
    18  	}
    19  
    20  	reqExtPrebid := reqExt.GetPrebid()
    21  	if reqExtPrebid == nil {
    22  		return nil, nil
    23  	}
    24  
    25  	return reqExtPrebid.AdServerTargeting, nil
    26  }
    27  
    28  func validateAdServerTargeting(adServerTargeting []openrtb_ext.AdServerTarget) ([]openrtb_ext.AdServerTarget, []openrtb_ext.ExtBidderMessage) {
    29  	var validatedAdServerTargeting []openrtb_ext.AdServerTarget
    30  	var warnings []openrtb_ext.ExtBidderMessage
    31  	for i, targetingObj := range adServerTargeting {
    32  
    33  		isDataCorrect := true
    34  
    35  		if len(targetingObj.Key) == 0 {
    36  			isDataCorrect = false
    37  			warnings = append(warnings, createWarning(fmt.Sprintf("Key is empty for the ad server targeting object at index %d", i)))
    38  		}
    39  
    40  		if len(targetingObj.Value) == 0 {
    41  			isDataCorrect = false
    42  			warnings = append(warnings, createWarning(fmt.Sprintf("Value is empty for the ad server targeting object at index %d", i)))
    43  		}
    44  
    45  		targetingObjSource := DataSource(strings.ToLower(targetingObj.Source))
    46  		if targetingObjSource != SourceStatic &&
    47  			targetingObjSource != SourceBidRequest &&
    48  			targetingObjSource != SourceBidResponse {
    49  			isDataCorrect = false
    50  			warnings = append(warnings, createWarning(fmt.Sprintf("Incorrect source for the ad server targeting object at index %d", i)))
    51  		}
    52  
    53  		if isDataCorrect {
    54  			validatedAdServerTargeting = append(validatedAdServerTargeting, targetingObj)
    55  		}
    56  
    57  	}
    58  	return validatedAdServerTargeting, warnings
    59  }
    60  
    61  func getValueFromBidRequest(dataHolder *requestCache, path string, queryParams url.Values) (RequestTargetingData, error) {
    62  	//use the path specified in 'value' to look for data in the ortb bidrequest.
    63  	res := RequestTargetingData{}
    64  
    65  	//check if key points to query param from ext.prebid.amp.data
    66  	ampDataValue, err := getValueFromQueryParam(path, queryParams)
    67  	if ampDataValue != nil || err != nil {
    68  		res.SingleVal = ampDataValue
    69  		return res, err
    70  	}
    71  
    72  	// check if key points to imp data
    73  	impData, err := getValueFromImp(path, dataHolder)
    74  	if len(impData) > 0 || err != nil {
    75  		res.TargetingValueByImpId = impData
    76  		return res, err
    77  	}
    78  
    79  	// get data by key from request
    80  	requestValue, err := getDataFromRequestJson(path, dataHolder)
    81  	if requestValue != nil || err != nil {
    82  		res.SingleVal = requestValue
    83  		return res, err
    84  	}
    85  
    86  	return res, nil
    87  }
    88  
    89  func getValueFromQueryParam(path string, queryParams url.Values) (json.RawMessage, error) {
    90  	ampDataSplit, hasPrefix := verifyPrefixAndTrim(path, "ext.prebid.amp.data.")
    91  	if hasPrefix {
    92  		val := queryParams.Get(ampDataSplit)
    93  		if val != "" {
    94  			return json.RawMessage(val), nil
    95  		} else {
    96  			return nil, errors.Errorf("value not found for path: %s", path)
    97  		}
    98  	}
    99  	return nil, nil
   100  }
   101  
   102  func getValueFromImp(path string, dataHolder *requestCache) (map[string][]byte, error) {
   103  	impsDatas := make(map[string][]byte, 0)
   104  	impSplit, hasPrefix := verifyPrefixAndTrim(path, "imp.")
   105  	if hasPrefix {
   106  		//If imp is specified in the path, the assumption is that the specific imp[] desired corresponds
   107  		//to the seatbid[].bid[] we're working on. i.e. imp[].id=seatbid[].bid[].impid
   108  		// key points to data in imp
   109  		keySplit := strings.Split(impSplit, pathDelimiter)
   110  		impsData, err := dataHolder.GetImpsData()
   111  		if err != nil {
   112  			return nil, err
   113  		}
   114  		for _, impData := range impsData {
   115  			id, _, _, err := jsonparser.Get(impData, "id")
   116  			if err != nil {
   117  				return nil, err
   118  			}
   119  			value, err := typedLookup(impData, path, keySplit...)
   120  			if err != nil {
   121  				return nil, err
   122  			}
   123  			impsDatas[string(id)] = value
   124  		}
   125  	}
   126  	return impsDatas, nil
   127  }
   128  
   129  func getDataFromRequestJson(path string, dataHolder *requestCache) (json.RawMessage, error) {
   130  	keySplit := strings.Split(path, pathDelimiter)
   131  	reqJson := dataHolder.GetReqJson()
   132  	value, err := typedLookup(reqJson, path, keySplit...)
   133  
   134  	if err != nil {
   135  		return nil, err
   136  	}
   137  	return value, nil
   138  }