Major refactor to library
This commit is contained in:
169
pkg/whatshooked/whatshooked.go
Normal file
169
pkg/whatshooked/whatshooked.go
Normal file
@@ -0,0 +1,169 @@
|
||||
package whatshooked
|
||||
|
||||
import (
|
||||
"context"
|
||||
|
||||
"git.warky.dev/wdevs/whatshooked/pkg/config"
|
||||
"git.warky.dev/wdevs/whatshooked/pkg/eventlogger"
|
||||
"git.warky.dev/wdevs/whatshooked/pkg/events"
|
||||
"git.warky.dev/wdevs/whatshooked/pkg/handlers"
|
||||
"git.warky.dev/wdevs/whatshooked/pkg/hooks"
|
||||
"git.warky.dev/wdevs/whatshooked/pkg/logging"
|
||||
"git.warky.dev/wdevs/whatshooked/pkg/whatsapp"
|
||||
)
|
||||
|
||||
// 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
|
||||
}
|
||||
|
||||
// NewFromFile creates a WhatsHooked instance from a config file
|
||||
func NewFromFile(configPath string) (*WhatsHooked, error) {
|
||||
cfg, err := config.Load(configPath)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
// Initialize logging from config
|
||||
logging.Init(cfg.LogLevel)
|
||||
|
||||
return newWithConfig(cfg, configPath)
|
||||
}
|
||||
|
||||
// New creates a WhatsHooked instance with programmatic config
|
||||
func New(opts ...Option) (*WhatsHooked, error) {
|
||||
cfg := &config.Config{
|
||||
Server: config.ServerConfig{
|
||||
Host: "localhost",
|
||||
Port: 8080,
|
||||
},
|
||||
Media: config.MediaConfig{
|
||||
DataPath: "./data/media",
|
||||
Mode: "link",
|
||||
},
|
||||
LogLevel: "info",
|
||||
}
|
||||
|
||||
// Apply options
|
||||
for _, opt := range opts {
|
||||
opt(cfg)
|
||||
}
|
||||
|
||||
// Initialize logging from config
|
||||
logging.Init(cfg.LogLevel)
|
||||
|
||||
return newWithConfig(cfg, "")
|
||||
}
|
||||
|
||||
// newWithConfig is the internal constructor
|
||||
func newWithConfig(cfg *config.Config, configPath string) (*WhatsHooked, error) {
|
||||
wh := &WhatsHooked{
|
||||
config: cfg,
|
||||
configPath: configPath,
|
||||
eventBus: events.NewEventBus(),
|
||||
}
|
||||
|
||||
// Initialize WhatsApp manager
|
||||
wh.whatsappMgr = whatsapp.NewManager(
|
||||
wh.eventBus,
|
||||
cfg.Media,
|
||||
cfg,
|
||||
configPath,
|
||||
func(updatedCfg *config.Config) error {
|
||||
if configPath != "" {
|
||||
return config.Save(configPath, updatedCfg)
|
||||
}
|
||||
return nil
|
||||
},
|
||||
)
|
||||
|
||||
// Initialize hook manager
|
||||
wh.hookMgr = hooks.NewManager(wh.eventBus)
|
||||
wh.hookMgr.LoadHooks(cfg.Hooks)
|
||||
wh.hookMgr.Start()
|
||||
|
||||
// Initialize event logger if enabled
|
||||
if cfg.EventLogger.Enabled && len(cfg.EventLogger.Targets) > 0 {
|
||||
logger, err := eventlogger.NewLogger(cfg.EventLogger, cfg.Database)
|
||||
if err == nil {
|
||||
wh.eventLogger = logger
|
||||
wh.eventBus.SubscribeAll(func(event events.Event) {
|
||||
wh.eventLogger.Log(event)
|
||||
})
|
||||
logging.Info("Event logger initialized", "targets", cfg.EventLogger.Targets)
|
||||
} else {
|
||||
logging.Error("Failed to initialize event logger", "error", err)
|
||||
}
|
||||
}
|
||||
|
||||
// Create handlers
|
||||
wh.handlers = handlers.New(wh.whatsappMgr, wh.hookMgr, cfg, configPath)
|
||||
|
||||
return wh, nil
|
||||
}
|
||||
|
||||
// ConnectAll connects to all configured WhatsApp accounts
|
||||
func (wh *WhatsHooked) ConnectAll(ctx context.Context) error {
|
||||
for _, waCfg := range wh.config.WhatsApp {
|
||||
if err := wh.whatsappMgr.Connect(ctx, waCfg); err != nil {
|
||||
logging.Error("Failed to connect to WhatsApp", "account_id", waCfg.ID, "error", err)
|
||||
// Continue connecting to other accounts even if one fails
|
||||
}
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
// Handlers returns the HTTP handlers instance
|
||||
func (wh *WhatsHooked) Handlers() *handlers.Handlers {
|
||||
return wh.handlers
|
||||
}
|
||||
|
||||
// Manager returns the WhatsApp manager
|
||||
func (wh *WhatsHooked) Manager() *whatsapp.Manager {
|
||||
return wh.whatsappMgr
|
||||
}
|
||||
|
||||
// EventBus returns the event bus
|
||||
func (wh *WhatsHooked) EventBus() *events.EventBus {
|
||||
return wh.eventBus
|
||||
}
|
||||
|
||||
// HookManager returns the hook manager
|
||||
func (wh *WhatsHooked) HookManager() *hooks.Manager {
|
||||
return wh.hookMgr
|
||||
}
|
||||
|
||||
// Config returns the configuration
|
||||
func (wh *WhatsHooked) Config() *config.Config {
|
||||
return wh.config
|
||||
}
|
||||
|
||||
// Close shuts down all components gracefully
|
||||
func (wh *WhatsHooked) Close() error {
|
||||
wh.whatsappMgr.DisconnectAll()
|
||||
if wh.eventLogger != nil {
|
||||
return wh.eventLogger.Close()
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
// StartServer starts the built-in HTTP server (convenience method)
|
||||
func (wh *WhatsHooked) StartServer() error {
|
||||
wh.server = NewServer(wh)
|
||||
return wh.server.Start()
|
||||
}
|
||||
|
||||
// StopServer stops the built-in HTTP server
|
||||
func (wh *WhatsHooked) StopServer(ctx context.Context) error {
|
||||
if wh.server != nil {
|
||||
return wh.server.Stop(ctx)
|
||||
}
|
||||
return nil
|
||||
}
|
||||
Reference in New Issue
Block a user