diff --git a/bin/DDNSUpdater.exe b/bin/DDNSUpdater.exe index 1c1302f..062d665 100644 Binary files a/bin/DDNSUpdater.exe and b/bin/DDNSUpdater.exe differ diff --git a/config.json b/config.json index d98571c..d1c7a8d 100644 --- a/config.json +++ b/config.json @@ -1,4 +1,5 @@ { - "url": "https://triztech.pro/cpanelwebcall/TOKEN", - "interval_minutes": 300 + "update_url": "https://triztech.pro/cpanelwebcall/TOKEN", + "check_interval_seconds": 30, + "ip_check_url": "https://api.ipify.org" } diff --git a/main.go b/main.go index 96ee82a..bb05e3e 100644 --- a/main.go +++ b/main.go @@ -1,62 +1,97 @@ package main import ( - "encoding/json" - "fmt" - "io/ioutil" - "net/http" - "os" - "time" + "encoding/json" + "fmt" + "io/ioutil" + "net/http" + "os" + "strings" + "time" ) type Config struct { - URL string `json:"url"` - IntervalMins int `json:"interval_minutes"` + UpdateURL string `json:"update_url"` + CheckIntervalSecs int `json:"check_interval_seconds"` + IPCheckURL string `json:"ip_check_url"` } -// read config.json func loadConfig(path string) (*Config, error) { - file, err := ioutil.ReadFile(path) - if err != nil { - return nil, err - } - var cfg Config - err = json.Unmarshal(file, &cfg) - if err != nil { - return nil, err - } - return &cfg, nil + data, err := ioutil.ReadFile(path) + if err != nil { + return nil, err + } + var cfg Config + err = json.Unmarshal(data, &cfg) + if err != nil { + return nil, err + } + return &cfg, nil } -func updateDDNS(url string) { - resp, err := http.Get(url) - if err != nil { - fmt.Println("Error calling DDNS URL:", err) - return - } - defer resp.Body.Close() +func getPublicIP(ipURL string) (string, error) { + resp, err := http.Get(ipURL) + if err != nil { + return "", err + } + defer resp.Body.Close() - if resp.StatusCode == http.StatusOK { - fmt.Println(time.Now(), "DDNS updated successfully") - } else { - fmt.Println(time.Now(), "Failed to update DDNS, status code:", resp.StatusCode) - } + body, err := ioutil.ReadAll(resp.Body) + if err != nil { + return "", err + } + + return strings.TrimSpace(string(body)), nil +} + +func updateDDNS(url string) error { + resp, err := http.Get(url) + if err != nil { + return err + } + defer resp.Body.Close() + + if resp.StatusCode != http.StatusOK { + return fmt.Errorf("failed, status code %d", resp.StatusCode) + } + return nil } func main() { - cfg, err := loadConfig("config.json") - if err != nil { - fmt.Println("Failed to load config:", err) - os.Exit(1) - } + cfg, err := loadConfig("config.json") + if err != nil { + fmt.Println("Failed to load config:", err) + os.Exit(1) + } - ticker := time.NewTicker(time.Duration(cfg.IntervalMins) * time.Minute) - defer ticker.Stop() + //var lastIP string + lastIP, err := getPublicIP(cfg.IPCheckURL) + if err != nil { + fmt.Println("Error getting intial public IP:", err) + lastIP = "" + } else { + fmt.Println(time.Now(), "Starting with current IP:", lastIP) + } - // run immediately once - updateDDNS(cfg.URL) + ticker := time.NewTicker(time.Duration(cfg.CheckIntervalSecs) * time.Second) + defer ticker.Stop() - for range ticker.C { - updateDDNS(cfg.URL) - } + for { + ip, err := getPublicIP(cfg.IPCheckURL) + if err != nil { + fmt.Println("Error getting public IP:", err) + } else if ip != lastIP { + fmt.Println(time.Now(), "IP changed to", ip) + if err := updateDDNS(cfg.UpdateURL); err != nil { + fmt.Println("Failed to update DDNS:", err) + } else { + fmt.Println(time.Now(), "DDNS updated successfully") + lastIP = ip + } + } else { + fmt.Println(time.Now(), "IP unchanged:", ip) + } + + <-ticker.C + } }