github.com/prebid/prebid-server@v0.275.0/adservertargeting/requestlookup.go (about)

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