github.com/prebid/prebid-server/v2@v2.18.0/openrtb_ext/device.go (about) 1 package openrtb_ext 2 3 import ( 4 "encoding/json" 5 "errors" 6 "strconv" 7 8 "github.com/buger/jsonparser" 9 "github.com/prebid/prebid-server/v2/errortypes" 10 ) 11 12 // PrebidExtKey represents the prebid extension key used in requests 13 const PrebidExtKey = "prebid" 14 15 // PrebidExtBidderKey represents the field name within request.imp.ext.prebid reserved for bidder params. 16 const PrebidExtBidderKey = "bidder" 17 18 // ExtDevice defines the contract for bidrequest.device.ext 19 type ExtDevice struct { 20 // Attribute: 21 // atts 22 // Type: 23 // integer; optional - iOS Only 24 // Description: 25 // iOS app tracking authorization status. 26 // Extension Spec: 27 // https://github.com/InteractiveAdvertisingBureau/openrtb/blob/master/extensions/community_extensions/skadnetwork.md 28 ATTS *IOSAppTrackingStatus `json:"atts"` 29 30 // Attribute: 31 // prebid 32 // Type: 33 // object; optional 34 // Description: 35 // Prebid extensions for the Device object. 36 Prebid ExtDevicePrebid `json:"prebid"` 37 } 38 39 // IOSAppTrackingStatus describes the values for iOS app tracking authorization status. 40 type IOSAppTrackingStatus int 41 42 // Values of the IOSAppTrackingStatus enumeration. 43 const ( 44 IOSAppTrackingStatusNotDetermined IOSAppTrackingStatus = 0 45 IOSAppTrackingStatusRestricted IOSAppTrackingStatus = 1 46 IOSAppTrackingStatusDenied IOSAppTrackingStatus = 2 47 IOSAppTrackingStatusAuthorized IOSAppTrackingStatus = 3 48 ) 49 50 // IsKnownIOSAppTrackingStatus returns true if the value is a known iOS app tracking authorization status. 51 func IsKnownIOSAppTrackingStatus(v int64) bool { 52 switch IOSAppTrackingStatus(v) { 53 case IOSAppTrackingStatusNotDetermined: 54 return true 55 case IOSAppTrackingStatusRestricted: 56 return true 57 case IOSAppTrackingStatusDenied: 58 return true 59 case IOSAppTrackingStatusAuthorized: 60 return true 61 default: 62 return false 63 } 64 } 65 66 // ExtDevicePrebid defines the contract for bidrequest.device.ext.prebid 67 type ExtDevicePrebid struct { 68 Interstitial *ExtDeviceInt `json:"interstitial"` 69 } 70 71 // ExtDeviceInt defines the contract for bidrequest.device.ext.prebid.interstitial 72 type ExtDeviceInt struct { 73 MinWidthPerc int64 `json:"minwidthperc"` 74 MinHeightPerc int64 `json:"minheightperc"` 75 } 76 77 func (edi *ExtDeviceInt) UnmarshalJSON(b []byte) error { 78 if len(b) == 0 { 79 return &errortypes.BadInput{Message: "request.device.ext.prebid.interstitial must have some data in it"} 80 } 81 if value, dataType, _, _ := jsonparser.Get(b, "minwidthperc"); dataType != jsonparser.Number { 82 return &errortypes.BadInput{Message: "request.device.ext.prebid.interstitial.minwidthperc must be a number between 0 and 100"} 83 } else { 84 perc, err := strconv.Atoi(string(value)) 85 if err != nil || perc < 0 || perc > 100 { 86 return &errortypes.BadInput{Message: "request.device.ext.prebid.interstitial.minwidthperc must be a number between 0 and 100"} 87 } 88 edi.MinWidthPerc = int64(perc) 89 } 90 if value, dataType, _, _ := jsonparser.Get(b, "minheightperc"); dataType != jsonparser.Number { 91 return &errortypes.BadInput{Message: "request.device.ext.prebid.interstitial.minheightperc must be a number between 0 and 100"} 92 } else { 93 perc, err := strconv.Atoi(string(value)) 94 if err != nil || perc < 0 || perc > 100 { 95 return &errortypes.BadInput{Message: "request.device.ext.prebid.interstitial.minheightperc must be a number between 0 and 100"} 96 } 97 edi.MinHeightPerc = int64(perc) 98 } 99 return nil 100 } 101 102 // ParseDeviceExtATTS parses the ATTS value from the request.device.ext OpenRTB field. 103 func ParseDeviceExtATTS(deviceExt json.RawMessage) (*IOSAppTrackingStatus, error) { 104 v, err := jsonparser.GetInt(deviceExt, "atts") 105 106 // node not found error 107 if err == jsonparser.KeyPathNotFoundError { 108 return nil, nil 109 } 110 111 // unexpected parse error 112 if err != nil { 113 return nil, err 114 } 115 116 // invalid value error 117 if !IsKnownIOSAppTrackingStatus(v) { 118 return nil, errors.New("invalid status") 119 } 120 121 status := IOSAppTrackingStatus(v) 122 return &status, nil 123 }