1
0
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:
Timothy 2020-03-21 14:43:10 +08:00 committed by GitHub
commit 1a417c87b3
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
10 changed files with 159 additions and 58 deletions

View File

@ -337,12 +337,14 @@ Update config file and provide your SMTP options, a notification mail will be se
```json
"notify": {
"enabled": true,
"smtp_server": "smtp.example.com",
"smtp_username": "user",
"smtp_password": "password",
"smtp_port": 25,
"send_to": "my_mail@example.com"
"mail": {
"enabled": true,
"smtp_server": "smtp.example.com",
"smtp_username": "user",
"smtp_password": "password",
"smtp_port": 25,
"send_to": "my_mail@example.com"
}
}
```
@ -350,6 +352,22 @@ Notification mail example:
<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
You can also use SOCKS5 proxy, just fill SOCKS5 address to the ```socks5_proxy``` item:

View File

@ -26,11 +26,19 @@
"ip_interface": "eth0",
"socks5_proxy": "",
"notify": {
"enabled": false,
"smtp_server": "",
"smtp_username": "",
"smtp_password": "",
"smtp_port": 25,
"send_to": ""
"telegram": {
"enabled": false,
"bot_api_key": "",
"chat_id": "",
"message_template": ""
},
"mail": {
"enabled": false,
"smtp_server": "",
"smtp_username": "",
"smtp_password": "",
"smtp_port": 25,
"send_to": ""
}
}
}

View File

@ -62,12 +62,9 @@ func (handler *Handler) DomainLoop(domain *godns.Domain, panicChan chan<- godns.
log.Printf("IP updated for subdomain:%s\r\n", subDomain)
}
// Send mail notification if notify is enabled
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 {
log.Printf("Failed to send notification")
}
// Send notification
if err := godns.SendNotify(handler.Configuration, fmt.Sprintf("%s.%s", subDomain, domain.DomainName), currentIP); err != nil {
log.Printf("Failed to send notification")
}
}
}

View File

@ -105,12 +105,9 @@ func (handler *Handler) DomainLoop(domain *godns.Domain, panicChan chan<- godns.
log.Printf("IP mismatch: Current(%+v) vs Cloudflare(%+v)\r\n", currentIP, rec.IP)
handler.updateRecord(rec, currentIP)
// Send mail notification if notify is enabled
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 {
log.Println("Failed to send notification")
}
// Send notification
if err := godns.SendNotify(handler.Configuration, rec.Name, currentIP); err != nil {
log.Println("Failed to send notification")
}
} else {
log.Printf("Record OK: %+v - %+v\r\n", rec.Name, rec.IP)

View File

@ -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)
handler.UpdateIP(domainID, subDomainID, subDomain, currentIP)
// Send mail notification if notify is enabled
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 {
log.Println("Failed to send notification")
}
// Send notification
if err := godns.SendNotify(handler.Configuration, fmt.Sprintf("%s.%s", subDomain, domain.DomainName), currentIP); err != nil {
log.Println("Failed to send notification")
}
} else {
log.Printf("%s.%s Current IP is same as domain IP, no need to update...\n", subDomain, domain.DomainName)
}

View File

@ -79,12 +79,9 @@ func (handler *Handler) DomainLoop(domain *godns.Domain, panicChan chan<- godns.
log.Print("IP updated to:", currentIP)
}
// Send mail notification if notify is enabled
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 {
log.Println("Failed to send notification")
}
// Send notification
if err := godns.SendNotify(handler.Configuration, fmt.Sprintf("%s.%s", subDomain, domain.DomainName), currentIP); err != nil {
log.Println("Failed to send notification")
}
}
}

View File

@ -58,12 +58,9 @@ func (handler *Handler) DomainLoop(domain *godns.Domain, panicChan chan<- godns.
log.Printf("%s.%s Start to update record IP...\n", subDomain, domain.DomainName)
handler.UpdateIP(domain.DomainName, subDomain, currentIP)
// Send mail notification if notify is enabled
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 {
log.Println("Failed to send notification")
}
// Send notification
if err := godns.SendNotify(handler.Configuration, fmt.Sprintf("%s.%s", subDomain, domain.DomainName), currentIP); err != nil {
log.Println("Failed to send notification")
}
}
}

View File

@ -57,12 +57,9 @@ func (handler *Handler) DomainLoop(domain *godns.Domain, panicChan chan<- godns.
log.Printf("%s.%s Start to update record IP...\n", subDomain, domain.DomainName)
handler.UpdateIP(domain.DomainName, subDomain, currentIP)
// Send mail notification if notify is enabled
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 {
log.Println("Failed to send notification")
}
// Send notification
if err := godns.SendNotify(handler.Configuration, fmt.Sprintf("%s.%s", subDomain, domain.DomainName), currentIP); err != nil {
log.Println("Failed to send notification")
}
}
}

View File

@ -12,8 +12,16 @@ type Domain struct {
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
type Notify struct {
type MailNotify struct {
Enabled bool `json:"enabled"`
SMTPServer string `json:"smtp_server"`
SMTPUsername string `json:"smtp_username"`
@ -22,6 +30,12 @@ type Notify struct {
SendTo string `json:"send_to"`
}
// Notify struct
type Notify struct {
Telegram TelegramNotify `json:"telegram"`
Mail MailNotify `json:"mail"`
}
// Settings struct
type Settings struct {
Provider string `json:"provider"`

View File

@ -2,7 +2,9 @@ package godns
import (
"bytes"
"encoding/json"
"errors"
"fmt"
"html/template"
"io/ioutil"
"log"
@ -234,30 +236,108 @@ func CheckSettings(config *Settings) error {
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
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.SetHeader("From", configuration.Notify.SMTPUsername)
m.SetHeader("To", configuration.Notify.SendTo)
m.SetHeader("From", configuration.Notify.Mail.SMTPUsername)
m.SetHeader("To", configuration.Notify.Mail.SendTo)
m.SetHeader("Subject", "GoDNS Notification")
log.Println("currentIP:", currentIP)
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 .
if err := d.DialAndSend(m); err != nil {
log.Println("Send email notification with error:", err.Error())
return err
}
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")
if _, err := t.Parse(mailTemplate); err != nil {
if _, err := t.Parse(tplsrc); err != nil {
log.Println("Failed to parse template")
return ""
}