Skip to content
Snippets Groups Projects

Slack utils

Merged Jano Hendriks requested to merge slack-utils into main
1 unresolved thread
Files
3
+ 117
0
package slack_utils
import (
"fmt"
"github.com/samber/lo"
"github.com/slack-go/slack"
"gitlab.bob.co.za/bob-public-utils/bobgroup-go-utils/errors"
"gitlab.bob.co.za/bob-public-utils/bobgroup-go-utils/logs"
"reflect"
"regexp"
)
type SlackField struct {
Label string
Value any
}
type SlackClient struct {
Client *slack.Client
}
func GetSlackClient(apiKey string) *SlackClient {
return &SlackClient{
Client: slack.New(apiKey),
}
}
func (s *SlackClient) SendAlert(message string, channel string, parentMessageTimestamp ...string) string {
if s == nil || s.Client == nil {
// If the slack client isn't set, log the message to Raygun instead
logs.ErrorMsg(message)
return ""
}
slackMessageOptions := []slack.MsgOption{
slack.MsgOptionText(message, false),
}
if len(parentMessageTimestamp) > 0 {
slackMessageOptions = append(slackMessageOptions, slack.MsgOptionTS(parentMessageTimestamp[0]))
}
return s.postMessage(channel, slackMessageOptions)
}
func (s *SlackClient) SendAlertWithFields(message string, channel string, slackFields []SlackField, parentMessageTimestamp ...string) string {
if s == nil || s.Client == nil {
// If the slack client isn't set, log the message to Raygun instead
slackFieldMap := slackFieldsToMap(slackFields)
logs.ErrorWithFields(slackFieldMap, errors.Error(message))
return ""
}
blocks := []slack.Block{slack.NewSectionBlock(slack.NewTextBlockObject(
"plain_text",
message,
hasEmoji(message),
false),
nil,
nil,
),
}
slackFieldsChunked := lo.Chunk(slackFields, 2)
for _, slackFieldsChunk := range slackFieldsChunked {
fieldBlocksForChunk := []*slack.TextBlockObject{}
for _, slackField := range slackFieldsChunk {
slackFieldValue := slackField.Value
// if slackField.Value is a pointer, dereference it
if reflect.ValueOf(slackField.Value).Kind() == reflect.Ptr {
slackFieldValue = reflect.ValueOf(slackField.Value).Elem().Interface()
}
text := fmt.Sprintf("*%s*\n%v", slackField.Label, slackFieldValue)
fieldBlocksForChunk = append(fieldBlocksForChunk, slack.NewTextBlockObject(
"mrkdwn",
text,
false,
false,
))
}
blocks = append(blocks, slack.NewSectionBlock(nil, fieldBlocksForChunk, nil))
}
slackMessageOptions := []slack.MsgOption{
slack.MsgOptionBlocks(blocks...),
}
if len(parentMessageTimestamp) > 0 {
slackMessageOptions = append(slackMessageOptions, slack.MsgOptionTS(parentMessageTimestamp[0]))
}
return s.postMessage(channel, slackMessageOptions)
}
func (s *SlackClient) postMessage(channel string, messageOptions []slack.MsgOption) string {
_, messageTimestamp, err := s.Client.PostMessage(channel, messageOptions...)
if err != nil {
logs.ErrorWithMsg("Error sending slack: %v+\n", err)
}
return messageTimestamp
}
func hasEmoji(message string) bool {
emojiRegex := regexp.MustCompile(`:[a-zA-Z0-9_]+:`)
return emojiRegex.MatchString(message)
}
func slackFieldsToMap(fields []SlackField) map[string]any {
slackFieldsMap := make(map[string]any)
for _, field := range fields {
slackFieldsMap[field.Label] = field.Value
}
return slackFieldsMap
}
Loading