package main import ( "encoding/json" "fmt" "io/ioutil" "net/http" "strconv" "time" ) // SiteAlertConfig is an instance of a site to be monitored // in the config file type SiteAlertConfig struct { URL string `json:"url"` } // Config is the config that we're running with type Config struct { RefreshInterval int `json:"refresh"` Alerts []SiteAlertConfig `json:"alerts"` } var config *Config var allAlerts []Alert func main() { loadConfig() for { fmt.Println("Kicking off refresh.") for i := range allAlerts { fmt.Println("Checking URL: " + allAlerts[i].url + "...") if allAlerts[i].Refresh() { for j := 0; j < 25; j++ { fmt.Println(" CHANGE DETECTED!") } } } fmt.Println("Refresh Completed.") time.Sleep(time.Minute) } } func loadConfig() { fmt.Print("Loading Config...") jsonInp, err := ioutil.ReadFile("config.json") assertError(err) assertError(json.Unmarshal(jsonInp, &config)) t, e := json.Marshal(config) if e != nil { fmt.Println(e) } else { fmt.Println(string(t)) } for i := range config.Alerts { allAlerts = append(allAlerts, *CreateNewAlert(config.Alerts[i].URL)) } fmt.Println("Found " + strconv.Itoa(len(allAlerts)) + " alerts") } // Alert is for monitoring a page type Alert struct { url string contents string response *http.Response err error updateTime time.Time lastChangeContents string lastChangeResponse *http.Response lastChangeError error lastChangeTime time.Time } // CreateNewAlert returns an alert object for url 'u' func CreateNewAlert(u string) *Alert { a := Alert{url: u} a.response, a.err = http.Get(u) return &a } // Refresh refetches the url for the alert and returns // true if it changed. func (a *Alert) Refresh() bool { var changed bool r, e := http.Get(a.url) if e != a.err { a.Update(r, "", e) return true } if body, err := ioutil.ReadAll(r.Body); err == nil { b := string(body) if b != a.contents { changed = true a.Update(r, b, e) } } else { e = err } r.Body.Close() if e != a.err { a.Update(r, "", e) return true } return changed } // Update updates the contents of the alert with the new changes func (a *Alert) Update(r *http.Response, body string, e error) { a.lastChangeContents = a.contents a.lastChangeResponse = a.response a.lastChangeError = a.err a.lastChangeTime = a.updateTime a.contents = body a.response = r a.err = e a.updateTime = time.Now() } func assertError(err error) { if err != nil { panic(err) } }