areweplaying/pkg/data/data.go
Harry Culpan 7370d1291e Add noon-of-gameday GM status email via awp-cli gameday-notice
Adds a cron-driven CLI command that emails the GM a player attendance
summary at noon on the session date, skipping automatically if the
game was canceled or today isn't game day, and tracking last-sent
date so it won't double-send.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
2026-07-11 19:18:02 -04:00

106 lines
2.3 KiB
Go

package data
import (
"fmt"
"strings"
)
const (
DATE_FORMAT string = "Monday Jan 2, 2006 3:04pm"
)
type Player struct {
Name string `json:"name"`
Attending string `json:"attending"`
ToggleUrl string `json:"-"`
Email string `json:"email"`
Gm bool `json:"gm"`
}
type Session struct {
Date string `json:"date"`
Players []Player `json:"players"`
IncrementDays int `json:"inc_days"`
Status string `json:"status"`
Password string `json:"password"`
LastNoticeSentDate string `json:"last_notice_sent_date,omitempty"`
}
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) FormatGameDayNotice() (string, string) {
subject := fmt.Sprintf("Game Day Status Check: %s", s.Date)
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, "Today is game day (%s). Here is the current player status.\n\n", s.Date)
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 {
return &s.Players[i]
}
}
return nil
}