github.com/mattermosttest/mattermost-server/v5@v5.0.0-20200917143240-9dfa12e121f9/model/slack_attachment.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 "fmt" 8 "regexp" 9 ) 10 11 var linkWithTextRegex = regexp.MustCompile(`<([^<\|]+)\|([^>]+)>`) 12 13 type SlackAttachment struct { 14 Id int64 `json:"id"` 15 Fallback string `json:"fallback"` 16 Color string `json:"color"` 17 Pretext string `json:"pretext"` 18 AuthorName string `json:"author_name"` 19 AuthorLink string `json:"author_link"` 20 AuthorIcon string `json:"author_icon"` 21 Title string `json:"title"` 22 TitleLink string `json:"title_link"` 23 Text string `json:"text"` 24 Fields []*SlackAttachmentField `json:"fields"` 25 ImageURL string `json:"image_url"` 26 ThumbURL string `json:"thumb_url"` 27 Footer string `json:"footer"` 28 FooterIcon string `json:"footer_icon"` 29 Timestamp interface{} `json:"ts"` // This is either a string or an int64 30 Actions []*PostAction `json:"actions,omitempty"` 31 } 32 33 func (s *SlackAttachment) Equals(input *SlackAttachment) bool { 34 // Direct comparison of simple types 35 36 if s.Id != input.Id { 37 return false 38 } 39 40 if s.Fallback != input.Fallback { 41 return false 42 } 43 44 if s.Color != input.Color { 45 return false 46 } 47 48 if s.Pretext != input.Pretext { 49 return false 50 } 51 52 if s.AuthorName != input.AuthorName { 53 return false 54 } 55 56 if s.AuthorLink != input.AuthorLink { 57 return false 58 } 59 60 if s.AuthorIcon != input.AuthorIcon { 61 return false 62 } 63 64 if s.Title != input.Title { 65 return false 66 } 67 68 if s.TitleLink != input.TitleLink { 69 return false 70 } 71 72 if s.Text != input.Text { 73 return false 74 } 75 76 if s.ImageURL != input.ImageURL { 77 return false 78 } 79 80 if s.ThumbURL != input.ThumbURL { 81 return false 82 } 83 84 if s.Footer != input.Footer { 85 return false 86 } 87 88 if s.FooterIcon != input.FooterIcon { 89 return false 90 } 91 92 // Compare length & slice values of fields 93 if len(s.Fields) != len(input.Fields) { 94 return false 95 } 96 97 for j := range s.Fields { 98 if !s.Fields[j].Equals(input.Fields[j]) { 99 return false 100 } 101 } 102 103 // Compare length & slice values of actions 104 if len(s.Actions) != len(input.Actions) { 105 return false 106 } 107 108 for j := range s.Actions { 109 if !s.Actions[j].Equals(input.Actions[j]) { 110 return false 111 } 112 } 113 114 return s.Timestamp == input.Timestamp 115 } 116 117 type SlackAttachmentField struct { 118 Title string `json:"title"` 119 Value interface{} `json:"value"` 120 Short SlackCompatibleBool `json:"short"` 121 } 122 123 func (s *SlackAttachmentField) Equals(input *SlackAttachmentField) bool { 124 if s.Title != input.Title { 125 return false 126 } 127 128 if s.Value != input.Value { 129 return false 130 } 131 132 if s.Short != input.Short { 133 return false 134 } 135 136 return true 137 } 138 139 func StringifySlackFieldValue(a []*SlackAttachment) []*SlackAttachment { 140 var nonNilAttachments []*SlackAttachment 141 for _, attachment := range a { 142 if attachment == nil { 143 continue 144 } 145 nonNilAttachments = append(nonNilAttachments, attachment) 146 147 var nonNilFields []*SlackAttachmentField 148 for _, field := range attachment.Fields { 149 if field == nil { 150 continue 151 } 152 nonNilFields = append(nonNilFields, field) 153 154 if field.Value != nil { 155 // Ensure the value is set to a string if it is set 156 field.Value = fmt.Sprintf("%v", field.Value) 157 } 158 } 159 attachment.Fields = nonNilFields 160 } 161 return nonNilAttachments 162 } 163 164 // This method only parses and processes the attachments, 165 // all else should be set in the post which is passed 166 func ParseSlackAttachment(post *Post, attachments []*SlackAttachment) { 167 if post.Type == "" { 168 post.Type = POST_SLACK_ATTACHMENT 169 } 170 171 postAttachments := []*SlackAttachment{} 172 173 for _, attachment := range attachments { 174 if attachment == nil { 175 continue 176 } 177 178 attachment.Text = ParseSlackLinksToMarkdown(attachment.Text) 179 attachment.Pretext = ParseSlackLinksToMarkdown(attachment.Pretext) 180 181 for _, field := range attachment.Fields { 182 if value, ok := field.Value.(string); ok { 183 field.Value = ParseSlackLinksToMarkdown(value) 184 } 185 } 186 postAttachments = append(postAttachments, attachment) 187 } 188 post.AddProp("attachments", postAttachments) 189 } 190 191 func ParseSlackLinksToMarkdown(text string) string { 192 return linkWithTextRegex.ReplaceAllString(text, "[${2}](${1})") 193 }