diff --git a/main.go b/main.go index 8a4f3d3..428512c 100644 --- a/main.go +++ b/main.go @@ -13,7 +13,35 @@ func WaitUntilNextHour() { time.Sleep(dur) } +func WaitUntilNextMinute() { + now := time.Now() + dur := now.Truncate(time.Minute).Add(time.Minute).Sub(now) + log.Println("sleeping for", dur.Round(time.Second)) + time.Sleep(dur) +} + +func CheckNotifications() { + var prevHasNewNotes bool + for { + hasNewNotes, err := FetchHasNewNotes() + if err != nil { + SendErrorToDiscord(err) + } else { + if !prevHasNewNotes && hasNewNotes { + // only send embed on "rising edge" + SendNotificationsEmbedToDiscord() + log.Println("Forwarded to monitoring") + } else if hasNewNotes { + log.Println("Already forwarded") + } + } + prevHasNewNotes = hasNewNotes + WaitUntilNextMinute() + } +} + func main() { + go CheckNotifications() for { stories, err := FetchHackerNewsTopStories() diff --git a/sn.go b/sn.go index 5f3c504..7f83ab3 100644 --- a/sn.go +++ b/sn.go @@ -95,6 +95,13 @@ type ItemsResponse struct { } `json:"data"` } +type HasNewNotesResponse struct { + Errors []GraphQLError `json:"errors"` + Data struct { + HasNewNotes bool `json:"hasNewNotes"` + } `json:"data"` +} + var ( StackerNewsUrl = "https://stacker.news" SnApiUrl = "https://stacker.news/api/graphql" @@ -318,3 +325,58 @@ func SendStackerNewsEmbedToDiscord(title string, id int) { } SendEmbedToDiscord(&embed) } + +func SendNotificationsEmbedToDiscord() { + Timestamp := time.Now().Format(time.RFC3339) + color := 0xffc107 + embed := discordgo.MessageEmbed{ + Title: "new notifications", + URL: "https://stacker.news/hn/posts", + Color: color, + Footer: &discordgo.MessageEmbedFooter{ + Text: "Stacker News", + IconURL: "https://stacker.news/favicon-notify.png", + }, + Timestamp: Timestamp, + } + SendEmbedToDiscord(&embed) +} + +func FetchHasNewNotes() (bool, error) { + log.Println("Checking notifications ...") + + body := GraphQLPayload{ + Query: ` + { + hasNewNotes + }`, + } + resp, err := MakeStackerNewsRequest(body) + if err != nil { + return false, err + } + defer resp.Body.Close() + + var hasNewNotesResp HasNewNotesResponse + err = json.NewDecoder(resp.Body).Decode(&hasNewNotesResp) + if err != nil { + err = fmt.Errorf("error decoding SN hasNewNotes: %w", err) + return false, err + } + err = CheckForErrors(hasNewNotesResp.Errors) + if err != nil { + return false, err + } + + hasNewNotes := hasNewNotesResp.Data.HasNewNotes + + msg := "Checking notifications ... OK - " + if hasNewNotes { + msg += "NEW" + } else { + msg += "NONE" + } + log.Println(msg) + + return hasNewNotes, nil +}