This commit is contained in:
Maxim 2018-02-25 02:31:38 +00:00 committed by GitHub
commit 9ea8fd2815
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
4 changed files with 129 additions and 16 deletions

View file

@ -189,7 +189,9 @@ Watchtower can send notifications when containers are updated. Notifications are
The types of notifications to send are passed via the comma-separated option `--notifications` (or corresponding environment variable `WATCHTOWER_NOTIFICATIONS`), which has the following valid values:
* `email` to send notifications via e-mail
* `discord` to send notifications into Discord channel
### Email
To receive notifications by email, the following command-line options, or their corresponding environment variables, can be set:
* `--notification-email-from` (env. `WATCHTOWER_NOTIFICATION_EMAIL_FROM`): The e-mail address from which notifications will be sent.
@ -214,3 +216,11 @@ docker run -d \
v2tec/watchtower
```
### Discord
To send notifications into Discord channel, the following command-line options, or their corresponding environment variables, can be set:
* `--notification-discord-webhook` (env. `WATCHTOWER_NOTIFICATION_DISCORD_WEBHOOK`): Webhook URL configured in Discord.
[Checkout how to add webhook for channel](https://support.discordapp.com/hc/en-us/articles/228383668)

View file

@ -93,7 +93,7 @@ func main() {
cli.StringSliceFlag{
Name: "notifications",
Value: &cli.StringSlice{},
Usage: "notification types to send (valid: email)",
Usage: "notification types to send (valid: email, discord)",
EnvVar: "WATCHTOWER_NOTIFICATIONS",
},
cli.StringFlag{
@ -127,6 +127,11 @@ func main() {
Usage: "SMTP server password for sending notifications",
EnvVar: "WATCHTOWER_NOTIFICATION_EMAIL_SERVER_PASSWORD",
},
cli.StringFlag{
Name: "notification-discord-webhook",
Usage: "Discord webhook url for sending notifications",
EnvVar: "WATCHTOWER_NOTIFICATION_DISCORD_WEBHOOK",
},
}
if err := app.Run(os.Args); err != nil {

96
notifications/discord.go Normal file
View file

@ -0,0 +1,96 @@
package notifications
import (
"bytes"
"encoding/json"
"fmt"
"net/http"
log "github.com/Sirupsen/logrus"
"github.com/urfave/cli"
)
const (
discordType = "discord"
)
type discordTypeNotifier struct {
WebhookURL string
entries []*log.Entry
}
func newDiscordNotifier(c *cli.Context) typeNotifier {
n := &discordTypeNotifier{
WebhookURL: c.GlobalString("notification-discord-webhook"),
}
log.AddHook(n)
return n
}
func (n *discordTypeNotifier) sendEntries(entries []*log.Entry) {
// Do the sending in a separate goroutine so we don't block the main process.
message := ""
for _, entry := range entries {
message += entry.Time.Format("2006-01-02 15:04:05") + " (" + entry.Level.String() + "): " + entry.Message + "\r\n"
}
go func() {
webhookBody := discordWebhookBody{Content: message}
jsonBody, err := json.Marshal(webhookBody)
if err != nil {
fmt.Println("Failed to build JSON body for Discord notificattion: ", err)
return
}
resp, err := http.Post(n.WebhookURL, "application/json", bytes.NewBuffer([]byte(jsonBody)))
if err != nil {
fmt.Println("Failed to send Discord notificattion: ", err)
}
defer resp.Body.Close()
if resp.StatusCode < 200 || resp.StatusCode > 299 {
fmt.Println("Failed to send Discord notificattion. HTTP RESPONSE STATUS: ", resp.StatusCode)
}
}()
}
func (n *discordTypeNotifier) StartNotification() {
if n.entries == nil {
n.entries = make([]*log.Entry, 0, 10)
}
}
func (n *discordTypeNotifier) SendNotification() {
if n.entries != nil && len(n.entries) != 0 {
n.sendEntries(n.entries)
}
n.entries = nil
}
func (n *discordTypeNotifier) Levels() []log.Level {
// TODO: Make this configurable.
return []log.Level{
log.PanicLevel,
log.FatalLevel,
log.ErrorLevel,
log.WarnLevel,
log.InfoLevel,
}
}
func (n *discordTypeNotifier) Fire(entry *log.Entry) error {
if n.entries != nil {
n.entries = append(n.entries, entry)
} else {
// Log output generated outside a cycle is sent immediately.
n.sendEntries([]*log.Entry{entry})
}
return nil
}
type discordWebhookBody struct {
Content string `json:"content"`
}

View file

@ -26,6 +26,8 @@ func NewNotifier(c *cli.Context) *Notifier {
switch t {
case emailType:
tn = newEmailNotifier(c)
case discordType:
tn = newDiscordNotifier(c)
default:
log.Fatalf("Unknown notification type %q", t)
}