mirror of
				https://github.com/taigrr/godns
				synced 2025-01-18 04:03:25 -08:00 
			
		
		
		
	Add support to telegram notification
This commit is contained in:
		
							parent
							
								
									e5f9076259
								
							
						
					
					
						commit
						f5a793a907
					
				
							
								
								
									
										30
									
								
								README.md
									
									
									
									
									
								
							
							
						
						
									
										30
									
								
								README.md
									
									
									
									
									
								
							| @ -337,12 +337,14 @@ Update config file and provide your SMTP options, a notification mail will be se | |||||||
| 
 | 
 | ||||||
| ```json | ```json | ||||||
|   "notify": { |   "notify": { | ||||||
|     "enabled": true, |     "mail": { | ||||||
|     "smtp_server": "smtp.example.com", |       "enabled": true, | ||||||
|     "smtp_username": "user", |       "smtp_server": "smtp.example.com", | ||||||
|     "smtp_password": "password", |       "smtp_username": "user", | ||||||
|     "smtp_port": 25, |       "smtp_password": "password", | ||||||
|     "send_to": "my_mail@example.com" |       "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" />   | <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,11 +26,19 @@ | |||||||
|   "ip_interface": "eth0", |   "ip_interface": "eth0", | ||||||
|   "socks5_proxy": "", |   "socks5_proxy": "", | ||||||
|   "notify": { |   "notify": { | ||||||
|     "enabled": false, |     "telegram": { | ||||||
|     "smtp_server": "", |       "enabled": false, | ||||||
|     "smtp_username": "", |       "bot_api_key": "", | ||||||
|     "smtp_password": "", |       "chat_id": "", | ||||||
|     "smtp_port": 25, |       "message_template": "" | ||||||
|     "send_to": "" |     }, | ||||||
|  |     "mail": { | ||||||
|  |       "enabled": false, | ||||||
|  |       "smtp_server": "", | ||||||
|  |       "smtp_username": "", | ||||||
|  |       "smtp_password": "", | ||||||
|  |       "smtp_port": 25, | ||||||
|  |       "send_to": "" | ||||||
|  |     } | ||||||
|   } |   } | ||||||
| } | } | ||||||
|  | |||||||
| @ -62,12 +62,9 @@ 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 { | 				if err := godns.SendNotify(handler.Configuration, fmt.Sprintf("%s.%s", subDomain, domain.DomainName), currentIP); err != nil { | ||||||
| 					log.Print("Sending notification to:", handler.Configuration.Notify.SendTo) | 					log.Printf("Failed to send notification") | ||||||
| 					if err := godns.SendNotify(handler.Configuration, fmt.Sprintf("%s.%s", subDomain, domain.DomainName), currentIP); err != nil { |  | ||||||
| 						log.Printf("Failed to send notification") |  | ||||||
| 					} |  | ||||||
| 				} | 				} | ||||||
| 			} | 			} | ||||||
| 		} | 		} | ||||||
|  | |||||||
| @ -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) | 						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 { | 						if err := godns.SendNotify(handler.Configuration, rec.Name, currentIP); err != nil { | ||||||
| 							log.Print("Sending notification to:", handler.Configuration.Notify.SendTo) | 							log.Println("Failed to send notification") | ||||||
| 							if err := godns.SendNotify(handler.Configuration, rec.Name, currentIP); err != nil { |  | ||||||
| 								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 { | 					if err := godns.SendNotify(handler.Configuration, fmt.Sprintf("%s.%s", subDomain, domain.DomainName), currentIP); err != nil { | ||||||
| 						log.Print("Sending notification to:", handler.Configuration.Notify.SendTo) | 						log.Println("Failed to 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 { | 				} 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,12 +79,9 @@ 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 { | 				if err := godns.SendNotify(handler.Configuration, fmt.Sprintf("%s.%s", subDomain, domain.DomainName), currentIP); err != nil { | ||||||
| 					log.Print("Sending notification to:", handler.Configuration.Notify.SendTo) | 					log.Println("Failed to send notification") | ||||||
| 					if err := godns.SendNotify(handler.Configuration, fmt.Sprintf("%s.%s", subDomain, domain.DomainName), currentIP); err != nil { |  | ||||||
| 						log.Println("Failed to send notification") |  | ||||||
| 					} |  | ||||||
| 				} | 				} | ||||||
| 			} | 			} | ||||||
| 		} | 		} | ||||||
|  | |||||||
| @ -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) | 				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 { | 				if err := godns.SendNotify(handler.Configuration, fmt.Sprintf("%s.%s", subDomain, domain.DomainName), currentIP); err != nil { | ||||||
| 					log.Print("Sending notification to:", handler.Configuration.Notify.SendTo) | 					log.Println("Failed to send notification") | ||||||
| 					if err := godns.SendNotify(handler.Configuration, fmt.Sprintf("%s.%s", subDomain, domain.DomainName), currentIP); err != nil { |  | ||||||
| 						log.Println("Failed to send notification") |  | ||||||
| 					} |  | ||||||
| 				} | 				} | ||||||
| 			} | 			} | ||||||
| 		} | 		} | ||||||
|  | |||||||
| @ -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) | 				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 { | 				if err := godns.SendNotify(handler.Configuration, fmt.Sprintf("%s.%s", subDomain, domain.DomainName), currentIP); err != nil { | ||||||
| 					log.Print("Sending notification to:", handler.Configuration.Notify.SendTo) | 					log.Println("Failed to send notification") | ||||||
| 					if err := godns.SendNotify(handler.Configuration, fmt.Sprintf("%s.%s", subDomain, domain.DomainName), currentIP); err != nil { |  | ||||||
| 						log.Println("Failed to send notification") |  | ||||||
| 					} |  | ||||||
| 				} | 				} | ||||||
| 			} | 			} | ||||||
| 		} | 		} | ||||||
|  | |||||||
							
								
								
									
										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