package main import ( "fmt" "io" "log" "net/http" "os" "strconv" "strings" "time" "github.com/hexops/gotextdiff" "github.com/hexops/gotextdiff/myers" "github.com/hexops/gotextdiff/span" "github.com/joho/godotenv" "gopkg.in/gomail.v2" ) /* Get a website HTML. */ func getWebsite(url string) []byte { response, err := http.Get(url) if err != nil { log.Fatal("Error: ", err) } defer response.Body.Close() body, err := io.ReadAll(response.Body) if err != nil { log.Fatal("Error reading response body: ", err) } return body } /* Send an email. */ func sendEmail(identity string, username string, password string, host string, recipient []string, port int, body string) { message := gomail.NewMessage() message.SetHeader("From", identity) message.SetHeader("To", strings.Join(recipient, ", ")) message.SetHeader("Subject", "Changes on website") message.SetBody("text/plain", body) dialer := gomail.NewDialer(host, port, username, password) if err := dialer.DialAndSend(message); err != nil { log.Fatal(err) } } /* Environnement variable checker */ func checkEnvVariables(keys []string) { for _, key := range keys { _, i := os.LookupEnv(key) if !i { log.Fatal(key, " doesn't exist.") } } } /* Take a map of string * string and returns a list of its values */ func valuesOfMapStringToListString(from map[string]string) []string { res := make([]string, 0, len(from)) for _, value := range from { res = append(res, value) } return res } func main() { // Loading environment variables godotenv.Load() keys := map[string]string{ "url": "WEBSITE", "smtp_host": "SMTP_HOST", "smtp_from": "SMTP_FROM", "smtp_user": "SMTP_USERNAME", "smtp_pass": "SMTP_PASSWORD", "smtp_port": "SMTP_PORT", "recipient_adress": "RECIPIENT_ADRESS", } checkEnvVariables(valuesOfMapStringToListString(keys)) url := os.Getenv(keys["url"]) smtp_from := os.Getenv(keys["smtp_from"]) smtp_user := os.Getenv(keys["smtp_user"]) smtp_pass := os.Getenv(keys["smtp_pass"]) smtp_host := os.Getenv(keys["smtp_host"]) recipient_adress := os.Getenv(keys["recipient_adress"]) smtp_port, err := strconv.Atoi(os.Getenv(keys["smtp_port"])) if err != nil { log.Fatal("SMTP port is invalid.") } last_bodypage := "" last_name := "" sleepDuration := 24 log.Default().Print("Checking: ", url) log.Default().Print("Running each ", sleepDuration, "h, starting now.") for { bodypage := string(getWebsite(url)) fname := time.Now().Format(time.DateTime) if last_bodypage != "" { edits := myers.ComputeEdits(span.URIFromPath(last_name), last_bodypage, bodypage) diff := fmt.Sprint(gotextdiff.ToUnified(last_name, fname, last_bodypage, edits)) if diff != "" { sendEmail( smtp_from, smtp_user, smtp_pass, smtp_host, strings.Split(recipient_adress, ","), smtp_port, "A changed has been found on the website:\n"+diff, ) } } last_bodypage = bodypage last_name = fname /* log.Default().Print("Next loop in ", sleepDuration, "h.") */ time.Sleep(time.Duration(sleepDuration) * time.Hour) } }