package alerts import ( "context" "encoding/json" "log/slog" "sync" "text/template" "git.sr.ht/~ashkeel/strimertul/database" "git.sr.ht/~ashkeel/strimertul/log" "git.sr.ht/~ashkeel/strimertul/twitch/eventsub" templater "git.sr.ht/~ashkeel/strimertul/twitch/template" ) type ( templateCache map[string]*template.Template templateCacheMap map[templateType]templateCache ) type templateType string const ( templateTypeSubscription templateType = "subscription" templateTypeFollow templateType = "follow" templateTypeRaid templateType = "raid" templateTypeCheer templateType = "cheer" templateTypeGift templateType = "gift" ) type Module struct { Config Config ctx context.Context db database.Database logger *slog.Logger templater templater.Engine templates templateCacheMap pendingMux sync.Mutex pendingSubs map[string]subMixedEvent } func Setup(ctx context.Context, db database.Database, logger *slog.Logger, templater templater.Engine) *Module { mod := &Module{ ctx: ctx, db: db, logger: logger, templater: templater, pendingMux: sync.Mutex{}, pendingSubs: make(map[string]subMixedEvent), } // Load config from database if err := db.GetJSON(ConfigKey, &mod.Config); err != nil { logger.Debug("Config load error", log.Error(err)) mod.Config = Config{} // Save empty config err = db.PutJSON(ConfigKey, mod.Config) if err != nil { logger.Warn("Could not save default config for bot alerts", log.Error(err)) } } mod.compileTemplates() if err := db.SubscribeKeyContext(ctx, ConfigKey, func(value string) { err := json.Unmarshal([]byte(value), &mod.Config) if err != nil { logger.Warn("Error loading alert config", log.Error(err)) } else { logger.Info("Reloaded alert config") } mod.compileTemplates() }); err != nil { logger.Error("Could not set-up bot alert reload subscription", log.Error(err)) } if err := db.SubscribePrefixContext(ctx, mod.onEventSubEvent, eventsub.EventKeyPrefix); err != nil { logger.Error("Could not setup twitch alert subscription", log.Error(err)) } logger.Debug("Loaded bot alerts") return mod }