feat(cache): 🎉 add message caching functionality
Some checks failed
CI / Test (1.23) (push) Failing after -27m1s
CI / Lint (push) Successful in -26m31s
CI / Build (push) Successful in -27m3s
CI / Test (1.22) (push) Failing after -24m58s

* Implement MessageCache to store events when no webhooks are available.
* Add configuration options for enabling cache, setting data path, max age, and max events.
* Create API endpoints for managing cached events, including listing, replaying, and deleting.
* Integrate caching into the hooks manager to store events when no active webhooks are found.
* Enhance logging for better traceability of cached events and operations.
This commit is contained in:
Hein
2026-01-30 16:00:34 +02:00
parent 3901bbb668
commit c4d974d6ce
9 changed files with 1535 additions and 30 deletions

View File

@@ -232,11 +232,21 @@ func (s *Server) setupRoutes() *http.ServeMux {
// Business API webhooks (no auth - Meta validates via verify_token)
mux.HandleFunc("/webhooks/whatsapp/", h.BusinessAPIWebhook)
// Message cache management (with auth)
mux.HandleFunc("/api/cache", h.Auth(h.GetCachedEvents)) // GET - list cached events
mux.HandleFunc("/api/cache/stats", h.Auth(h.GetCacheStats)) // GET - cache statistics
mux.HandleFunc("/api/cache/replay", h.Auth(h.ReplayCachedEvents)) // POST - replay all
mux.HandleFunc("/api/cache/event", h.Auth(h.GetCachedEvent)) // GET with ?id=
mux.HandleFunc("/api/cache/event/replay", h.Auth(h.ReplayCachedEvent)) // POST with ?id=
mux.HandleFunc("/api/cache/event/delete", h.Auth(h.DeleteCachedEvent)) // DELETE with ?id=
mux.HandleFunc("/api/cache/clear", h.Auth(h.ClearCache)) // DELETE with ?confirm=true
logging.Info("HTTP server endpoints configured",
"health", "/health",
"hooks", "/api/hooks",
"accounts", "/api/accounts",
"send", "/api/send",
"cache", "/api/cache",
"qr", "/api/qr")
return mux

View File

@@ -2,7 +2,9 @@ package whatshooked
import (
"context"
"time"
"git.warky.dev/wdevs/whatshooked/pkg/cache"
"git.warky.dev/wdevs/whatshooked/pkg/config"
"git.warky.dev/wdevs/whatshooked/pkg/eventlogger"
"git.warky.dev/wdevs/whatshooked/pkg/events"
@@ -14,14 +16,15 @@ import (
// WhatsHooked is the main library instance
type WhatsHooked struct {
config *config.Config
configPath string
eventBus *events.EventBus
whatsappMgr *whatsapp.Manager
hookMgr *hooks.Manager
eventLogger *eventlogger.Logger
handlers *handlers.Handlers
server *Server // Optional built-in server
config *config.Config
configPath string
eventBus *events.EventBus
whatsappMgr *whatsapp.Manager
hookMgr *hooks.Manager
eventLogger *eventlogger.Logger
messageCache *cache.MessageCache
handlers *handlers.Handlers
server *Server // Optional built-in server
}
// NewFromFile creates a WhatsHooked instance from a config file
@@ -84,8 +87,24 @@ func newWithConfig(cfg *config.Config, configPath string) (*WhatsHooked, error)
},
)
// Initialize message cache
cacheConfig := cache.Config{
Enabled: cfg.MessageCache.Enabled,
DataPath: cfg.MessageCache.DataPath,
MaxAge: time.Duration(cfg.MessageCache.MaxAgeDays) * 24 * time.Hour,
MaxEvents: cfg.MessageCache.MaxEvents,
}
messageCache, err := cache.NewMessageCache(cacheConfig)
if err != nil {
logging.Error("Failed to initialize message cache", "error", err)
// Continue without cache rather than failing
messageCache = &cache.MessageCache{}
}
wh.messageCache = messageCache
// Initialize hook manager
wh.hookMgr = hooks.NewManager(wh.eventBus)
wh.hookMgr = hooks.NewManager(wh.eventBus, wh.messageCache)
wh.hookMgr.LoadHooks(cfg.Hooks)
wh.hookMgr.Start()