Skip to content
Snippets Groups Projects
Commit 12fe6157 authored by Jano Hendriks's avatar Jano Hendriks
Browse files

Add slack utils to send formatted slack messages

parent 99b7881c
Branches
Tags
1 merge request!53Slack utils
......@@ -64,6 +64,7 @@ require (
github.com/go-pg/zerochecker v0.2.0 // indirect
github.com/go-stack/stack v1.8.1 // indirect
github.com/golang/protobuf v1.5.2 // indirect
github.com/gorilla/websocket v1.4.2 // indirect
github.com/hbollon/go-edlib v1.6.0 // indirect
github.com/inconshreveable/log15 v3.0.0-testing.3+incompatible // indirect
github.com/inconshreveable/log15/v3 v3.0.0-testing.5 // indirect
......@@ -76,6 +77,7 @@ require (
github.com/olekukonko/tablewriter v0.0.5 // indirect
github.com/pborman/uuid v1.2.1 // indirect
github.com/rivo/uniseg v0.1.0 // indirect
github.com/slack-go/slack v0.15.0 // indirect
github.com/smartystreets/goconvey v1.7.2 // indirect
github.com/ssor/bom v0.0.0-20170718123548-6386211fdfcf // indirect
github.com/tmthrgd/go-hex v0.0.0-20190904060850-447a3041c3bc // indirect
......
......@@ -106,6 +106,7 @@ github.com/go-resty/resty/v2 v2.7.0/go.mod h1:9PWDzw47qPphMRFfhsyk0NnSgvluHcljSM
github.com/go-stack/stack v1.8.1 h1:ntEHSVwIt7PNXNpgPmVfMrNhLtgjlmnZha2kOpuRiDw=
github.com/go-stack/stack v1.8.1/go.mod h1:dcoOX6HbPZSZptuspn9bctJ+N/CnF5gGygcUP3XYfe4=
github.com/go-task/slim-sprig v0.0.0-20210107165309-348f09dbbbc0/go.mod h1:fyg7847qk6SyHyPtNmDHnmrv/HOrqktSC+C9fM+CJOE=
github.com/go-test/deep v1.0.4/go.mod h1:wGDj63lr65AM2AQyKZd/NYHGb0R+1RLqB8NKt3aSFNA=
github.com/golang-jwt/jwt/v4 v4.4.3 h1:Hxl6lhQFj4AnOX6MLrsCb/+7tCj7DxP7VA+2rDIq5AU=
github.com/golang-jwt/jwt/v4 v4.4.3/go.mod h1:m21LjoU+eqJr34lmDMbreY2eSTRJ1cv77w39/MY0Ch0=
github.com/golang/glog v0.0.0-20160126235308-23def4e6c14b/go.mod h1:SBH7ygxi8pfUlaOkMMuAQtPIUF8ecWP5IEl/CR7VP2Q=
......@@ -131,6 +132,7 @@ github.com/google/go-cmp v0.4.0/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/
github.com/google/go-cmp v0.5.0/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=
github.com/google/go-cmp v0.5.5/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=
github.com/google/go-cmp v0.5.6/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=
github.com/google/go-cmp v0.5.7/go.mod h1:n+brtR0CgQNWTVd5ZUFpTBC8YFBDLK/h/bpaJ8/DtOE=
github.com/google/go-cmp v0.5.8 h1:e6P7q2lk1O+qJJb4BtCQXlK8vWEO8V1ZeuEdJNOqZyg=
github.com/google/go-cmp v0.5.8/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY=
github.com/google/uuid v1.0.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo=
......@@ -138,6 +140,8 @@ github.com/google/uuid v1.3.0 h1:t6JiXgmwXMjEs8VusXIJk2BXHsn+wx8BZdTaoZ5fu7I=
github.com/google/uuid v1.3.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo=
github.com/gopherjs/gopherjs v0.0.0-20181017120253-0766667cb4d1 h1:EGx4pi6eqNxGaHF6qqu48+N2wcFQ5qg5FXgOdqsJ5d8=
github.com/gopherjs/gopherjs v0.0.0-20181017120253-0766667cb4d1/go.mod h1:wJfORRmW1u3UXTncJ5qlYoELFm8eSnnEO6hX4iZ3EWY=
github.com/gorilla/websocket v1.4.2 h1:+/TMaTYc4QFitKJxsQ7Yye35DkWvkdLcvGKqM+x0Ufc=
github.com/gorilla/websocket v1.4.2/go.mod h1:YR8l580nyteQvAITg2hZ9XVh4b55+EU/adAjf1fMHhE=
github.com/h2non/parth v0.0.0-20190131123155-b4df798d6542 h1:2VTzZjLZBgl62/EtslCrtky5vbi9dd7HrQPQIx6wqiw=
github.com/h2non/parth v0.0.0-20190131123155-b4df798d6542/go.mod h1:Ow0tF8D4Kplbc8s8sSb3V2oUCygFHVp8gC3Dn6U4MNI=
github.com/hashicorp/yamux v0.1.1 h1:yrQxtgseBDrq9Y652vSRDvsKCJKOUD+GzTS4Y0Y8pvE=
......@@ -223,6 +227,8 @@ github.com/scylladb/termtables v0.0.0-20191203121021-c4c0b6d42ff4/go.mod h1:C1a7
github.com/shurcooL/sanitized_anchor_name v1.0.0/go.mod h1:1NzhyTcUVG4SuEtjjoZeVRXNmyL/1OwPU0+IJeTBvfc=
github.com/sirupsen/logrus v1.8.1 h1:dJKuHgqk1NNQlqoA6BTlM1Wf9DOH3NBjQyu0h9+AZZE=
github.com/sirupsen/logrus v1.8.1/go.mod h1:yWOB1SBYBC5VeMP7gHvWumXLIWorT60ONWic61uBYv0=
github.com/slack-go/slack v0.15.0 h1:LE2lj2y9vqqiOf+qIIy0GvEoxgF1N5yLGZffmEZykt0=
github.com/slack-go/slack v0.15.0/go.mod h1:hlGi5oXA+Gt+yWTPP0plCdRKmjsDxecdHxYQdlMQKOw=
github.com/smartystreets/assertions v1.2.0 h1:42S6lae5dvLc7BrLu/0ugRtcFVjoJNMC/N3yZFZkDFs=
github.com/smartystreets/assertions v1.2.0/go.mod h1:tcbTF8ujkAEcZ8TElKY+i30BzYlVhC/LOxJk7iOWnoo=
github.com/smartystreets/goconvey v1.7.2 h1:9RBaZCeXEQ3UselpuwUQHltGVXvdwm6cv1hgR6gDIPg=
......
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
}
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment