diff --git a/cmd/cli/cmd/check.go b/cmd/cli/cmd/check.go index b359e2c..6f08f1b 100644 --- a/cmd/cli/cmd/check.go +++ b/cmd/cli/cmd/check.go @@ -87,12 +87,12 @@ will attend the next session.`, player.Attending = attending log.Default().Printf("Received player response for %s: %s", player.Name, player.Attending) if !player.Gm { - if err := sendEventNotice( - session, - "Received player response", - fmt.Sprintf(`Player %s has responded with %q`, player.Name, player.Attending), - ); err != nil { - log.Default().Printf("ERROR: %s", err) + gmEmail := session.GMEmail() + if gmEmail != "" { + subject, body := session.FormatStatusUpdate(player.Name, attending, "email") + if err := sendNotice(gmEmail, subject, body); err != nil { + log.Default().Printf("ERROR sending GM notification: %s", err) + } } } } else { diff --git a/cmd/web/routes.go b/cmd/web/routes.go index 5983cb3..0ef7e5a 100644 --- a/cmd/web/routes.go +++ b/cmd/web/routes.go @@ -12,6 +12,7 @@ import ( "github.com/golang-jwt/jwt/v4" "github.com/hculpan/areweplaying/cmd/web/templates" "github.com/hculpan/areweplaying/pkg/data" + "github.com/hculpan/areweplaying/pkg/email" ) func routes(r *chi.Mux) { @@ -145,23 +146,32 @@ func GenerateJWTAndStoreInCookie(w http.ResponseWriter, key []byte) error { func updatePlayerAttending(name, attending string, session data.Session) error { for i, p := range session.Players { if p.Name == name { + var newAttending string switch strings.ToLower(attending) { case "yes", "no": - session.Players[i].Attending = strings.ToLower(attending) - return data.PersistSession(session) + newAttending = strings.ToLower(attending) case "toggle": - newAttending := session.Players[i].Attending - switch newAttending { + switch session.Players[i].Attending { case "unknown", "no": newAttending = "yes" - case "yes": + default: newAttending = "no" } - session.Players[i].Attending = newAttending - return data.PersistSession(session) default: return fmt.Errorf("unrecognized attending indicator %q", attending) } + session.Players[i].Attending = newAttending + if err := data.PersistSession(session); err != nil { + return err + } + if gmEmail := session.GMEmail(); gmEmail != "" { + subject, body := session.FormatStatusUpdate(name, newAttending, "the site") + e := email.NewEmail([]string{gmEmail}, []string{}, gmEmail, subject, body) + if err := email.SendEmail(e); err != nil { + log.Default().Printf("ERROR sending GM notification: %s", err) + } + } + return nil } } diff --git a/pkg/data/data.go b/pkg/data/data.go index 03e1cc8..87ccffb 100644 --- a/pkg/data/data.go +++ b/pkg/data/data.go @@ -1,5 +1,10 @@ package data +import ( + "fmt" + "strings" +) + const ( DATE_FORMAT string = "Monday Jan 2, 2006 3:04pm" ) @@ -20,6 +25,45 @@ type Session struct { Password string `json:"password"` } +func (s *Session) GMEmail() string { + for _, p := range s.Players { + if p.Gm { + return p.Email + } + } + return "" +} + +func (s *Session) FormatStatusUpdate(playerName, newStatus, source string) (string, string) { + subject := fmt.Sprintf("Player Status Update: %s → %s", playerName, newStatus) + + var yes, no, unknown int + for _, p := range s.Players { + switch p.Attending { + case "yes": + yes++ + case "no": + no++ + default: + unknown++ + } + } + + var sb strings.Builder + fmt.Fprintf(&sb, "%s has updated their status to %q (via %s).\n\n", playerName, newStatus, source) + fmt.Fprintf(&sb, "Attending: %d | Not attending: %d | No response: %d\n\n", yes, no, unknown) + sb.WriteString("Current player status:\n") + for _, p := range s.Players { + role := "" + if p.Gm { + role = " (GM)" + } + fmt.Fprintf(&sb, " %s%s: %s\n", p.Name, role, p.Attending) + } + + return subject, sb.String() +} + func (s *Session) GetPlayerByEmail(addr string) *Player { for i, p := range s.Players { if addr == p.Email {