Files
whatshooked/cmd/server/main.go
Hein f9773bd07f
Some checks failed
CI / Test (1.23) (push) Failing after -22m46s
CI / Test (1.22) (push) Failing after -22m32s
CI / Build (push) Failing after -23m30s
CI / Lint (push) Failing after -23m12s
refactor(API): Relspect integration
2026-02-05 13:39:43 +02:00

115 lines
3.2 KiB
Go

package main
import (
"context"
"flag"
"fmt"
"os"
"os/signal"
"path/filepath"
"syscall"
"time"
"git.warky.dev/wdevs/whatshooked/pkg/logging"
"git.warky.dev/wdevs/whatshooked/pkg/whatshooked"
)
var (
configPath = flag.String("config", "", "Path to configuration file (optional, defaults to user home directory)")
)
// resolveConfigPath determines the config file path to use
// Priority: 1) provided path (if exists), 2) config.json in current dir, 3) .whatshooked/config.json in user home
func resolveConfigPath(providedPath string) (string, error) {
// If a path was explicitly provided, check if it exists
if providedPath != "" {
if _, err := os.Stat(providedPath); err == nil {
return providedPath, nil
}
// Directory doesn't exist, fall through to default locations
fmt.Fprintf(os.Stderr, "Provided config path directory does not exist, using default locations: %s\n", providedPath)
}
// Check for config.json in current directory
currentDirConfig := "config.json"
if _, err := os.Stat(currentDirConfig); err == nil {
return currentDirConfig, nil
}
// Fall back to user home directory
homeDir, err := os.UserHomeDir()
if err != nil {
return "", fmt.Errorf("failed to get user home directory: %w", err)
}
// Create .whatshooked directory if it doesn't exist
configDir := filepath.Join(homeDir, ".whatshooked")
if err := os.MkdirAll(configDir, 0755); err != nil {
return "", fmt.Errorf("failed to create config directory: %w", err)
}
return filepath.Join(configDir, "config.json"), nil
}
func main() {
flag.Parse()
// Resolve config path
cfgPath, err := resolveConfigPath(*configPath)
if err != nil {
fmt.Fprintf(os.Stderr, "Failed to resolve config path: %v\n", err)
os.Exit(1)
}
// Create WhatsHooked instance from config file
wh, err := whatshooked.NewFromFile(cfgPath)
if err != nil {
fmt.Fprintf(os.Stderr, "Failed to initialize WhatsHooked from %s: %v\n", cfgPath, err)
os.Exit(1)
}
logging.Info("Starting WhatsHooked server", "config_path", cfgPath)
// Create context for initialization
ctx := context.Background()
// Start the ResolveSpec server
// This serves both the WhatsApp API and the Admin UI
if err := wh.StartServer(ctx); err != nil {
logging.Error("Failed to start server", "error", err)
os.Exit(1)
}
// Connect to WhatsApp accounts after a brief delay
go func() {
time.Sleep(500 * time.Millisecond) // Give server a moment to start
logging.Info("Server ready, connecting to WhatsApp accounts")
if err := wh.ConnectAll(context.Background()); err != nil {
logging.Error("Failed to connect to WhatsApp accounts", "error", err)
}
}()
// Wait for interrupt signal
sigChan := make(chan os.Signal, 1)
signal.Notify(sigChan, os.Interrupt, syscall.SIGTERM)
<-sigChan
logging.Info("Shutting down server")
// Graceful shutdown
shutdownCtx, cancel := context.WithTimeout(context.Background(), 10*time.Second)
defer cancel()
// Stop server
if err := wh.StopServer(shutdownCtx); err != nil {
logging.Error("Error stopping server", "error", err)
}
// Close WhatsHooked (disconnects WhatsApp, closes event logger, etc.)
if err := wh.Close(); err != nil {
logging.Error("Error closing WhatsHooked", "error", err)
}
logging.Info("Server stopped")
}