Skip to content

Commit 3a14a69

Browse files
cornelklunny
authored andcommitted
Fix Slack webhook payload title generation to work with Mattermost (#9378) (#9404)
1 parent f0f48e0 commit 3a14a69

File tree

1 file changed

+93
-76
lines changed

1 file changed

+93
-76
lines changed

models/webhook_slack.go

+93-76
Original file line numberDiff line numberDiff line change
@@ -36,10 +36,11 @@ type SlackPayload struct {
3636

3737
// SlackAttachment contains the slack message
3838
type SlackAttachment struct {
39-
Fallback string `json:"fallback"`
40-
Color string `json:"color"`
41-
Title string `json:"title"`
42-
Text string `json:"text"`
39+
Fallback string `json:"fallback"`
40+
Color string `json:"color"`
41+
Title string `json:"title"`
42+
TitleLink string `json:"title_link"`
43+
Text string `json:"text"`
4344
}
4445

4546
// SetSecret sets the slack secret
@@ -133,70 +134,78 @@ func getSlackForkPayload(p *api.ForkPayload, slack *SlackMeta) (*SlackPayload, e
133134

134135
func getSlackIssuesPayload(p *api.IssuePayload, slack *SlackMeta) (*SlackPayload, error) {
135136
senderLink := SlackLinkFormatter(setting.AppURL+p.Sender.UserName, p.Sender.UserName)
136-
titleLink := SlackLinkFormatter(fmt.Sprintf("%s/pulls/%d", p.Repository.HTMLURL, p.Index),
137-
fmt.Sprintf("#%d %s", p.Index, p.Issue.Title))
138-
var text, title, attachmentText string
137+
title := SlackTextFormatter(fmt.Sprintf("#%d %s", p.Index, p.Issue.Title))
138+
titleLink := fmt.Sprintf("%s/issues/%d", p.Repository.HTMLURL, p.Index)
139+
repoLink := SlackLinkFormatter(p.Repository.HTMLURL, p.Repository.FullName)
140+
var text, attachmentText string
141+
139142
switch p.Action {
140143
case api.HookIssueOpened:
141-
text = fmt.Sprintf("[%s] Issue submitted by %s", p.Repository.FullName, senderLink)
142-
title = titleLink
144+
text = fmt.Sprintf("[%s] Issue opened by %s", repoLink, senderLink)
143145
attachmentText = SlackTextFormatter(p.Issue.Body)
144146
case api.HookIssueClosed:
145-
text = fmt.Sprintf("[%s] Issue closed: %s by %s", p.Repository.FullName, titleLink, senderLink)
147+
text = fmt.Sprintf("[%s] Issue closed: [%s](%s) by %s", repoLink, title, titleLink, senderLink)
146148
case api.HookIssueReOpened:
147-
text = fmt.Sprintf("[%s] Issue re-opened: %s by %s", p.Repository.FullName, titleLink, senderLink)
149+
text = fmt.Sprintf("[%s] Issue re-opened: [%s](%s) by %s", repoLink, title, titleLink, senderLink)
148150
case api.HookIssueEdited:
149-
text = fmt.Sprintf("[%s] Issue edited: %s by %s", p.Repository.FullName, titleLink, senderLink)
151+
text = fmt.Sprintf("[%s] Issue edited: [%s](%s) by %s", repoLink, title, titleLink, senderLink)
150152
attachmentText = SlackTextFormatter(p.Issue.Body)
151153
case api.HookIssueAssigned:
152-
text = fmt.Sprintf("[%s] Issue assigned to %s: %s by %s", p.Repository.FullName,
154+
text = fmt.Sprintf("[%s] Issue assigned to %s: [%s](%s) by %s", repoLink,
153155
SlackLinkFormatter(setting.AppURL+p.Issue.Assignee.UserName, p.Issue.Assignee.UserName),
154-
titleLink, senderLink)
156+
title, titleLink, senderLink)
155157
case api.HookIssueUnassigned:
156-
text = fmt.Sprintf("[%s] Issue unassigned: %s by %s", p.Repository.FullName, titleLink, senderLink)
158+
text = fmt.Sprintf("[%s] Issue unassigned: [%s](%s) by %s", repoLink, title, titleLink, senderLink)
157159
case api.HookIssueLabelUpdated:
158-
text = fmt.Sprintf("[%s] Issue labels updated: %s by %s", p.Repository.FullName, titleLink, senderLink)
160+
text = fmt.Sprintf("[%s] Issue labels updated: [%s](%s) by %s", repoLink, title, titleLink, senderLink)
159161
case api.HookIssueLabelCleared:
160-
text = fmt.Sprintf("[%s] Issue labels cleared: %s by %s", p.Repository.FullName, titleLink, senderLink)
162+
text = fmt.Sprintf("[%s] Issue labels cleared: [%s](%s) by %s", repoLink, title, titleLink, senderLink)
161163
case api.HookIssueSynchronized:
162-
text = fmt.Sprintf("[%s] Issue synchronized: %s by %s", p.Repository.FullName, titleLink, senderLink)
164+
text = fmt.Sprintf("[%s] Issue synchronized: [%s](%s) by %s", repoLink, title, titleLink, senderLink)
163165
case api.HookIssueMilestoned:
164-
text = fmt.Sprintf("[%s] Issue milestoned: #%s %s", p.Repository.FullName, titleLink, senderLink)
166+
mileStoneLink := fmt.Sprintf("%s/milestone/%d", p.Repository.HTMLURL, p.Issue.Milestone.ID)
167+
text = fmt.Sprintf("[%s] Issue milestoned to [%s](%s): [%s](%s) by %s", repoLink,
168+
p.Issue.Milestone.Title, mileStoneLink, title, titleLink, senderLink)
165169
case api.HookIssueDemilestoned:
166-
text = fmt.Sprintf("[%s] Issue milestone cleared: #%s %s", p.Repository.FullName, titleLink, senderLink)
170+
text = fmt.Sprintf("[%s] Issue milestone cleared: [%s](%s) by %s", repoLink, title, titleLink, senderLink)
167171
}
168172

169-
return &SlackPayload{
173+
pl := &SlackPayload{
170174
Channel: slack.Channel,
171175
Text: text,
172176
Username: slack.Username,
173177
IconURL: slack.IconURL,
174-
Attachments: []SlackAttachment{{
175-
Color: slack.Color,
176-
Title: title,
177-
Text: attachmentText,
178-
}},
179-
}, nil
178+
}
179+
if attachmentText != "" {
180+
pl.Attachments = []SlackAttachment{{
181+
Color: slack.Color,
182+
Title: title,
183+
TitleLink: titleLink,
184+
Text: attachmentText,
185+
}}
186+
}
187+
188+
return pl, nil
180189
}
181190

182191
func getSlackIssueCommentPayload(p *api.IssueCommentPayload, slack *SlackMeta) (*SlackPayload, error) {
183192
senderLink := SlackLinkFormatter(setting.AppURL+p.Sender.UserName, p.Sender.UserName)
184-
titleLink := SlackLinkFormatter(fmt.Sprintf("%s/issues/%d#%s", p.Repository.HTMLURL, p.Issue.Index, CommentHashTag(p.Comment.ID)),
185-
fmt.Sprintf("#%d %s", p.Issue.Index, p.Issue.Title))
186-
var text, title, attachmentText string
193+
title := SlackTextFormatter(fmt.Sprintf("#%d %s", p.Issue.Index, p.Issue.Title))
194+
repoLink := SlackLinkFormatter(p.Repository.HTMLURL, p.Repository.FullName)
195+
var text, titleLink, attachmentText string
196+
187197
switch p.Action {
188198
case api.HookIssueCommentCreated:
189-
text = fmt.Sprintf("[%s] New comment created by %s", p.Repository.FullName, senderLink)
190-
title = titleLink
199+
text = fmt.Sprintf("[%s] New comment created by %s", repoLink, senderLink)
200+
titleLink = fmt.Sprintf("%s/issues/%d#%s", p.Repository.HTMLURL, p.Issue.Index, CommentHashTag(p.Comment.ID))
191201
attachmentText = SlackTextFormatter(p.Comment.Body)
192202
case api.HookIssueCommentEdited:
193-
text = fmt.Sprintf("[%s] Comment edited by %s", p.Repository.FullName, senderLink)
194-
title = titleLink
203+
text = fmt.Sprintf("[%s] Comment edited by %s", repoLink, senderLink)
204+
titleLink = fmt.Sprintf("%s/issues/%d#%s", p.Repository.HTMLURL, p.Issue.Index, CommentHashTag(p.Comment.ID))
195205
attachmentText = SlackTextFormatter(p.Comment.Body)
196206
case api.HookIssueCommentDeleted:
197-
text = fmt.Sprintf("[%s] Comment deleted by %s", p.Repository.FullName, senderLink)
198-
title = SlackLinkFormatter(fmt.Sprintf("%s/issues/%d", p.Repository.HTMLURL, p.Issue.Index),
199-
fmt.Sprintf("#%d %s", p.Issue.Index, p.Issue.Title))
207+
text = fmt.Sprintf("[%s] Comment deleted by %s", repoLink, senderLink)
208+
titleLink = fmt.Sprintf("%s/issues/%d", p.Repository.HTMLURL, p.Issue.Index)
200209
attachmentText = SlackTextFormatter(p.Comment.Body)
201210
}
202211

@@ -206,9 +215,10 @@ func getSlackIssueCommentPayload(p *api.IssueCommentPayload, slack *SlackMeta) (
206215
Username: slack.Username,
207216
IconURL: slack.IconURL,
208217
Attachments: []SlackAttachment{{
209-
Color: slack.Color,
210-
Title: title,
211-
Text: attachmentText,
218+
Color: slack.Color,
219+
Title: title,
220+
TitleLink: titleLink,
221+
Text: attachmentText,
212222
}},
213223
}, nil
214224
}
@@ -281,91 +291,97 @@ func getSlackPushPayload(p *api.PushPayload, slack *SlackMeta) (*SlackPayload, e
281291

282292
func getSlackPullRequestPayload(p *api.PullRequestPayload, slack *SlackMeta) (*SlackPayload, error) {
283293
senderLink := SlackLinkFormatter(setting.AppURL+p.Sender.UserName, p.Sender.UserName)
284-
titleLink := SlackLinkFormatter(fmt.Sprintf("%s/pulls/%d", p.Repository.HTMLURL, p.Index),
285-
fmt.Sprintf("#%d %s", p.Index, p.PullRequest.Title))
286-
var text, title, attachmentText string
294+
title := fmt.Sprintf("#%d %s", p.Index, p.PullRequest.Title)
295+
titleLink := fmt.Sprintf("%s/pulls/%d", p.Repository.HTMLURL, p.Index)
296+
repoLink := SlackLinkFormatter(p.Repository.HTMLURL, p.Repository.FullName)
297+
var text, attachmentText string
298+
287299
switch p.Action {
288300
case api.HookIssueOpened:
289-
text = fmt.Sprintf("[%s] Pull request submitted by %s", p.Repository.FullName, senderLink)
290-
title = titleLink
301+
text = fmt.Sprintf("[%s] Pull request opened by %s", repoLink, senderLink)
291302
attachmentText = SlackTextFormatter(p.PullRequest.Body)
292303
case api.HookIssueClosed:
293304
if p.PullRequest.HasMerged {
294-
text = fmt.Sprintf("[%s] Pull request merged: %s by %s", p.Repository.FullName, titleLink, senderLink)
305+
text = fmt.Sprintf("[%s] Pull request merged: [%s](%s) by %s", repoLink, title, titleLink, senderLink)
295306
} else {
296-
text = fmt.Sprintf("[%s] Pull request closed: %s by %s", p.Repository.FullName, titleLink, senderLink)
307+
text = fmt.Sprintf("[%s] Pull request closed: [%s](%s) by %s", repoLink, title, titleLink, senderLink)
297308
}
298309
case api.HookIssueReOpened:
299-
text = fmt.Sprintf("[%s] Pull request re-opened: %s by %s", p.Repository.FullName, titleLink, senderLink)
310+
text = fmt.Sprintf("[%s] Pull request re-opened: [%s](%s) by %s", repoLink, title, titleLink, senderLink)
300311
case api.HookIssueEdited:
301-
text = fmt.Sprintf("[%s] Pull request edited: %s by %s", p.Repository.FullName, titleLink, senderLink)
312+
text = fmt.Sprintf("[%s] Pull request edited: [%s](%s) by %s", repoLink, title, titleLink, senderLink)
302313
attachmentText = SlackTextFormatter(p.PullRequest.Body)
303314
case api.HookIssueAssigned:
304315
list := make([]string, len(p.PullRequest.Assignees))
305316
for i, user := range p.PullRequest.Assignees {
306317
list[i] = SlackLinkFormatter(setting.AppURL+user.UserName, user.UserName)
307318
}
308-
text = fmt.Sprintf("[%s] Pull request assigned to %s: %s by %s", p.Repository.FullName,
319+
text = fmt.Sprintf("[%s] Pull request assigned to %s: [%s](%s) by %s", repoLink,
309320
strings.Join(list, ", "),
310-
titleLink, senderLink)
321+
title, titleLink, senderLink)
311322
case api.HookIssueUnassigned:
312-
text = fmt.Sprintf("[%s] Pull request unassigned: %s by %s", p.Repository.FullName, titleLink, senderLink)
323+
text = fmt.Sprintf("[%s] Pull request unassigned: [%s](%s) by %s", repoLink, title, titleLink, senderLink)
313324
case api.HookIssueLabelUpdated:
314-
text = fmt.Sprintf("[%s] Pull request labels updated: %s by %s", p.Repository.FullName, titleLink, senderLink)
325+
text = fmt.Sprintf("[%s] Pull request labels updated: [%s](%s) by %s", repoLink, title, titleLink, senderLink)
315326
case api.HookIssueLabelCleared:
316-
text = fmt.Sprintf("[%s] Pull request labels cleared: %s by %s", p.Repository.FullName, titleLink, senderLink)
327+
text = fmt.Sprintf("[%s] Pull request labels cleared: [%s](%s) by %s", repoLink, title, titleLink, senderLink)
317328
case api.HookIssueSynchronized:
318-
text = fmt.Sprintf("[%s] Pull request synchronized: %s by %s", p.Repository.FullName, titleLink, senderLink)
329+
text = fmt.Sprintf("[%s] Pull request synchronized: [%s](%s) by %s", repoLink, title, titleLink, senderLink)
319330
case api.HookIssueMilestoned:
320-
text = fmt.Sprintf("[%s] Pull request milestoned: #%s %s", p.Repository.FullName, titleLink, senderLink)
331+
mileStoneLink := fmt.Sprintf("%s/milestone/%d", p.Repository.HTMLURL, p.PullRequest.Milestone.ID)
332+
text = fmt.Sprintf("[%s] Pull request milestoned to [%s](%s): [%s](%s) %s", repoLink,
333+
p.PullRequest.Milestone.Title, mileStoneLink, title, titleLink, senderLink)
321334
case api.HookIssueDemilestoned:
322-
text = fmt.Sprintf("[%s] Pull request milestone cleared: #%s %s", p.Repository.FullName, titleLink, senderLink)
335+
text = fmt.Sprintf("[%s] Pull request milestone cleared: [%s](%s) %s", repoLink, title, titleLink, senderLink)
323336
}
324337

325-
return &SlackPayload{
338+
pl := &SlackPayload{
326339
Channel: slack.Channel,
327340
Text: text,
328341
Username: slack.Username,
329342
IconURL: slack.IconURL,
330-
Attachments: []SlackAttachment{{
331-
Color: slack.Color,
332-
Title: title,
333-
Text: attachmentText,
334-
}},
335-
}, nil
343+
}
344+
if attachmentText != "" {
345+
pl.Attachments = []SlackAttachment{{
346+
Color: slack.Color,
347+
Title: title,
348+
TitleLink: titleLink,
349+
Text: attachmentText,
350+
}}
351+
}
352+
353+
return pl, nil
336354
}
337355

338356
func getSlackPullRequestApprovalPayload(p *api.PullRequestPayload, slack *SlackMeta, event HookEventType) (*SlackPayload, error) {
339357
senderLink := SlackLinkFormatter(setting.AppURL+p.Sender.UserName, p.Sender.UserName)
340-
titleLink := SlackLinkFormatter(fmt.Sprintf("%s/pulls/%d", p.Repository.HTMLURL, p.Index),
341-
fmt.Sprintf("#%d %s", p.Index, p.PullRequest.Title))
342-
var text, title, attachmentText string
358+
title := fmt.Sprintf("#%d %s", p.Index, p.PullRequest.Title)
359+
titleLink := fmt.Sprintf("%s/pulls/%d", p.Repository.HTMLURL, p.Index)
360+
repoLink := SlackLinkFormatter(p.Repository.HTMLURL, p.Repository.FullName)
361+
var text string
362+
343363
switch p.Action {
344364
case api.HookIssueSynchronized:
345365
action, err := parseHookPullRequestEventType(event)
346366
if err != nil {
347367
return nil, err
348368
}
349369

350-
text = fmt.Sprintf("[%s] Pull request review %s : %s by %s", p.Repository.FullName, action, titleLink, senderLink)
370+
text = fmt.Sprintf("[%s] Pull request review %s: [%s](%s) by %s", repoLink, action, title, titleLink, senderLink)
351371
}
352372

353373
return &SlackPayload{
354374
Channel: slack.Channel,
355375
Text: text,
356376
Username: slack.Username,
357377
IconURL: slack.IconURL,
358-
Attachments: []SlackAttachment{{
359-
Color: slack.Color,
360-
Title: title,
361-
Text: attachmentText,
362-
}},
363378
}, nil
364379
}
365380

366381
func getSlackRepositoryPayload(p *api.RepositoryPayload, slack *SlackMeta) (*SlackPayload, error) {
367382
senderLink := SlackLinkFormatter(setting.AppURL+p.Sender.UserName, p.Sender.UserName)
368383
var text, title, attachmentText string
384+
369385
switch p.Action {
370386
case api.HookRepoCreated:
371387
text = fmt.Sprintf("[%s] Repository created by %s", p.Repository.FullName, senderLink)
@@ -380,9 +396,10 @@ func getSlackRepositoryPayload(p *api.RepositoryPayload, slack *SlackMeta) (*Sla
380396
Username: slack.Username,
381397
IconURL: slack.IconURL,
382398
Attachments: []SlackAttachment{{
383-
Color: slack.Color,
384-
Title: title,
385-
Text: attachmentText,
399+
Color: slack.Color,
400+
Title: title,
401+
TitleLink: title,
402+
Text: attachmentText,
386403
}},
387404
}, nil
388405
}

0 commit comments

Comments
 (0)