From 5686725d2b890488bdb14064077637cbbb7667f6 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Adam=20Zahradn=C3=ADk?= Date: Fri, 8 Mar 2024 22:50:03 +0100 Subject: [PATCH] ping users that still did not respond --- ping.go | 69 ++++++++++++++++++++++++++++++++++++++++++++++++++++ scheduler.go | 17 +++++++++++++ 2 files changed, 86 insertions(+) create mode 100644 ping.go diff --git a/ping.go b/ping.go new file mode 100644 index 0000000..a695740 --- /dev/null +++ b/ping.go @@ -0,0 +1,69 @@ +package main + +import ( + "encoding/json" + "fmt" + "github.com/charmbracelet/log" + "github.com/slack-go/slack" + bolt "go.etcd.io/bbolt" + "strconv" + "strings" + "time" +) + +const pingCron = "30 12 * * 1,3,5" + +func PingMissingUsers() error { + users := map[string][]string{} + + err := App.db.View(func(tx *bolt.Tx) error { + return tx.Bucket([]byte("messages")).ForEach(func(k, v []byte) error { + var qi QuestionInstance + err := json.Unmarshal(v, &qi) + if err != nil { + return err + } + + err = qi.LoadQuestion() + if err != nil { + return err + } + + ts, err := strconv.ParseFloat(qi.Timestamp, 64) + if err != nil { + log.Error("Cannot parse timestamp for message.", "message", string(k), "err", err) + return nil // we ignore this error as it should not really happen, and it should not break the loop + } + + posted := time.Unix(int64(ts), 0) + if time.Now().Sub(posted) < 24*time.Hour { + return nil + } + + for user, replied := range qi.Responses { + if replied { + users[user] = append(users[user], qi.Question.Channel) + } + } + return nil + }) + }) + if err != nil { + return err + } + + for user, channels := range users { + log.Info("Pinging.", "user", user, "channels", channels) + msg := "Ahoj, zatiaľ si sa nevyjadril/-a do môjho update threadu v týchto kanáloch:\n%s\nNájdi si prosím minútku a doplň odpovede 😇" + var channelMentions []string + for _, channel := range channels { + channelMentions = append(channelMentions, fmt.Sprintf("<#%s>", channel)) + } + + _, _, err := App.slack.PostMessage(user, slack.MsgOptionText(fmt.Sprintf(msg, strings.Join(channelMentions, ", ")), false)) + if err != nil { + log.Error("Could not send ping message.", "user", user, "err", err) + } + } + return nil +} diff --git a/scheduler.go b/scheduler.go index c9bd284..24670ff 100644 --- a/scheduler.go +++ b/scheduler.go @@ -69,6 +69,23 @@ func (s *scheduler) tickPeriodicCheck(now time.Time) { } } +func (s *scheduler) tickPing(now time.Time) { + due, err := s.gron.IsDue(pingCron, now) + if err != nil { + s.logger.Error("Error while checking cron.", "err", err) + return + } + + if due { + s.logger.Info("Pinging all missing users.") + err = PingMissingUsers() + if err != nil { + s.logger.Error("Error while pinging users.", "err", err) + return + } + } +} + func RunScheduler() { defer App.wg.Done()