github.com/prebid/prebid-server@v0.275.0/config/events.go (about) 1 package config 2 3 import ( 4 "errors" 5 "fmt" 6 "strings" 7 8 validator "github.com/asaskevich/govalidator" 9 ) 10 11 // VASTEventElement indicates valid VAST event element 12 type VASTEventElement string 13 14 const ( 15 ImpressionVASTElement VASTEventElement = "impression" 16 TrackingVASTElement VASTEventElement = "tracking" 17 ClickTrackingVASTElement VASTEventElement = "clicktracking" 18 CompanionClickThroughVASTElement VASTEventElement = "companionclickthrough" 19 ErrorVASTElement VASTEventElement = "error" 20 NonLinearClickTrackingVASTElement VASTEventElement = "nonlinearclicktracking" 21 ) 22 23 var vastEventElementMap = map[VASTEventElement]struct{}{ 24 ImpressionVASTElement: {}, 25 TrackingVASTElement: {}, 26 ClickTrackingVASTElement: {}, 27 CompanionClickThroughVASTElement: {}, 28 ErrorVASTElement: {}, 29 NonLinearClickTrackingVASTElement: {}, 30 } 31 32 // TrackingEventType indicates quartile events 33 type TrackingEventType string 34 35 const ( 36 Start TrackingEventType = "start" 37 FirstQuartile TrackingEventType = "firstQuartile" 38 MidPoint TrackingEventType = "midPoint" 39 ThirdQuartile TrackingEventType = "thirdQuartile" 40 Complete TrackingEventType = "complete" 41 ) 42 43 var trackingEventTypeMap = map[TrackingEventType]struct{}{ 44 Start: {}, 45 FirstQuartile: {}, 46 MidPoint: {}, 47 ThirdQuartile: {}, 48 Complete: {}, 49 } 50 51 // VASTEvent indicates the configurations required for injecting VAST event trackers within 52 // VAST XML 53 type VASTEvent struct { 54 CreateElement VASTEventElement `mapstructure:"create_element" json:"create_element"` 55 Type TrackingEventType `mapstructure:"type" json:"type"` 56 ExcludeDefaultURL bool `mapstructure:"exclude_default_url" json:"exclude_default_url"` 57 URLs []string `mapstructure:"urls" json:"urls"` 58 } 59 60 // Events indicates the various types of events to be captured typically for injecting tracker URLs 61 // within the VAST XML 62 // Don't enable this feature. It is still under developmment. Please follow https://github.com/prebid/prebid-server/issues/1725 for more updates 63 type Events struct { 64 Enabled *bool `mapstructure:"enabled" json:"enabled"` 65 DefaultURL string `mapstructure:"default_url" json:"default_url"` 66 VASTEvents []VASTEvent `mapstructure:"vast_events" json:"vast_events,omitempty"` 67 } 68 69 // validate verifies the events object and returns error if at least one is invalid. 70 func (e Events) validate(errs []error) []error { 71 if e.IsEnabled() { 72 if !isValidURL(e.DefaultURL) { 73 return append(errs, errors.New("Invalid events.default_url")) 74 } 75 err := validateVASTEvents(e.VASTEvents) 76 if err != nil { 77 return append(errs, err) 78 } 79 } 80 return errs 81 } 82 83 // validateVASTEvents verifies the all VASTEvent objects and returns error if at least one is invalid. 84 func validateVASTEvents(events []VASTEvent) error { 85 if events != nil { 86 for i, event := range events { 87 if err := event.validate(); err != nil { 88 return fmt.Errorf(err.Error(), i, i) 89 } 90 } 91 } 92 return nil 93 } 94 95 // validate validates event object and returns error if at least one is invalid 96 func (e VASTEvent) validate() error { 97 if !e.CreateElement.isValid() { 98 return fmt.Errorf("Invalid events.vast_events[%s].create_element", "%d") 99 } 100 validType := e.Type.isValid() 101 102 if e.isTrackingEvent() && !validType { 103 var ele []string 104 for k := range vastEventElementMap { 105 ele = append(ele, string(k)) 106 } 107 return fmt.Errorf("Missing or Invalid events.vast_events[%s].type. Valid values are %v", "%d", strings.Join(ele, ", ")) 108 } 109 if validType && !e.isTrackingEvent() { 110 return fmt.Errorf("events.vast_events[%s].type is not applicable for create element '%s'", "%d", e.CreateElement) 111 } 112 for i, url := range e.URLs { 113 if !isValidURL(url) { 114 return fmt.Errorf("Invalid events.vast_events[%s].urls[%d]", "%d", i) 115 } 116 } 117 // ensure at least one valid url exists when default URL to be excluded 118 if e.ExcludeDefaultURL && len(e.URLs) == 0 { 119 return fmt.Errorf("Please provide at least one valid URL in events.vast_events[%s].urls or set events.vast_events[%s].exclude_default_url=false", "%d", "%d") 120 } 121 122 return nil // no errors 123 } 124 125 // isValid checks create_element has valid value 126 // if value is value returns true, otherwise false 127 func (element VASTEventElement) isValid() bool { 128 // validate create element 129 if _, ok := vastEventElementMap[element]; ok { 130 return true 131 } 132 return false 133 } 134 135 // isValid checks if valid type is provided (case-sensitive) 136 func (t TrackingEventType) isValid() bool { 137 _, valid := trackingEventTypeMap[t] 138 return valid 139 } 140 141 // isValidURL validates the event URL 142 func isValidURL(eventURL string) bool { 143 return validator.IsURL(eventURL) && validator.IsRequestURL(eventURL) 144 } 145 146 // isTrackingEvent returns true if event object contains event.CreateElement == "tracking" 147 func (e VASTEvent) isTrackingEvent() bool { 148 return e.CreateElement == TrackingVASTElement 149 } 150 151 // IsEnabled function returns the value of events.enabled field 152 func (e Events) IsEnabled() bool { 153 return e.Enabled != nil && *e.Enabled 154 }