From 1605a592addc6ced299200b397f4c1e7072c69f2 Mon Sep 17 00:00:00 2001 From: Christopher Smith Date: Thu, 22 Apr 2021 02:15:42 -0400 Subject: [PATCH] feat: Add support for discord notifications (#110) * add: functionality for discord bot This was acheived using what seems to be the most well update/documented library for discord in go. https://github.com/bwmarrin/discordgo * rename: botapikey to botapitoken for discord config * document: discord notification configuration * fix: moved message_template documentation back to proper place Co-authored-by: Chris Smith --- README.md | 16 ++++++++++++++ go.mod | 1 + go.sum | 5 +++++ notify/discord.go | 55 +++++++++++++++++++++++++++++++++++++++++++++++ notify/manager.go | 5 +++++ settings.go | 14 +++++++++--- 6 files changed, 93 insertions(+), 3 deletions(-) create mode 100644 notify/discord.go diff --git a/README.md b/README.md index be1836b7..20ac363e 100644 --- a/README.md +++ b/README.md @@ -47,6 +47,7 @@ Currently supports updating A records for subdomains. Doesn't support updating o - [Email](#email) - [Telegram](#telegram) - [Slack](#slack) + - [Discord](#discord) - [Miscellaneous topics](#miscellaneous-topics) - [IPv6 support](#ipv6-support) - [Network interface IP address](#network-interface-ip-address) @@ -496,6 +497,21 @@ To receive a [Slack](https://slack.com) message each time the IP changes, update The `message_template` property supports [markdown](https://www.markdownguide.org). New lines needs to be escaped with `\n`. +#### Discord + +To receive a [Discord](https://discord.gg) message each time the IP changes, update your configuration with the following snippit: + +```json + "notify": { + "discord": { + "enabled": true, + "bot_api_token": "discord_bot_token", + "channel": "your_channel", + "message_template": "(Optional) Domain *{{ .Domain }}* is updated to \n{{ .CurrentIP }}", + } + } +``` + ### Miscellaneous topics #### IPv6 support diff --git a/go.mod b/go.mod index da5de793..a3e1224c 100644 --- a/go.mod +++ b/go.mod @@ -4,6 +4,7 @@ require ( github.com/bitly/go-simplejson v0.5.0 github.com/bmizerany/assert v0.0.0-20160611221934-b7ed37b82869 // indirect github.com/bogdanovich/dns_resolver v0.0.0-20170211073258-a8e42bc6a5b6 // indirect + github.com/bwmarrin/discordgo v0.23.2 github.com/fatih/color v1.7.0 github.com/google/uuid v1.1.1 github.com/kr/pretty v0.1.0 // indirect diff --git a/go.sum b/go.sum index ef880d2f..f754d38f 100644 --- a/go.sum +++ b/go.sum @@ -4,10 +4,14 @@ github.com/bmizerany/assert v0.0.0-20160611221934-b7ed37b82869 h1:DDGfHa7BWjL4Yn github.com/bmizerany/assert v0.0.0-20160611221934-b7ed37b82869/go.mod h1:Ekp36dRnpXw/yCqJaO+ZrUyxD+3VXMFFr56k5XYrpB4= github.com/bogdanovich/dns_resolver v0.0.0-20170211073258-a8e42bc6a5b6 h1:oV1V+uwP+sjmdSkvMxsl/l+HE+N8wbL49wCXZPel25M= github.com/bogdanovich/dns_resolver v0.0.0-20170211073258-a8e42bc6a5b6/go.mod h1:txOV61Nn+21z77KUMkNsp8lTHoOFTtqotltQAFenS9I= +github.com/bwmarrin/discordgo v0.23.2 h1:BzrtTktixGHIu9Tt7dEE6diysEF9HWnXeHuoJEt2fH4= +github.com/bwmarrin/discordgo v0.23.2/go.mod h1:c1WtWUGN6nREDmzIpyTp/iD3VYt4Fpx+bVyfBG7JE+M= github.com/fatih/color v1.7.0 h1:DkWD4oS2D8LGGgTQ6IvwJJXSL5Vp2ffcQg58nFV38Ys= github.com/fatih/color v1.7.0/go.mod h1:Zm6kSWBoL9eyXnKyktHP6abPY2pDugNf5KwzbycvMj4= github.com/google/uuid v1.1.1 h1:Gkbcsh/GbpXz7lPftLA3P6TYMwjCLYm83jiFQZF/3gY= github.com/google/uuid v1.1.1/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= +github.com/gorilla/websocket v1.4.0 h1:WDFjx/TMzVgy9VdMMQi2K2Emtwi2QcUQsztZ/zLaH/Q= +github.com/gorilla/websocket v1.4.0/go.mod h1:E7qHFY5m1UJ88s3WnNqhKjPHQ0heANvMoAMk2YaljkQ= github.com/kr/pretty v0.1.0 h1:L/CwN0zerZDmRFUapSPitk6f+Q3+0za1rQkzVuMiMFI= github.com/kr/pretty v0.1.0/go.mod h1:dAy3ld7l9f0ibDNOQOHHMYYIIbhfbHSm3C4ZsoJORNo= github.com/kr/pty v1.1.1/go.mod h1:pFQYn66WHrOpPYNljwOMqo10TkYh1fy3cYio2l3bCsQ= @@ -19,6 +23,7 @@ github.com/mattn/go-isatty v0.0.4 h1:bnP0vzxcAdeI1zdubAl5PjU6zsERjGZb7raWodagDYs github.com/mattn/go-isatty v0.0.4/go.mod h1:M+lRXTBqGeGNdLjl/ufCoiOlB5xdOkqRJdNxMWT7Zi4= github.com/miekg/dns v1.1.29 h1:xHBEhR+t5RzcFJjBLJlax2daXOrTYtr9z4WdKEfWFzg= github.com/miekg/dns v1.1.29/go.mod h1:KNUDUusw/aVsxyTYZM1oqvCicbwhgbNgztCETuNZ7xM= +golang.org/x/crypto v0.0.0-20181030102418-4d3f4d9ffa16/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4= golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w= golang.org/x/crypto v0.0.0-20191011191535-87dc89f01550 h1:ObdrDkeb4kJdCP557AjRjq69pTHfNouLtWZG7j9rPN8= golang.org/x/crypto v0.0.0-20191011191535-87dc89f01550/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= diff --git a/notify/discord.go b/notify/discord.go new file mode 100644 index 00000000..ba719d8f --- /dev/null +++ b/notify/discord.go @@ -0,0 +1,55 @@ +package notify + +import ( + "errors" + + "github.com/TimothyYe/godns" + "github.com/bwmarrin/discordgo" +) + +type DiscordNotify struct { + conf *godns.Settings +} + +func NewDiscordNotify(conf *godns.Settings) INotify { + return &DiscordNotify{conf: conf} +} + +func (n *DiscordNotify) Send(domain, currentIP string) error { + + if n.conf.Notify.Discord.BotApiToken == "" { + return errors.New("bot api token cannot be empty") + } + + if n.conf.Notify.Discord.Channel == "" { + return errors.New("channel id cannot be empty") + } + + tpl := n.conf.Notify.Discord.MsgTemplate + if tpl == "" { + tpl = "Your IP address for {{.Domain}} has been updated to {{ .CurrentIP }} " + } + msg := buildTemplate(currentIP, domain, tpl) + + //Create discordgo client + d, err := discordgo.New("Bot " + n.conf.Notify.Discord.BotApiToken) + if err != nil { + return errors.New("error creating discord bot") + } + //Open socket connection + err = d.Open() + if err != nil { + return errors.New("error opening connection,") + } + //Send message + _, err = d.ChannelMessageSend(n.conf.Notify.Discord.Channel, msg) + if err != nil { + return errors.New("error sending message") + } + //Close socket connection + err = d.Close() + if err != nil { + return errors.New("error closing discord connection") + } + return nil +} diff --git a/notify/manager.go b/notify/manager.go index b54c5f2e..6057b6fb 100644 --- a/notify/manager.go +++ b/notify/manager.go @@ -11,6 +11,7 @@ const ( Email = "email" Slack = "slack" Telegram = "telegram" + Discord = "discord" ) var ( @@ -51,6 +52,10 @@ func initNotifications(conf *godns.Settings) map[string]INotify { notifyMap[Telegram] = NewTelegramNotify(conf) } + if conf.Notify.Discord.Enabled { + notifyMap[Discord] = NewDiscordNotify(conf) + } + return notifyMap } diff --git a/settings.go b/settings.go index 8827073a..b33794af 100644 --- a/settings.go +++ b/settings.go @@ -15,8 +15,8 @@ type Domain struct { // Notify struct for slack notification type SlackNotify struct { Enabled bool `json:"enabled"` - BotApiToken string `json:"bot_api_token"` - Channel string `json:"channel"` + BotApiToken string `json:"bot_api_token"` + Channel string `json:"channel"` MsgTemplate string `json:"message_template"` UseProxy bool `json:"use_proxy"` } @@ -40,11 +40,19 @@ type MailNotify struct { SendTo string `json:"send_to"` } +type DiscordNotify struct { + Enabled bool `json:"enabled"` + BotApiToken string `json:"bot_api_token"` + Channel string `json:"channel"` + MsgTemplate string `json:"message_template"` +} + // Notify struct type Notify struct { Telegram TelegramNotify `json:"telegram"` Mail MailNotify `json:"mail"` - Slack SlackNotify `json:"slack"` + Slack SlackNotify `json:"slack"` + Discord DiscordNotify `json:"discord"` } // Settings struct