github.com/mattermosttest/mattermost-server/v5@v5.0.0-20200917143240-9dfa12e121f9/model/outgoing_webhook.go (about) 1 // Copyright (c) 2015-present Mattermost, Inc. All Rights Reserved. 2 // See LICENSE.txt for license information. 3 4 package model 5 6 import ( 7 "encoding/json" 8 "fmt" 9 "io" 10 "net/http" 11 "net/url" 12 "strconv" 13 "strings" 14 ) 15 16 type OutgoingWebhook struct { 17 Id string `json:"id"` 18 Token string `json:"token"` 19 CreateAt int64 `json:"create_at"` 20 UpdateAt int64 `json:"update_at"` 21 DeleteAt int64 `json:"delete_at"` 22 CreatorId string `json:"creator_id"` 23 ChannelId string `json:"channel_id"` 24 TeamId string `json:"team_id"` 25 TriggerWords StringArray `json:"trigger_words"` 26 TriggerWhen int `json:"trigger_when"` 27 CallbackURLs StringArray `json:"callback_urls"` 28 DisplayName string `json:"display_name"` 29 Description string `json:"description"` 30 ContentType string `json:"content_type"` 31 Username string `json:"username"` 32 IconURL string `json:"icon_url"` 33 } 34 35 type OutgoingWebhookPayload struct { 36 Token string `json:"token"` 37 TeamId string `json:"team_id"` 38 TeamDomain string `json:"team_domain"` 39 ChannelId string `json:"channel_id"` 40 ChannelName string `json:"channel_name"` 41 Timestamp int64 `json:"timestamp"` 42 UserId string `json:"user_id"` 43 UserName string `json:"user_name"` 44 PostId string `json:"post_id"` 45 Text string `json:"text"` 46 TriggerWord string `json:"trigger_word"` 47 FileIds string `json:"file_ids"` 48 } 49 50 type OutgoingWebhookResponse struct { 51 Text *string `json:"text"` 52 Username string `json:"username"` 53 IconURL string `json:"icon_url"` 54 Props StringInterface `json:"props"` 55 Attachments []*SlackAttachment `json:"attachments"` 56 Type string `json:"type"` 57 ResponseType string `json:"response_type"` 58 } 59 60 const OUTGOING_HOOK_RESPONSE_TYPE_COMMENT = "comment" 61 62 func (o *OutgoingWebhookPayload) ToJSON() string { 63 b, _ := json.Marshal(o) 64 return string(b) 65 } 66 67 func (o *OutgoingWebhookPayload) ToFormValues() string { 68 v := url.Values{} 69 v.Set("token", o.Token) 70 v.Set("team_id", o.TeamId) 71 v.Set("team_domain", o.TeamDomain) 72 v.Set("channel_id", o.ChannelId) 73 v.Set("channel_name", o.ChannelName) 74 v.Set("timestamp", strconv.FormatInt(o.Timestamp/1000, 10)) 75 v.Set("user_id", o.UserId) 76 v.Set("user_name", o.UserName) 77 v.Set("post_id", o.PostId) 78 v.Set("text", o.Text) 79 v.Set("trigger_word", o.TriggerWord) 80 v.Set("file_ids", o.FileIds) 81 82 return v.Encode() 83 } 84 85 func (o *OutgoingWebhook) ToJson() string { 86 b, _ := json.Marshal(o) 87 return string(b) 88 } 89 90 func OutgoingWebhookFromJson(data io.Reader) *OutgoingWebhook { 91 var o *OutgoingWebhook 92 json.NewDecoder(data).Decode(&o) 93 return o 94 } 95 96 func OutgoingWebhookListToJson(l []*OutgoingWebhook) string { 97 b, _ := json.Marshal(l) 98 return string(b) 99 } 100 101 func OutgoingWebhookListFromJson(data io.Reader) []*OutgoingWebhook { 102 var o []*OutgoingWebhook 103 json.NewDecoder(data).Decode(&o) 104 return o 105 } 106 107 func (o *OutgoingWebhookResponse) ToJson() string { 108 b, _ := json.Marshal(o) 109 return string(b) 110 } 111 112 func OutgoingWebhookResponseFromJson(data io.Reader) (*OutgoingWebhookResponse, error) { 113 var o *OutgoingWebhookResponse 114 err := json.NewDecoder(data).Decode(&o) 115 if err == io.EOF { 116 return nil, nil 117 } 118 return o, err 119 } 120 121 func (o *OutgoingWebhook) IsValid() *AppError { 122 123 if !IsValidId(o.Id) { 124 return NewAppError("OutgoingWebhook.IsValid", "model.outgoing_hook.is_valid.id.app_error", nil, "", http.StatusBadRequest) 125 } 126 127 if len(o.Token) != 26 { 128 return NewAppError("OutgoingWebhook.IsValid", "model.outgoing_hook.is_valid.token.app_error", nil, "", http.StatusBadRequest) 129 } 130 131 if o.CreateAt == 0 { 132 return NewAppError("OutgoingWebhook.IsValid", "model.outgoing_hook.is_valid.create_at.app_error", nil, "id="+o.Id, http.StatusBadRequest) 133 } 134 135 if o.UpdateAt == 0 { 136 return NewAppError("OutgoingWebhook.IsValid", "model.outgoing_hook.is_valid.update_at.app_error", nil, "id="+o.Id, http.StatusBadRequest) 137 } 138 139 if !IsValidId(o.CreatorId) { 140 return NewAppError("OutgoingWebhook.IsValid", "model.outgoing_hook.is_valid.user_id.app_error", nil, "", http.StatusBadRequest) 141 } 142 143 if len(o.ChannelId) != 0 && !IsValidId(o.ChannelId) { 144 return NewAppError("OutgoingWebhook.IsValid", "model.outgoing_hook.is_valid.channel_id.app_error", nil, "", http.StatusBadRequest) 145 } 146 147 if !IsValidId(o.TeamId) { 148 return NewAppError("OutgoingWebhook.IsValid", "model.outgoing_hook.is_valid.team_id.app_error", nil, "", http.StatusBadRequest) 149 } 150 151 if len(fmt.Sprintf("%s", o.TriggerWords)) > 1024 { 152 return NewAppError("OutgoingWebhook.IsValid", "model.outgoing_hook.is_valid.words.app_error", nil, "", http.StatusBadRequest) 153 } 154 155 if len(o.TriggerWords) != 0 { 156 for _, triggerWord := range o.TriggerWords { 157 if len(triggerWord) == 0 { 158 return NewAppError("OutgoingWebhook.IsValid", "model.outgoing_hook.is_valid.trigger_words.app_error", nil, "", http.StatusBadRequest) 159 } 160 } 161 } 162 163 if len(o.CallbackURLs) == 0 || len(fmt.Sprintf("%s", o.CallbackURLs)) > 1024 { 164 return NewAppError("OutgoingWebhook.IsValid", "model.outgoing_hook.is_valid.callback.app_error", nil, "", http.StatusBadRequest) 165 } 166 167 for _, callback := range o.CallbackURLs { 168 if !IsValidHttpUrl(callback) { 169 return NewAppError("OutgoingWebhook.IsValid", "model.outgoing_hook.is_valid.url.app_error", nil, "", http.StatusBadRequest) 170 } 171 } 172 173 if len(o.DisplayName) > 64 { 174 return NewAppError("OutgoingWebhook.IsValid", "model.outgoing_hook.is_valid.display_name.app_error", nil, "", http.StatusBadRequest) 175 } 176 177 if len(o.Description) > 500 { 178 return NewAppError("OutgoingWebhook.IsValid", "model.outgoing_hook.is_valid.description.app_error", nil, "", http.StatusBadRequest) 179 } 180 181 if len(o.ContentType) > 128 { 182 return NewAppError("OutgoingWebhook.IsValid", "model.outgoing_hook.is_valid.content_type.app_error", nil, "", http.StatusBadRequest) 183 } 184 185 if o.TriggerWhen > 1 { 186 return NewAppError("OutgoingWebhook.IsValid", "model.outgoing_hook.is_valid.content_type.app_error", nil, "", http.StatusBadRequest) 187 } 188 189 if len(o.Username) > 64 { 190 return NewAppError("OutgoingWebhook.IsValid", "model.outgoing_hook.username.app_error", nil, "", http.StatusBadRequest) 191 } 192 193 if len(o.IconURL) > 1024 { 194 return NewAppError("OutgoingWebhook.IsValid", "model.outgoing_hook.icon_url.app_error", nil, "", http.StatusBadRequest) 195 } 196 197 return nil 198 } 199 200 func (o *OutgoingWebhook) PreSave() { 201 if o.Id == "" { 202 o.Id = NewId() 203 } 204 205 if o.Token == "" { 206 o.Token = NewId() 207 } 208 209 o.CreateAt = GetMillis() 210 o.UpdateAt = o.CreateAt 211 } 212 213 func (o *OutgoingWebhook) PreUpdate() { 214 o.UpdateAt = GetMillis() 215 } 216 217 func (o *OutgoingWebhook) TriggerWordExactMatch(word string) bool { 218 if len(word) == 0 { 219 return false 220 } 221 222 for _, trigger := range o.TriggerWords { 223 if trigger == word { 224 return true 225 } 226 } 227 228 return false 229 } 230 231 func (o *OutgoingWebhook) TriggerWordStartsWith(word string) bool { 232 if len(word) == 0 { 233 return false 234 } 235 236 for _, trigger := range o.TriggerWords { 237 if strings.HasPrefix(word, trigger) { 238 return true 239 } 240 } 241 242 return false 243 } 244 245 func (o *OutgoingWebhook) GetTriggerWord(word string, isExactMatch bool) (triggerWord string) { 246 if len(word) == 0 { 247 return 248 } 249 250 if isExactMatch { 251 for _, trigger := range o.TriggerWords { 252 if trigger == word { 253 triggerWord = trigger 254 break 255 } 256 } 257 } else { 258 for _, trigger := range o.TriggerWords { 259 if strings.HasPrefix(word, trigger) { 260 triggerWord = trigger 261 break 262 } 263 } 264 } 265 266 return triggerWord 267 }