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 }