170 lines
4.1 KiB
Go
170 lines
4.1 KiB
Go
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, wh.whatsappMgr)
|
|
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
|
|
}
|