Add queued email notifications for collaboration events

This commit is contained in:
2026-07-22 08:51:42 -04:00
parent b6d2ded141
commit 09f51d1ef4
20 changed files with 1507 additions and 102 deletions

View File

@@ -38,9 +38,31 @@ type AuthConfig struct {
}
type EmailConfig struct {
SMTPHost string `json:"smtpHost"`
SMTPPort int `json:"smtpPort"`
From string `json:"from"`
// Provider selects the sender implementation. Valid values: "noop",
// "smtp", "postmark". When empty, the loader infers from the other
// fields: PostmarkToken wins, then SMTPHost, then NoOp.
Provider string `json:"provider"`
SMTPHost string `json:"smtpHost"`
SMTPPort int `json:"smtpPort"`
PostmarkToken string `json:"postmarkToken"`
PostmarkAPIURL string `json:"postmarkApiUrl"`
From string `json:"from"`
InstanceName string `json:"instanceName"`
}
// ResolvedProvider returns the concrete provider choice after applying the
// inference rule. Operators can set Provider explicitly to force a choice.
func (e EmailConfig) ResolvedProvider() string {
if e.Provider != "" {
return e.Provider
}
if e.PostmarkToken != "" {
return "postmark"
}
if e.SMTPHost != "" {
return "smtp"
}
return "noop"
}
func Default() Config {
@@ -59,9 +81,10 @@ func Default() Config {
PublicOrigin: "http://localhost:8080",
},
Email: EmailConfig{
SMTPHost: "localhost",
SMTPPort: 1025,
From: "notifications@cairnquire.local",
SMTPHost: "localhost",
SMTPPort: 1025,
From: "notifications@cairnquire.local",
InstanceName: "Cairnquire",
},
LogLevel: "INFO",
}
@@ -87,6 +110,10 @@ func Load() (Config, error) {
overrideString(&cfg.Content.StoreDir, "CAIRNQUIRE_CONTENT_STORE_DIR")
overrideString(&cfg.Auth.PublicOrigin, "CAIRNQUIRE_PUBLIC_ORIGIN")
overrideString(&cfg.Email.SMTPHost, "CAIRNQUIRE_EMAIL_SMTP_HOST")
overrideString(&cfg.Email.PostmarkToken, "CAIRNQUIRE_EMAIL_POSTMARK_TOKEN")
overrideString(&cfg.Email.PostmarkAPIURL, "CAIRNQUIRE_EMAIL_POSTMARK_API_URL")
overrideString(&cfg.Email.Provider, "CAIRNQUIRE_EMAIL_PROVIDER")
overrideString(&cfg.Email.InstanceName, "CAIRNQUIRE_INSTANCE_NAME")
if port := os.Getenv("CAIRNQUIRE_EMAIL_SMTP_PORT"); port != "" {
if p, err := strconv.Atoi(port); err == nil {
cfg.Email.SMTPPort = p