mirror of
https://github.com/taigrr/godns
synced 2025-01-18 04:03:25 -08:00
Merge pull request #56 from jemyzhang/master
Add support to telegram notification
This commit is contained in:
commit
1a417c87b3
18
README.md
18
README.md
@ -337,6 +337,7 @@ Update config file and provide your SMTP options, a notification mail will be se
|
|||||||
|
|
||||||
```json
|
```json
|
||||||
"notify": {
|
"notify": {
|
||||||
|
"mail": {
|
||||||
"enabled": true,
|
"enabled": true,
|
||||||
"smtp_server": "smtp.example.com",
|
"smtp_server": "smtp.example.com",
|
||||||
"smtp_username": "user",
|
"smtp_username": "user",
|
||||||
@ -344,12 +345,29 @@ Update config file and provide your SMTP options, a notification mail will be se
|
|||||||
"smtp_port": 25,
|
"smtp_port": 25,
|
||||||
"send_to": "my_mail@example.com"
|
"send_to": "my_mail@example.com"
|
||||||
}
|
}
|
||||||
|
}
|
||||||
```
|
```
|
||||||
|
|
||||||
Notification mail example:
|
Notification mail example:
|
||||||
|
|
||||||
<img src="https://github.com/TimothyYe/godns/blob/master/snapshots/mail.png?raw=true" />
|
<img src="https://github.com/TimothyYe/godns/blob/master/snapshots/mail.png?raw=true" />
|
||||||
|
|
||||||
|
### Telegram notification support
|
||||||
|
|
||||||
|
Update config file and provide your Telegram options, a notification message will be sent to your telegram channel once the IP is changed and updated.
|
||||||
|
|
||||||
|
```json
|
||||||
|
"notify": {
|
||||||
|
"telegram": {
|
||||||
|
"enabled": true,
|
||||||
|
"bot_api_key": "11111:aaaa-bbbb",
|
||||||
|
"chat_id": "-123456",
|
||||||
|
"message_template": "Domain *{{ .Domain }}* is updated to %0A{{ .CurrentIP }}"
|
||||||
|
},
|
||||||
|
}
|
||||||
|
```
|
||||||
|
Markdown is supported in message template, and use `%0A` for newline.
|
||||||
|
|
||||||
### SOCKS5 proxy support
|
### SOCKS5 proxy support
|
||||||
|
|
||||||
You can also use SOCKS5 proxy, just fill SOCKS5 address to the ```socks5_proxy``` item:
|
You can also use SOCKS5 proxy, just fill SOCKS5 address to the ```socks5_proxy``` item:
|
||||||
|
@ -26,6 +26,13 @@
|
|||||||
"ip_interface": "eth0",
|
"ip_interface": "eth0",
|
||||||
"socks5_proxy": "",
|
"socks5_proxy": "",
|
||||||
"notify": {
|
"notify": {
|
||||||
|
"telegram": {
|
||||||
|
"enabled": false,
|
||||||
|
"bot_api_key": "",
|
||||||
|
"chat_id": "",
|
||||||
|
"message_template": ""
|
||||||
|
},
|
||||||
|
"mail": {
|
||||||
"enabled": false,
|
"enabled": false,
|
||||||
"smtp_server": "",
|
"smtp_server": "",
|
||||||
"smtp_username": "",
|
"smtp_username": "",
|
||||||
@ -33,4 +40,5 @@
|
|||||||
"smtp_port": 25,
|
"smtp_port": 25,
|
||||||
"send_to": ""
|
"send_to": ""
|
||||||
}
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -62,15 +62,12 @@ func (handler *Handler) DomainLoop(domain *godns.Domain, panicChan chan<- godns.
|
|||||||
log.Printf("IP updated for subdomain:%s\r\n", subDomain)
|
log.Printf("IP updated for subdomain:%s\r\n", subDomain)
|
||||||
}
|
}
|
||||||
|
|
||||||
// Send mail notification if notify is enabled
|
// Send notification
|
||||||
if handler.Configuration.Notify.Enabled {
|
|
||||||
log.Print("Sending notification to:", handler.Configuration.Notify.SendTo)
|
|
||||||
if err := godns.SendNotify(handler.Configuration, fmt.Sprintf("%s.%s", subDomain, domain.DomainName), currentIP); err != nil {
|
if err := godns.SendNotify(handler.Configuration, fmt.Sprintf("%s.%s", subDomain, domain.DomainName), currentIP); err != nil {
|
||||||
log.Printf("Failed to send notification")
|
log.Printf("Failed to send notification")
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
// Sleep with interval
|
// Sleep with interval
|
||||||
log.Printf("Going to sleep, will start next checking in %d seconds...\r\n", handler.Configuration.Interval)
|
log.Printf("Going to sleep, will start next checking in %d seconds...\r\n", handler.Configuration.Interval)
|
||||||
time.Sleep(time.Second * time.Duration(handler.Configuration.Interval))
|
time.Sleep(time.Second * time.Duration(handler.Configuration.Interval))
|
||||||
|
@ -105,13 +105,10 @@ func (handler *Handler) DomainLoop(domain *godns.Domain, panicChan chan<- godns.
|
|||||||
log.Printf("IP mismatch: Current(%+v) vs Cloudflare(%+v)\r\n", currentIP, rec.IP)
|
log.Printf("IP mismatch: Current(%+v) vs Cloudflare(%+v)\r\n", currentIP, rec.IP)
|
||||||
handler.updateRecord(rec, currentIP)
|
handler.updateRecord(rec, currentIP)
|
||||||
|
|
||||||
// Send mail notification if notify is enabled
|
// Send notification
|
||||||
if handler.Configuration.Notify.Enabled {
|
|
||||||
log.Print("Sending notification to:", handler.Configuration.Notify.SendTo)
|
|
||||||
if err := godns.SendNotify(handler.Configuration, rec.Name, currentIP); err != nil {
|
if err := godns.SendNotify(handler.Configuration, rec.Name, currentIP); err != nil {
|
||||||
log.Println("Failed to send notification")
|
log.Println("Failed to send notification")
|
||||||
}
|
}
|
||||||
}
|
|
||||||
} else {
|
} else {
|
||||||
log.Printf("Record OK: %+v - %+v\r\n", rec.Name, rec.IP)
|
log.Printf("Record OK: %+v - %+v\r\n", rec.Name, rec.IP)
|
||||||
}
|
}
|
||||||
|
@ -73,14 +73,10 @@ func (handler *Handler) DomainLoop(domain *godns.Domain, panicChan chan<- godns.
|
|||||||
log.Printf("%s.%s Start to update record IP...\n", subDomain, domain.DomainName)
|
log.Printf("%s.%s Start to update record IP...\n", subDomain, domain.DomainName)
|
||||||
handler.UpdateIP(domainID, subDomainID, subDomain, currentIP)
|
handler.UpdateIP(domainID, subDomainID, subDomain, currentIP)
|
||||||
|
|
||||||
// Send mail notification if notify is enabled
|
// Send notification
|
||||||
if handler.Configuration.Notify.Enabled {
|
|
||||||
log.Print("Sending notification to:", handler.Configuration.Notify.SendTo)
|
|
||||||
if err := godns.SendNotify(handler.Configuration, fmt.Sprintf("%s.%s", subDomain, domain.DomainName), currentIP); err != nil {
|
if err := godns.SendNotify(handler.Configuration, fmt.Sprintf("%s.%s", subDomain, domain.DomainName), currentIP); err != nil {
|
||||||
log.Println("Failed to send notification")
|
log.Println("Failed to send notification")
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
} else {
|
} else {
|
||||||
log.Printf("%s.%s Current IP is same as domain IP, no need to update...\n", subDomain, domain.DomainName)
|
log.Printf("%s.%s Current IP is same as domain IP, no need to update...\n", subDomain, domain.DomainName)
|
||||||
}
|
}
|
||||||
|
@ -79,15 +79,12 @@ func (handler *Handler) DomainLoop(domain *godns.Domain, panicChan chan<- godns.
|
|||||||
log.Print("IP updated to:", currentIP)
|
log.Print("IP updated to:", currentIP)
|
||||||
}
|
}
|
||||||
|
|
||||||
// Send mail notification if notify is enabled
|
// Send notification
|
||||||
if handler.Configuration.Notify.Enabled {
|
|
||||||
log.Print("Sending notification to:", handler.Configuration.Notify.SendTo)
|
|
||||||
if err := godns.SendNotify(handler.Configuration, fmt.Sprintf("%s.%s", subDomain, domain.DomainName), currentIP); err != nil {
|
if err := godns.SendNotify(handler.Configuration, fmt.Sprintf("%s.%s", subDomain, domain.DomainName), currentIP); err != nil {
|
||||||
log.Println("Failed to send notification")
|
log.Println("Failed to send notification")
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
// Sleep with interval
|
// Sleep with interval
|
||||||
log.Printf("Going to sleep, will start next checking in %d seconds...\r\n", handler.Configuration.Interval)
|
log.Printf("Going to sleep, will start next checking in %d seconds...\r\n", handler.Configuration.Interval)
|
||||||
|
@ -58,15 +58,12 @@ func (handler *Handler) DomainLoop(domain *godns.Domain, panicChan chan<- godns.
|
|||||||
log.Printf("%s.%s Start to update record IP...\n", subDomain, domain.DomainName)
|
log.Printf("%s.%s Start to update record IP...\n", subDomain, domain.DomainName)
|
||||||
handler.UpdateIP(domain.DomainName, subDomain, currentIP)
|
handler.UpdateIP(domain.DomainName, subDomain, currentIP)
|
||||||
|
|
||||||
// Send mail notification if notify is enabled
|
// Send notification
|
||||||
if handler.Configuration.Notify.Enabled {
|
|
||||||
log.Print("Sending notification to:", handler.Configuration.Notify.SendTo)
|
|
||||||
if err := godns.SendNotify(handler.Configuration, fmt.Sprintf("%s.%s", subDomain, domain.DomainName), currentIP); err != nil {
|
if err := godns.SendNotify(handler.Configuration, fmt.Sprintf("%s.%s", subDomain, domain.DomainName), currentIP); err != nil {
|
||||||
log.Println("Failed to send notification")
|
log.Println("Failed to send notification")
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
// Sleep with interval
|
// Sleep with interval
|
||||||
log.Printf("Going to sleep, will start next checking in %d seconds...\r\n", handler.Configuration.Interval)
|
log.Printf("Going to sleep, will start next checking in %d seconds...\r\n", handler.Configuration.Interval)
|
||||||
time.Sleep(time.Second * time.Duration(handler.Configuration.Interval))
|
time.Sleep(time.Second * time.Duration(handler.Configuration.Interval))
|
||||||
|
@ -57,15 +57,12 @@ func (handler *Handler) DomainLoop(domain *godns.Domain, panicChan chan<- godns.
|
|||||||
log.Printf("%s.%s Start to update record IP...\n", subDomain, domain.DomainName)
|
log.Printf("%s.%s Start to update record IP...\n", subDomain, domain.DomainName)
|
||||||
handler.UpdateIP(domain.DomainName, subDomain, currentIP)
|
handler.UpdateIP(domain.DomainName, subDomain, currentIP)
|
||||||
|
|
||||||
// Send mail notification if notify is enabled
|
// Send notification
|
||||||
if handler.Configuration.Notify.Enabled {
|
|
||||||
log.Print("Sending notification to:", handler.Configuration.Notify.SendTo)
|
|
||||||
if err := godns.SendNotify(handler.Configuration, fmt.Sprintf("%s.%s", subDomain, domain.DomainName), currentIP); err != nil {
|
if err := godns.SendNotify(handler.Configuration, fmt.Sprintf("%s.%s", subDomain, domain.DomainName), currentIP); err != nil {
|
||||||
log.Println("Failed to send notification")
|
log.Println("Failed to send notification")
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
// Sleep with interval
|
// Sleep with interval
|
||||||
log.Printf("Going to sleep, will start next checking in %d seconds...\r\n", handler.Configuration.Interval)
|
log.Printf("Going to sleep, will start next checking in %d seconds...\r\n", handler.Configuration.Interval)
|
||||||
time.Sleep(time.Second * time.Duration(handler.Configuration.Interval))
|
time.Sleep(time.Second * time.Duration(handler.Configuration.Interval))
|
||||||
|
16
settings.go
16
settings.go
@ -12,8 +12,16 @@ type Domain struct {
|
|||||||
SubDomains []string `json:"sub_domains"`
|
SubDomains []string `json:"sub_domains"`
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Notify struct for telegram notification
|
||||||
|
type TelegramNotify struct {
|
||||||
|
Enabled bool `json:"enabled"`
|
||||||
|
BotApiKey string `json:"bot_api_key"`
|
||||||
|
ChatId string `json:"chat_id"`
|
||||||
|
MsgTemplate string `json:"message_template"`
|
||||||
|
}
|
||||||
|
|
||||||
// Notify struct for SMTP notification
|
// Notify struct for SMTP notification
|
||||||
type Notify struct {
|
type MailNotify struct {
|
||||||
Enabled bool `json:"enabled"`
|
Enabled bool `json:"enabled"`
|
||||||
SMTPServer string `json:"smtp_server"`
|
SMTPServer string `json:"smtp_server"`
|
||||||
SMTPUsername string `json:"smtp_username"`
|
SMTPUsername string `json:"smtp_username"`
|
||||||
@ -22,6 +30,12 @@ type Notify struct {
|
|||||||
SendTo string `json:"send_to"`
|
SendTo string `json:"send_to"`
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Notify struct
|
||||||
|
type Notify struct {
|
||||||
|
Telegram TelegramNotify `json:"telegram"`
|
||||||
|
Mail MailNotify `json:"mail"`
|
||||||
|
}
|
||||||
|
|
||||||
// Settings struct
|
// Settings struct
|
||||||
type Settings struct {
|
type Settings struct {
|
||||||
Provider string `json:"provider"`
|
Provider string `json:"provider"`
|
||||||
|
96
utils.go
96
utils.go
@ -2,7 +2,9 @@ package godns
|
|||||||
|
|
||||||
import (
|
import (
|
||||||
"bytes"
|
"bytes"
|
||||||
|
"encoding/json"
|
||||||
"errors"
|
"errors"
|
||||||
|
"fmt"
|
||||||
"html/template"
|
"html/template"
|
||||||
"io/ioutil"
|
"io/ioutil"
|
||||||
"log"
|
"log"
|
||||||
@ -234,30 +236,108 @@ func CheckSettings(config *Settings) error {
|
|||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// SendNotify sends notify if IP is changed
|
||||||
|
func SendTelegramNotify(configuration *Settings, domain, currentIP string) error {
|
||||||
|
if ! configuration.Notify.Telegram.Enabled {
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
if configuration.Notify.Telegram.BotApiKey == "" {
|
||||||
|
return errors.New("bot api key cannot be empty")
|
||||||
|
}
|
||||||
|
|
||||||
|
if configuration.Notify.Telegram.ChatId == "" {
|
||||||
|
return errors.New("chat id cannot be empty")
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
client := GetHttpClient(configuration)
|
||||||
|
tpl := configuration.Notify.Telegram.MsgTemplate
|
||||||
|
if tpl == "" {
|
||||||
|
tpl = "_Your IP address is changed to_%0A%0A*{{ .CurrentIP }}*%0A%0ADomain *{{ .Domain }}* is updated"
|
||||||
|
}
|
||||||
|
|
||||||
|
msg := buildTemplate(currentIP, domain, tpl)
|
||||||
|
url := fmt.Sprintf("https://api.telegram.org/bot%s/sendMessage?chat_id=%s&parse_mode=Markdown&text=%s",
|
||||||
|
configuration.Notify.Telegram.BotApiKey,
|
||||||
|
configuration.Notify.Telegram.ChatId,
|
||||||
|
msg)
|
||||||
|
var response *http.Response
|
||||||
|
var err error
|
||||||
|
|
||||||
|
response, err = client.Get(url)
|
||||||
|
|
||||||
|
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 mail notify if IP is changed
|
// SendNotify sends mail notify if IP is changed
|
||||||
func SendNotify(configuration *Settings, domain, currentIP string) error {
|
func SendMailNotify(configuration *Settings, domain, currentIP string) error {
|
||||||
|
if ! configuration.Notify.Mail.Enabled {
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
log.Print("Sending notification to:", configuration.Notify.Mail.SendTo)
|
||||||
m := gomail.NewMessage()
|
m := gomail.NewMessage()
|
||||||
|
|
||||||
m.SetHeader("From", configuration.Notify.SMTPUsername)
|
m.SetHeader("From", configuration.Notify.Mail.SMTPUsername)
|
||||||
m.SetHeader("To", configuration.Notify.SendTo)
|
m.SetHeader("To", configuration.Notify.Mail.SendTo)
|
||||||
m.SetHeader("Subject", "GoDNS Notification")
|
m.SetHeader("Subject", "GoDNS Notification")
|
||||||
log.Println("currentIP:", currentIP)
|
log.Println("currentIP:", currentIP)
|
||||||
log.Println("domain:", domain)
|
log.Println("domain:", domain)
|
||||||
m.SetBody("text/html", buildTemplate(currentIP, domain))
|
m.SetBody("text/html", buildTemplate(currentIP, domain, mailTemplate))
|
||||||
|
|
||||||
d := gomail.NewPlainDialer(configuration.Notify.SMTPServer, configuration.Notify.SMTPPort, configuration.Notify.SMTPUsername, configuration.Notify.SMTPPassword)
|
d := gomail.NewPlainDialer(configuration.Notify.Mail.SMTPServer, configuration.Notify.Mail.SMTPPort, configuration.Notify.Mail.SMTPUsername, configuration.Notify.Mail.SMTPPassword)
|
||||||
|
|
||||||
// Send the email config by sendlist .
|
// Send the email config by sendlist .
|
||||||
if err := d.DialAndSend(m); err != nil {
|
if err := d.DialAndSend(m); err != nil {
|
||||||
log.Println("Send email notification with error:", err.Error())
|
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func buildTemplate(currentIP, domain string) string {
|
// SendNotify sends notify if IP is changed
|
||||||
|
func SendNotify(configuration *Settings, domain, currentIP string) error {
|
||||||
|
err := SendTelegramNotify(configuration, domain, currentIP)
|
||||||
|
if (err != nil) {
|
||||||
|
log.Println("Send telegram notification with error:", err.Error())
|
||||||
|
}
|
||||||
|
err = SendMailNotify(configuration, domain, currentIP)
|
||||||
|
if (err != nil) {
|
||||||
|
log.Println("Send email notification with error:", err.Error())
|
||||||
|
}
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func buildTemplate(currentIP, domain string, tplsrc string) string {
|
||||||
t := template.New("notification template")
|
t := template.New("notification template")
|
||||||
if _, err := t.Parse(mailTemplate); err != nil {
|
if _, err := t.Parse(tplsrc); err != nil {
|
||||||
log.Println("Failed to parse template")
|
log.Println("Failed to parse template")
|
||||||
return ""
|
return ""
|
||||||
}
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user