diff --git a/docs/notifications.md b/docs/notifications.md index 3663aff..faa4e4a 100644 --- a/docs/notifications.md +++ b/docs/notifications.md @@ -180,7 +180,7 @@ To send notifications via shoutrrr, the following command-line options, or their - `--notification-url` (env. `WATCHTOWER_NOTIFICATION_URL`): The shoutrrr service URL to be used. -Go to [containrrr.dev/shoutrrr/v0.4/services/overview](https://containrrr.dev/shoutrrr/v0.4/services/overview) to +Go to [containrrr.dev/shoutrrr/v0.5/services/overview](https://containrrr.dev/shoutrrr/v0.5/services/overview) to learn more about the different service URLs you can use. You can define multiple services by space separating the URLs. (See example below) diff --git a/go.mod b/go.mod index 225915b..2515454 100644 --- a/go.mod +++ b/go.mod @@ -17,7 +17,7 @@ require ( github.com/cenkalti/backoff v2.2.1+incompatible // indirect github.com/cloudflare/cfssl v0.0.0-20190911221928-1a911ca1b1d6 // indirect github.com/containerd/continuity v0.0.0-20181203112020-004b46473808 // indirect - github.com/containrrr/shoutrrr v0.4.4 + github.com/containrrr/shoutrrr v0.5.1 github.com/docker/cli v0.0.0-20190327152802-57b27434ea29 github.com/docker/distribution v2.7.1+incompatible github.com/docker/docker v0.0.0-20190404075923-dbe4a30928d4 diff --git a/go.sum b/go.sum index e1d7071..6eb935f 100644 --- a/go.sum +++ b/go.sum @@ -52,6 +52,10 @@ github.com/containerd/continuity v0.0.0-20181203112020-004b46473808 h1:4BX8f882b github.com/containerd/continuity v0.0.0-20181203112020-004b46473808/go.mod h1:GL3xCUCBDV3CZiTSEKksMWbLE66hEyuu9qyDOOqM47Y= github.com/containrrr/shoutrrr v0.4.4 h1:vHZ4E/76pKVY+Jyn/qhBz3X540Bn8NI5ppPHK4PyILY= github.com/containrrr/shoutrrr v0.4.4/go.mod h1:zqL2BvfC1W4FujrT4b3/ZCLxvD+uoeEpBL7rg9Dqpbg= +github.com/containrrr/shoutrrr v0.5.0 h1:befKPRMqSvEsHYgxYJq4nuGmSWYvjbhVvb0nNk5OR5Q= +github.com/containrrr/shoutrrr v0.5.0/go.mod h1:XSU8tOIZ1JG8m6OuPozfGLpj6Ed+S8ZrRJaEodQhbzw= +github.com/containrrr/shoutrrr v0.5.1 h1:who87ACg0spQdbImaFMsOSh3g2FWyeN5nmO8tCg3llQ= +github.com/containrrr/shoutrrr v0.5.1/go.mod h1:XSU8tOIZ1JG8m6OuPozfGLpj6Ed+S8ZrRJaEodQhbzw= github.com/coreos/bbolt v1.3.2/go.mod h1:iRUV2dpdMOn7Bo10OQBFzIJO9kkE559Wcmn+qkEiiKk= github.com/coreos/etcd v3.3.10+incompatible/go.mod h1:uF7uidLiAD3TWHmW31ZFd/JWoc32PjwdhPthX9715RE= github.com/coreos/etcd v3.3.13+incompatible/go.mod h1:uF7uidLiAD3TWHmW31ZFd/JWoc32PjwdhPthX9715RE= diff --git a/pkg/notifications/notifier.go b/pkg/notifications/notifier.go index e1cb5e7..b54630c 100644 --- a/pkg/notifications/notifier.go +++ b/pkg/notifications/notifier.go @@ -66,7 +66,7 @@ func AppendLegacyUrls(urls []string, cmd *cobra.Command) []string { shoutrrrURL, err := legacyNotifier.GetURL(cmd) if err != nil { - log.Fatal("failed to create notification config:", err) + log.Fatal("failed to create notification config: ", err) } urls = append(urls, shoutrrrURL) diff --git a/pkg/notifications/notifier_test.go b/pkg/notifications/notifier_test.go index 58c1ebb..71bfea3 100644 --- a/pkg/notifications/notifier_test.go +++ b/pkg/notifications/notifier_test.go @@ -40,7 +40,7 @@ var _ = Describe("notifications", func() { token := "abvsihdbau" color := notifications.ColorInt title := url.QueryEscape(notifications.GetTitle(command)) - expected := fmt.Sprintf("discord://%s@%s?color=0x%x&colordebug=0x0&colorerror=0x0&colorinfo=0x0&colorwarn=0x0&splitlines=Yes&title=%s&username=watchtower", token, channel, color, title) + expected := fmt.Sprintf("discord://%s@%s?color=0x%x&colordebug=0x0&colorerror=0x0&colorinfo=0x0&colorwarn=0x0&title=%s&username=watchtower", token, channel, color, title) buildArgs := func(url string) []string { return []string{ "--notifications", @@ -60,31 +60,56 @@ var _ = Describe("notifications", func() { }) }) When("converting a slack service config into a shoutrrr url", func() { + command := cmd.NewRootCommand() + flags.RegisterNotificationFlags(command) + username := "containrrrbot" + tokenA := "AAAAAAAAA" + tokenB := "BBBBBBBBB" + tokenC := "123456789123456789123456" + color := url.QueryEscape(notifications.ColorHex) + title := url.QueryEscape(notifications.GetTitle(command)) + iconURL := "https://containrrr.dev/watchtower-sq180.png" + iconEmoji := "whale" + + When("icon URL is specified", func() { + It("should return the expected URL", func() { + + hookURL := fmt.Sprintf("https://hooks.slack.com/services/%s/%s/%s", tokenA, tokenB, tokenC) + expectedOutput := fmt.Sprintf("slack://hook:%s-%s-%s@webhook?botname=%s&color=%s&icon=%s&title=%s", tokenA, tokenB, tokenC, username, color, url.QueryEscape(iconURL), title) + + args := []string{ + "--notifications", + "slack", + "--notification-slack-hook-url", + hookURL, + "--notification-slack-identifier", + username, + "--notification-slack-icon-url", + iconURL, + } + + testURL(args, expectedOutput) + }) + }) - It("should return the expected URL", func() { - command := cmd.NewRootCommand() - flags.RegisterNotificationFlags(command) - - username := "containrrrbot" - tokenA := "aaa" - tokenB := "bbb" - tokenC := "ccc" - color := url.QueryEscape(notifications.ColorHex) - title := url.QueryEscape(notifications.GetTitle(command)) - - hookURL := fmt.Sprintf("https://hooks.slack.com/services/%s/%s/%s", tokenA, tokenB, tokenC) - expectedOutput := fmt.Sprintf("slack://%s@%s/%s/%s?color=%s&title=%s", username, tokenA, tokenB, tokenC, color, title) - - args := []string{ - "--notifications", - "slack", - "--notification-slack-hook-url", - hookURL, - "--notification-slack-identifier", - username, - } - - testURL(args, expectedOutput) + When("icon emoji is specified", func() { + It("should return the expected URL", func() { + hookURL := fmt.Sprintf("https://hooks.slack.com/services/%s/%s/%s", tokenA, tokenB, tokenC) + expectedOutput := fmt.Sprintf("slack://hook:%s-%s-%s@webhook?botname=%s&color=%s&icon=%s&title=%s", tokenA, tokenB, tokenC, username, color, iconEmoji, title) + + args := []string{ + "--notifications", + "slack", + "--notification-slack-hook-url", + hookURL, + "--notification-slack-identifier", + username, + "--notification-slack-icon-emoji", + iconEmoji, + } + + testURL(args, expectedOutput) + }) }) }) }) @@ -208,6 +233,7 @@ func buildExpectedURL(username string, password string, host string, port int, f } func testURL(args []string, expectedURL string) { + defer GinkgoRecover() command := cmd.NewRootCommand() flags.RegisterNotificationFlags(command) diff --git a/pkg/notifications/slack.go b/pkg/notifications/slack.go index 7f6e0d4..c5c73b2 100644 --- a/pkg/notifications/slack.go +++ b/pkg/notifications/slack.go @@ -49,7 +49,7 @@ func (s *slackTypeNotifier) GetURL(c *cobra.Command) (string, error) { if parts[0] == "discord.com" || parts[0] == "discordapp.com" { log.Debug("Detected a discord slack wrapper URL, using shoutrrr discord service") conf := &shoutrrrDisco.Config{ - Channel: parts[len(parts)-3], + WebhookID: parts[len(parts)-3], Token: parts[len(parts)-2], Color: ColorInt, Title: GetTitle(c), @@ -59,15 +59,24 @@ func (s *slackTypeNotifier) GetURL(c *cobra.Command) (string, error) { return conf.GetURL().String(), nil } - rawTokens := strings.Replace(s.HookURL, "https://hooks.slack.com/services/", "", 1) - tokens := strings.Split(rawTokens, "/") + webhookToken := strings.Replace(s.HookURL, "https://hooks.slack.com/services/", "", 1) conf := &shoutrrrSlack.Config{ BotName: s.Username, - Token: tokens, Color: ColorHex, + Channel: "webhook", Title: GetTitle(c), } + if s.IconURL != "" { + conf.Icon = s.IconURL + } else if s.IconEmoji != "" { + conf.Icon = s.IconEmoji + } + + if err := conf.Token.SetFromProp(webhookToken); err != nil { + return "", err + } + return conf.GetURL().String(), nil }