BuildMessage constructs the Slack message payload with a colored attachment sidebar.
(ctx webhook.Context)
| 117 | |
| 118 | // BuildMessage constructs the Slack message payload with a colored attachment sidebar. |
| 119 | func BuildMessage(ctx webhook.Context) MessagePayload { |
| 120 | var blocks []Block |
| 121 | |
| 122 | // Title — linked when Link is present. |
| 123 | escapedTitle := escapeMrkdwn(ctx.Title) |
| 124 | titleText := escapedTitle |
| 125 | if ctx.Link != "" { |
| 126 | titleText = fmt.Sprintf("<%s|%s>", ctx.Link, escapedTitle) |
| 127 | } |
| 128 | blocks = append(blocks, Block{ |
| 129 | Type: "section", |
| 130 | Text: &BlockMarkdown{Type: "mrkdwn", Text: levelEmoji(ctx.Level) + "*" + titleText + "*"}, |
| 131 | }) |
| 132 | |
| 133 | // Description. |
| 134 | if ctx.Description != "" { |
| 135 | blocks = append(blocks, Block{ |
| 136 | Type: "section", |
| 137 | Text: &BlockMarkdown{Type: "mrkdwn", Text: escapeMrkdwn(ctx.Description)}, |
| 138 | }) |
| 139 | } |
| 140 | |
| 141 | // Issue/Rollout title — prominent tile between description and metadata. |
| 142 | if ctx.Issue != nil { |
| 143 | blocks = append(blocks, Block{ |
| 144 | Type: "section", |
| 145 | Text: &BlockMarkdown{Type: "mrkdwn", Text: fmt.Sprintf("*%s*", escapeMrkdwn(ctx.Issue.Name))}, |
| 146 | }) |
| 147 | if ctx.Issue.Description != "" { |
| 148 | blocks = append(blocks, Block{ |
| 149 | Type: "section", |
| 150 | Text: &BlockMarkdown{Type: "mrkdwn", Text: escapeMrkdwn(common.TruncateStringWithDescription(ctx.Issue.Description))}, |
| 151 | }) |
| 152 | } |
| 153 | } else if ctx.Rollout != nil && ctx.Rollout.Title != "" { |
| 154 | blocks = append(blocks, Block{ |
| 155 | Type: "section", |
| 156 | Text: &BlockMarkdown{Type: "mrkdwn", Text: fmt.Sprintf("*%s*", escapeMrkdwn(ctx.Rollout.Title))}, |
| 157 | }) |
| 158 | } |
| 159 | |
| 160 | // Compact context metadata (issue/rollout name shown above as tile). |
| 161 | var parts []string |
| 162 | if ctx.Project != nil { |
| 163 | parts = append(parts, fmt.Sprintf("*Project:* %s", escapeMrkdwn(ctx.Project.Title))) |
| 164 | } |
| 165 | if ctx.Issue != nil && ctx.Issue.Creator.Name != "" { |
| 166 | parts = append(parts, fmt.Sprintf("*Creator:* %s", escapeMrkdwn(ctx.Issue.Creator.Name))) |
| 167 | } |
| 168 | if ctx.Rollout != nil && ctx.Environment != "" { |
| 169 | parts = append(parts, fmt.Sprintf("*Env:* %s", escapeMrkdwn(ctx.Environment))) |
| 170 | } |
| 171 | if ctx.ActorName != "" { |
| 172 | parts = append(parts, fmt.Sprintf("*By:* %s", escapeMrkdwn(ctx.ActorName))) |
| 173 | } |
| 174 | if len(parts) > 0 { |
| 175 | blocks = append(blocks, Block{ |
| 176 | Type: "context", |