Skip to content

Commit

Permalink
Add support for Slack Icon emojis (influxdata#986)
Browse files Browse the repository at this point in the history
  • Loading branch information
Nathaniel Cook authored Oct 25, 2016
1 parent b7ad058 commit 7c0e6d5
Show file tree
Hide file tree
Showing 7 changed files with 60 additions and 16 deletions.
1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,7 @@ See the API docs for more details.
- [#928](https://github.com/influxdata/kapacitor/issues/928): Add new API endpoint for dynamically overriding sections of the configuration.
- [#980](https://github.com/influxdata/kapacitor/pull/980): Upgrade to using go 1.7
- [#957](https://github.com/influxdata/kapacitor/issues/957): Add API endpoints for testing service integrations.
- [#958](https://github.com/influxdata/kapacitor/issues/958): Add support for Slack icon emojis and custom usernames.

### Bugfixes

Expand Down
2 changes: 2 additions & 0 deletions alert.go
Original file line number Diff line number Diff line change
Expand Up @@ -1047,6 +1047,8 @@ func (a *AlertNode) handleSlack(slack *pipeline.SlackHandler, ad *AlertData) {
err := a.et.tm.SlackService.Alert(
slack.Channel,
ad.Message,
slack.Username,
slack.IconEmoji,
ad.Level,
)
if err != nil {
Expand Down
8 changes: 8 additions & 0 deletions pipeline/alert.go
Original file line number Diff line number Diff line change
Expand Up @@ -1043,6 +1043,14 @@ type SlackHandler struct {
// Slack channel in which to post messages.
// If empty uses the channel from the configuration.
Channel string

// Username of the Slack bot.
// If empty uses the username from the configuration.
Username string

// IconEmoji is an emoji name surrounded in ':' characters.
// The emoji image will replace the normal user icon for the slack bot.
IconEmoji string
}

// Send the alert to Telegram.
Expand Down
24 changes: 18 additions & 6 deletions server/server_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -5645,8 +5645,10 @@ func TestServer_UpdateConfig(t *testing.T) {
"channel": "",
"enabled": false,
"global": true,
"icon-emoji": "",
"state-changes-only": false,
"url": false,
"username": "kapacitor",
},
}},
},
Expand All @@ -5656,8 +5658,10 @@ func TestServer_UpdateConfig(t *testing.T) {
"channel": "",
"enabled": false,
"global": true,
"icon-emoji": "",
"state-changes-only": false,
"url": false,
"username": "kapacitor",
},
},
updates: []updateAction{
Expand All @@ -5678,8 +5682,10 @@ func TestServer_UpdateConfig(t *testing.T) {
"channel": "#general",
"enabled": true,
"global": false,
"icon-emoji": "",
"state-changes-only": false,
"url": true,
"username": "kapacitor",
},
}},
},
Expand All @@ -5689,8 +5695,10 @@ func TestServer_UpdateConfig(t *testing.T) {
"channel": "#general",
"enabled": true,
"global": false,
"icon-emoji": "",
"state-changes-only": false,
"url": true,
"username": "kapacitor",
},
},
},
Expand Down Expand Up @@ -6074,9 +6082,11 @@ func TestServer_ListServiceTests(t *testing.T) {
Link: client.Link{Relation: client.Self, Href: "/kapacitor/v1/service-tests/slack"},
Name: "slack",
Options: client.ServiceTestOptions{
"channel": "",
"message": "test slack message",
"level": "CRITICAL",
"channel": "",
"icon-emoji": "",
"level": "CRITICAL",
"message": "test slack message",
"username": "",
},
},
{
Expand Down Expand Up @@ -6159,9 +6169,11 @@ func TestServer_ListServiceTests_WithPattern(t *testing.T) {
Link: client.Link{Relation: client.Self, Href: "/kapacitor/v1/service-tests/slack"},
Name: "slack",
Options: client.ServiceTestOptions{
"channel": "",
"message": "test slack message",
"level": "CRITICAL",
"channel": "",
"icon-emoji": "",
"level": "CRITICAL",
"message": "test slack message",
"username": "",
},
},
{
Expand Down
11 changes: 10 additions & 1 deletion services/slack/config.go
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ package slack
import (
"net/url"

"github.com/influxdata/kapacitor"
"github.com/pkg/errors"
)

Expand All @@ -13,6 +14,12 @@ type Config struct {
URL string `toml:"url" override:"url,redact"`
// The default channel, can be overridden per alert.
Channel string `toml:"channel" override:"channel"`
// The username of the Slack bot.
// Default: kapacitor
Username string `toml:"username" override:"username"`
// IconEmoji uses an emoji instead of the normal icon for the message.
// The contents should be the name of an emoji surrounded with ':', i.e. ':chart_with_upwards_trend:'
IconEmoji string `toml:"icon-emoji" override:"icon-emoji"`
// Whether all alerts should automatically post to slack
Global bool `toml:"global" override:"global"`
// Whether all alerts should automatically use stateChangesOnly mode.
Expand All @@ -21,7 +28,9 @@ type Config struct {
}

func NewConfig() Config {
return Config{}
return Config{
Username: kapacitor.Product,
}
}

func (c Config) Validate() error {
Expand Down
28 changes: 20 additions & 8 deletions services/slack/service.go
Original file line number Diff line number Diff line change
Expand Up @@ -69,9 +69,11 @@ type attachment struct {
}

type testOptions struct {
Channel string `json:"channel"`
Message string `json:"message"`
Level kapacitor.AlertLevel `json:"level"`
Channel string `json:"channel"`
Message string `json:"message"`
Level kapacitor.AlertLevel `json:"level"`
Username string `json:"username"`
IconEmoji string `json:"icon-emoji"`
}

func (s *Service) TestOptions() interface{} {
Expand All @@ -88,11 +90,11 @@ func (s *Service) Test(options interface{}) error {
if !ok {
return fmt.Errorf("unexpected options type %T", options)
}
return s.Alert(o.Channel, o.Message, o.Level)
return s.Alert(o.Channel, o.Message, o.Username, o.IconEmoji, o.Level)
}

func (s *Service) Alert(channel, message string, level kapacitor.AlertLevel) error {
url, post, err := s.preparePost(channel, message, level)
func (s *Service) Alert(channel, message, username, iconEmoji string, level kapacitor.AlertLevel) error {
url, post, err := s.preparePost(channel, message, username, iconEmoji, level)
if err != nil {
return err
}
Expand All @@ -118,7 +120,7 @@ func (s *Service) Alert(channel, message string, level kapacitor.AlertLevel) err
return nil
}

func (s *Service) preparePost(channel, message string, level kapacitor.AlertLevel) (string, io.Reader, error) {
func (s *Service) preparePost(channel, message, username, iconEmoji string, level kapacitor.AlertLevel) (string, io.Reader, error) {
c := s.config()

if !c.Enabled {
Expand All @@ -142,11 +144,21 @@ func (s *Service) preparePost(channel, message string, level kapacitor.AlertLeve
Color: color,
}
postData := make(map[string]interface{})
postData["as_user"] = false
postData["channel"] = channel
postData["username"] = kapacitor.Product
postData["text"] = ""
postData["attachments"] = []attachment{a}

if username == "" {
username = c.Username
}
postData["username"] = username

if iconEmoji == "" {
iconEmoji = c.IconEmoji
}
postData["icon_emoji"] = iconEmoji

var post bytes.Buffer
enc := json.NewEncoder(&post)
err := enc.Encode(postData)
Expand Down
2 changes: 1 addition & 1 deletion task_master.go
Original file line number Diff line number Diff line change
Expand Up @@ -80,7 +80,7 @@ type TaskMaster struct {
SlackService interface {
Global() bool
StateChangesOnly() bool
Alert(channel, message string, level AlertLevel) error
Alert(channel, message, username, iconEmoji string, level AlertLevel) error
}
TelegramService interface {
Global() bool
Expand Down

0 comments on commit 7c0e6d5

Please sign in to comment.