From eec9e9a8810cde642b3940acb10f3b9a060a50f6 Mon Sep 17 00:00:00 2001 From: Kent Hua Date: Thu, 2 Jul 2020 06:14:57 +0000 Subject: [PATCH] add slack support for notification --- README.md | 18 ++++++++++++++ settings.go | 10 ++++++++ utils.go | 68 +++++++++++++++++++++++++++++++++++++++++++++++++++++ 3 files changed, 96 insertions(+) diff --git a/README.md b/README.md index fb3a84d..a2084c9 100644 --- a/README.md +++ b/README.md @@ -405,6 +405,24 @@ Update config file and provide your Telegram options, a notification message wil ``` Markdown is supported in message template, and use `%0A` for newline. +### Slack notification support + +Update config file and provide your Slack options, a notification message will be sent to your slack channel once the IP is changed and updated. + +```json + "notify": { + "slack": { + "enabled": true, + "bot_api_token": "xoxb-xxx", + "channel": "your_channel", + "message_template": "Domain *{{ .Domain }}* is updated to \n{{ .CurrentIP }}", + "use_proxy": false + }, + } +``` +Markdown is supported in message template, and use `\n` for newline. + + ### SOCKS5 proxy support You can also use SOCKS5 proxy, just fill SOCKS5 address to the ```socks5_proxy``` item: diff --git a/settings.go b/settings.go index 4443580..8827073 100644 --- a/settings.go +++ b/settings.go @@ -12,6 +12,15 @@ type Domain struct { SubDomains []string `json:"sub_domains"` } +// Notify struct for slack notification +type SlackNotify struct { + Enabled bool `json:"enabled"` + BotApiToken string `json:"bot_api_token"` + Channel string `json:"channel"` + MsgTemplate string `json:"message_template"` + UseProxy bool `json:"use_proxy"` +} + // Notify struct for telegram notification type TelegramNotify struct { Enabled bool `json:"enabled"` @@ -35,6 +44,7 @@ type MailNotify struct { type Notify struct { Telegram TelegramNotify `json:"telegram"` Mail MailNotify `json:"mail"` + Slack SlackNotify `json:"slack"` } // Settings struct diff --git a/utils.go b/utils.go index d74c03f..8489152 100644 --- a/utils.go +++ b/utils.go @@ -10,6 +10,7 @@ import ( "log" "net" "net/http" + "net/url" "strings" dnsResolver "github.com/TimothyYe/godns/resolver" @@ -321,6 +322,69 @@ func SendMailNotify(configuration *Settings, domain, currentIP string) error { return nil } +// SendSlack sends slack if IP is changed +func SendSlackNotify(configuration *Settings, domain, currentIP string) error { + if !configuration.Notify.Slack.Enabled { + return nil + } + + if configuration.Notify.Slack.BotApiToken == "" { + return errors.New("bot api token cannot be empty") + } + + if configuration.Notify.Slack.Channel == "" { + return errors.New("channel cannot be empty") + } + client := GetHttpClient(configuration, configuration.Notify.Slack.UseProxy) + tpl := configuration.Notify.Slack.MsgTemplate + if tpl == "" { + tpl = "_Your IP address is changed to_\n\n*{{ .CurrentIP }}*\n\nDomain *{{ .Domain }}* is updated" + } + + msg := buildTemplate(currentIP, domain, tpl) + + var response *http.Response + var err error + + formData := url.Values{ + "token": {configuration.Notify.Slack.BotApiToken}, + "channel": {configuration.Notify.Slack.Channel}, + "text": {msg}, + } + + response, err = client.PostForm("https://slack.com/api/chat.postMessage", formData) + + if err != nil { + return err + } + + defer response.Body.Close() + + body, _ := ioutil.ReadAll(response.Body) + type ResponseParameters struct { + MigrateToChatID int64 `json:"migrate_to_chat_id"` // optional + RetryAfter int `json:"retry_after"` // optional + } + type APIResponse struct { + Ok bool `json:"ok"` + Result json.RawMessage `json:"result"` + ErrorCode int `json:"error_code"` + Description string `json:"description"` + Parameters *ResponseParameters `json:"parameters"` + } + var resp APIResponse + err = json.Unmarshal([]byte(body), &resp) + if err != nil { + fmt.Println("error:", err) + return errors.New("Failed to parse response") + } + if !resp.Ok { + return errors.New(resp.Description) + } + + return nil +} + // SendNotify sends notify if IP is changed func SendNotify(configuration *Settings, domain, currentIP string) error { err := SendTelegramNotify(configuration, domain, currentIP) @@ -331,6 +395,10 @@ func SendNotify(configuration *Settings, domain, currentIP string) error { if err != nil { log.Println("Send email notification with error:", err.Error()) } + err = SendSlackNotify(configuration, domain, currentIP) + if err != nil { + log.Println("Send slack notification with error:", err.Error()) + } return nil }