Skip to content

Commit 04ab113

Browse files
cornelklafriks
authored andcommitted
Fix Slack webhook payload title generation to work with Mattermost (#9378)
* Fix Slack webhook payload title generation to work with Mattermost by using a markdown link instead of html * Fix Slack webhook attachment title and title link handling
1 parent 669791b commit 04ab113

File tree

1 file changed

+86
-73
lines changed

1 file changed

+86
-73
lines changed

modules/webhook/slack.go

+86-73
Original file line numberDiff line numberDiff line change
@@ -47,10 +47,11 @@ type SlackPayload struct {
4747

4848
// SlackAttachment contains the slack message
4949
type SlackAttachment struct {
50-
Fallback string `json:"fallback"`
51-
Color string `json:"color"`
52-
Title string `json:"title"`
53-
Text string `json:"text"`
50+
Fallback string `json:"fallback"`
51+
Color string `json:"color"`
52+
Title string `json:"title"`
53+
TitleLink string `json:"title_link"`
54+
Text string `json:"text"`
5455
}
5556

5657
// SetSecret sets the slack secret
@@ -144,72 +145,78 @@ func getSlackForkPayload(p *api.ForkPayload, slack *SlackMeta) (*SlackPayload, e
144145

145146
func getSlackIssuesPayload(p *api.IssuePayload, slack *SlackMeta) (*SlackPayload, error) {
146147
senderLink := SlackLinkFormatter(setting.AppURL+p.Sender.UserName, p.Sender.UserName)
147-
titleLink := SlackLinkFormatter(fmt.Sprintf("%s/pulls/%d", p.Repository.HTMLURL, p.Index),
148-
fmt.Sprintf("#%d %s", p.Index, p.Issue.Title))
148+
title := SlackTextFormatter(fmt.Sprintf("#%d %s", p.Index, p.Issue.Title))
149+
titleLink := fmt.Sprintf("%s/issues/%d", p.Repository.HTMLURL, p.Index)
149150
repoLink := SlackLinkFormatter(p.Repository.HTMLURL, p.Repository.FullName)
150-
var text, title, attachmentText string
151+
var text, attachmentText string
152+
151153
switch p.Action {
152154
case api.HookIssueOpened:
153-
text = fmt.Sprintf("[%s] Issue submitted by %s", repoLink, senderLink)
154-
title = titleLink
155+
text = fmt.Sprintf("[%s] Issue opened by %s", repoLink, senderLink)
155156
attachmentText = SlackTextFormatter(p.Issue.Body)
156157
case api.HookIssueClosed:
157-
text = fmt.Sprintf("[%s] Issue closed: %s by %s", repoLink, titleLink, senderLink)
158+
text = fmt.Sprintf("[%s] Issue closed: [%s](%s) by %s", repoLink, title, titleLink, senderLink)
158159
case api.HookIssueReOpened:
159-
text = fmt.Sprintf("[%s] Issue re-opened: %s by %s", repoLink, titleLink, senderLink)
160+
text = fmt.Sprintf("[%s] Issue re-opened: [%s](%s) by %s", repoLink, title, titleLink, senderLink)
160161
case api.HookIssueEdited:
161-
text = fmt.Sprintf("[%s] Issue edited: %s by %s", repoLink, titleLink, senderLink)
162+
text = fmt.Sprintf("[%s] Issue edited: [%s](%s) by %s", repoLink, title, titleLink, senderLink)
162163
attachmentText = SlackTextFormatter(p.Issue.Body)
163164
case api.HookIssueAssigned:
164-
text = fmt.Sprintf("[%s] Issue assigned to %s: %s by %s", repoLink,
165+
text = fmt.Sprintf("[%s] Issue assigned to %s: [%s](%s) by %s", repoLink,
165166
SlackLinkFormatter(setting.AppURL+p.Issue.Assignee.UserName, p.Issue.Assignee.UserName),
166-
titleLink, senderLink)
167+
title, titleLink, senderLink)
167168
case api.HookIssueUnassigned:
168-
text = fmt.Sprintf("[%s] Issue unassigned: %s by %s", repoLink, titleLink, senderLink)
169+
text = fmt.Sprintf("[%s] Issue unassigned: [%s](%s) by %s", repoLink, title, titleLink, senderLink)
169170
case api.HookIssueLabelUpdated:
170-
text = fmt.Sprintf("[%s] Issue labels updated: %s by %s", repoLink, titleLink, senderLink)
171+
text = fmt.Sprintf("[%s] Issue labels updated: [%s](%s) by %s", repoLink, title, titleLink, senderLink)
171172
case api.HookIssueLabelCleared:
172-
text = fmt.Sprintf("[%s] Issue labels cleared: %s by %s", repoLink, titleLink, senderLink)
173+
text = fmt.Sprintf("[%s] Issue labels cleared: [%s](%s) by %s", repoLink, title, titleLink, senderLink)
173174
case api.HookIssueSynchronized:
174-
text = fmt.Sprintf("[%s] Issue synchronized: %s by %s", repoLink, titleLink, senderLink)
175+
text = fmt.Sprintf("[%s] Issue synchronized: [%s](%s) by %s", repoLink, title, titleLink, senderLink)
175176
case api.HookIssueMilestoned:
176-
text = fmt.Sprintf("[%s] Issue milestoned: #%s %s", repoLink, titleLink, senderLink)
177+
mileStoneLink := fmt.Sprintf("%s/milestone/%d", p.Repository.HTMLURL, p.Issue.Milestone.ID)
178+
text = fmt.Sprintf("[%s] Issue milestoned to [%s](%s): [%s](%s) by %s", repoLink,
179+
p.Issue.Milestone.Title, mileStoneLink, title, titleLink, senderLink)
177180
case api.HookIssueDemilestoned:
178-
text = fmt.Sprintf("[%s] Issue milestone cleared: #%s %s", repoLink, titleLink, senderLink)
181+
text = fmt.Sprintf("[%s] Issue milestone cleared: [%s](%s) by %s", repoLink, title, titleLink, senderLink)
179182
}
180183

181-
return &SlackPayload{
184+
pl := &SlackPayload{
182185
Channel: slack.Channel,
183186
Text: text,
184187
Username: slack.Username,
185188
IconURL: slack.IconURL,
186-
Attachments: []SlackAttachment{{
187-
Color: slack.Color,
188-
Title: title,
189-
Text: attachmentText,
190-
}},
191-
}, nil
189+
}
190+
if attachmentText != "" {
191+
pl.Attachments = []SlackAttachment{{
192+
Color: slack.Color,
193+
Title: title,
194+
TitleLink: titleLink,
195+
Text: attachmentText,
196+
}}
197+
}
198+
199+
return pl, nil
192200
}
193201

194202
func getSlackIssueCommentPayload(p *api.IssueCommentPayload, slack *SlackMeta) (*SlackPayload, error) {
195203
senderLink := SlackLinkFormatter(setting.AppURL+p.Sender.UserName, p.Sender.UserName)
196-
titleLink := SlackLinkFormatter(fmt.Sprintf("%s/issues/%d#%s", p.Repository.HTMLURL, p.Issue.Index, models.CommentHashTag(p.Comment.ID)),
197-
fmt.Sprintf("#%d %s", p.Issue.Index, p.Issue.Title))
204+
title := SlackTextFormatter(fmt.Sprintf("#%d %s", p.Issue.Index, p.Issue.Title))
198205
repoLink := SlackLinkFormatter(p.Repository.HTMLURL, p.Repository.FullName)
199-
var text, title, attachmentText string
206+
var text, titleLink, attachmentText string
207+
200208
switch p.Action {
201209
case api.HookIssueCommentCreated:
202210
text = fmt.Sprintf("[%s] New comment created by %s", repoLink, senderLink)
203-
title = titleLink
211+
titleLink = fmt.Sprintf("%s/issues/%d#%s", p.Repository.HTMLURL, p.Issue.Index, models.CommentHashTag(p.Comment.ID))
204212
attachmentText = SlackTextFormatter(p.Comment.Body)
205213
case api.HookIssueCommentEdited:
206214
text = fmt.Sprintf("[%s] Comment edited by %s", repoLink, senderLink)
207-
title = titleLink
215+
titleLink = fmt.Sprintf("%s/issues/%d#%s", p.Repository.HTMLURL, p.Issue.Index, models.CommentHashTag(p.Comment.ID))
208216
attachmentText = SlackTextFormatter(p.Comment.Body)
209217
case api.HookIssueCommentDeleted:
210218
text = fmt.Sprintf("[%s] Comment deleted by %s", repoLink, senderLink)
211-
title = SlackLinkFormatter(fmt.Sprintf("%s/issues/%d", p.Repository.HTMLURL, p.Issue.Index),
212-
fmt.Sprintf("#%d %s", p.Issue.Index, p.Issue.Title))
219+
titleLink = fmt.Sprintf("%s/issues/%d", p.Repository.HTMLURL, p.Issue.Index)
213220
attachmentText = SlackTextFormatter(p.Comment.Body)
214221
}
215222

@@ -219,9 +226,10 @@ func getSlackIssueCommentPayload(p *api.IssueCommentPayload, slack *SlackMeta) (
219226
Username: slack.Username,
220227
IconURL: slack.IconURL,
221228
Attachments: []SlackAttachment{{
222-
Color: slack.Color,
223-
Title: title,
224-
Text: attachmentText,
229+
Color: slack.Color,
230+
Title: title,
231+
TitleLink: titleLink,
232+
Text: attachmentText,
225233
}},
226234
}, nil
227235
}
@@ -294,94 +302,98 @@ func getSlackPushPayload(p *api.PushPayload, slack *SlackMeta) (*SlackPayload, e
294302

295303
func getSlackPullRequestPayload(p *api.PullRequestPayload, slack *SlackMeta) (*SlackPayload, error) {
296304
senderLink := SlackLinkFormatter(setting.AppURL+p.Sender.UserName, p.Sender.UserName)
297-
titleLink := SlackLinkFormatter(fmt.Sprintf("%s/pulls/%d", p.Repository.HTMLURL, p.Index),
298-
fmt.Sprintf("#%d %s", p.Index, p.PullRequest.Title))
305+
title := fmt.Sprintf("#%d %s", p.Index, p.PullRequest.Title)
306+
titleLink := fmt.Sprintf("%s/pulls/%d", p.Repository.HTMLURL, p.Index)
299307
repoLink := SlackLinkFormatter(p.Repository.HTMLURL, p.Repository.FullName)
300-
var text, title, attachmentText string
308+
var text, attachmentText string
309+
301310
switch p.Action {
302311
case api.HookIssueOpened:
303-
text = fmt.Sprintf("[%s] Pull request submitted by %s", repoLink, senderLink)
304-
title = titleLink
312+
text = fmt.Sprintf("[%s] Pull request opened by %s", repoLink, senderLink)
305313
attachmentText = SlackTextFormatter(p.PullRequest.Body)
306314
case api.HookIssueClosed:
307315
if p.PullRequest.HasMerged {
308-
text = fmt.Sprintf("[%s] Pull request merged: %s by %s", repoLink, titleLink, senderLink)
316+
text = fmt.Sprintf("[%s] Pull request merged: [%s](%s) by %s", repoLink, title, titleLink, senderLink)
309317
} else {
310-
text = fmt.Sprintf("[%s] Pull request closed: %s by %s", repoLink, titleLink, senderLink)
318+
text = fmt.Sprintf("[%s] Pull request closed: [%s](%s) by %s", repoLink, title, titleLink, senderLink)
311319
}
312320
case api.HookIssueReOpened:
313-
text = fmt.Sprintf("[%s] Pull request re-opened: %s by %s", repoLink, titleLink, senderLink)
321+
text = fmt.Sprintf("[%s] Pull request re-opened: [%s](%s) by %s", repoLink, title, titleLink, senderLink)
314322
case api.HookIssueEdited:
315-
text = fmt.Sprintf("[%s] Pull request edited: %s by %s", repoLink, titleLink, senderLink)
323+
text = fmt.Sprintf("[%s] Pull request edited: [%s](%s) by %s", repoLink, title, titleLink, senderLink)
316324
attachmentText = SlackTextFormatter(p.PullRequest.Body)
317325
case api.HookIssueAssigned:
318326
list := make([]string, len(p.PullRequest.Assignees))
319327
for i, user := range p.PullRequest.Assignees {
320328
list[i] = SlackLinkFormatter(setting.AppURL+user.UserName, user.UserName)
321329
}
322-
text = fmt.Sprintf("[%s] Pull request assigned to %s: %s by %s", repoLink,
330+
text = fmt.Sprintf("[%s] Pull request assigned to %s: [%s](%s) by %s", repoLink,
323331
strings.Join(list, ", "),
324-
titleLink, senderLink)
332+
title, titleLink, senderLink)
325333
case api.HookIssueUnassigned:
326-
text = fmt.Sprintf("[%s] Pull request unassigned: %s by %s", repoLink, titleLink, senderLink)
334+
text = fmt.Sprintf("[%s] Pull request unassigned: [%s](%s) by %s", repoLink, title, titleLink, senderLink)
327335
case api.HookIssueLabelUpdated:
328-
text = fmt.Sprintf("[%s] Pull request labels updated: %s by %s", repoLink, titleLink, senderLink)
336+
text = fmt.Sprintf("[%s] Pull request labels updated: [%s](%s) by %s", repoLink, title, titleLink, senderLink)
329337
case api.HookIssueLabelCleared:
330-
text = fmt.Sprintf("[%s] Pull request labels cleared: %s by %s", repoLink, titleLink, senderLink)
338+
text = fmt.Sprintf("[%s] Pull request labels cleared: [%s](%s) by %s", repoLink, title, titleLink, senderLink)
331339
case api.HookIssueSynchronized:
332-
text = fmt.Sprintf("[%s] Pull request synchronized: %s by %s", repoLink, titleLink, senderLink)
340+
text = fmt.Sprintf("[%s] Pull request synchronized: [%s](%s) by %s", repoLink, title, titleLink, senderLink)
333341
case api.HookIssueMilestoned:
334-
text = fmt.Sprintf("[%s] Pull request milestoned: #%s %s", repoLink, titleLink, senderLink)
342+
mileStoneLink := fmt.Sprintf("%s/milestone/%d", p.Repository.HTMLURL, p.PullRequest.Milestone.ID)
343+
text = fmt.Sprintf("[%s] Pull request milestoned to [%s](%s): [%s](%s) %s", repoLink,
344+
p.PullRequest.Milestone.Title, mileStoneLink, title, titleLink, senderLink)
335345
case api.HookIssueDemilestoned:
336-
text = fmt.Sprintf("[%s] Pull request milestone cleared: #%s %s", repoLink, titleLink, senderLink)
346+
text = fmt.Sprintf("[%s] Pull request milestone cleared: [%s](%s) %s", repoLink, title, titleLink, senderLink)
337347
}
338348

339-
return &SlackPayload{
349+
pl := &SlackPayload{
340350
Channel: slack.Channel,
341351
Text: text,
342352
Username: slack.Username,
343353
IconURL: slack.IconURL,
344-
Attachments: []SlackAttachment{{
345-
Color: slack.Color,
346-
Title: title,
347-
Text: attachmentText,
348-
}},
349-
}, nil
354+
}
355+
if attachmentText != "" {
356+
pl.Attachments = []SlackAttachment{{
357+
Color: slack.Color,
358+
Title: title,
359+
TitleLink: titleLink,
360+
Text: attachmentText,
361+
}}
362+
}
363+
364+
return pl, nil
350365
}
351366

352367
func getSlackPullRequestApprovalPayload(p *api.PullRequestPayload, slack *SlackMeta, event models.HookEventType) (*SlackPayload, error) {
353368
senderLink := SlackLinkFormatter(setting.AppURL+p.Sender.UserName, p.Sender.UserName)
354-
titleLink := SlackLinkFormatter(fmt.Sprintf("%s/pulls/%d", p.Repository.HTMLURL, p.Index),
355-
fmt.Sprintf("#%d %s", p.Index, p.PullRequest.Title))
369+
title := fmt.Sprintf("#%d %s", p.Index, p.PullRequest.Title)
370+
titleLink := fmt.Sprintf("%s/pulls/%d", p.Repository.HTMLURL, p.Index)
356371
repoLink := SlackLinkFormatter(p.Repository.HTMLURL, p.Repository.FullName)
357-
var text, title, attachmentText string
372+
var text string
373+
358374
switch p.Action {
359375
case api.HookIssueSynchronized:
360376
action, err := parseHookPullRequestEventType(event)
361377
if err != nil {
362378
return nil, err
363379
}
364380

365-
text = fmt.Sprintf("[%s] Pull request review %s : %s by %s", repoLink, action, titleLink, senderLink)
381+
text = fmt.Sprintf("[%s] Pull request review %s: [%s](%s) by %s", repoLink, action, title, titleLink, senderLink)
366382
}
367383

368384
return &SlackPayload{
369385
Channel: slack.Channel,
370386
Text: text,
371387
Username: slack.Username,
372388
IconURL: slack.IconURL,
373-
Attachments: []SlackAttachment{{
374-
Color: slack.Color,
375-
Title: title,
376-
Text: attachmentText,
377-
}},
378389
}, nil
379390
}
380391

381392
func getSlackRepositoryPayload(p *api.RepositoryPayload, slack *SlackMeta) (*SlackPayload, error) {
382393
senderLink := SlackLinkFormatter(setting.AppURL+p.Sender.UserName, p.Sender.UserName)
383394
repoLink := SlackLinkFormatter(p.Repository.HTMLURL, p.Repository.FullName)
384395
var text, title, attachmentText string
396+
385397
switch p.Action {
386398
case api.HookRepoCreated:
387399
text = fmt.Sprintf("[%s] Repository created by %s", repoLink, senderLink)
@@ -396,9 +408,10 @@ func getSlackRepositoryPayload(p *api.RepositoryPayload, slack *SlackMeta) (*Sla
396408
Username: slack.Username,
397409
IconURL: slack.IconURL,
398410
Attachments: []SlackAttachment{{
399-
Color: slack.Color,
400-
Title: title,
401-
Text: attachmentText,
411+
Color: slack.Color,
412+
Title: title,
413+
TitleLink: title,
414+
Text: attachmentText,
402415
}},
403416
}, nil
404417
}

0 commit comments

Comments
 (0)