201 lines
7.0 KiB
Go
201 lines
7.0 KiB
Go
package config
|
|
|
|
import (
|
|
"encoding/json"
|
|
"os"
|
|
)
|
|
|
|
// Config represents the application configuration
|
|
type Config struct {
|
|
Server ServerConfig `json:"server"`
|
|
WhatsApp []WhatsAppConfig `json:"whatsapp"`
|
|
Hooks []Hook `json:"hooks"`
|
|
Database DatabaseConfig `json:"database,omitempty"`
|
|
Media MediaConfig `json:"media"`
|
|
EventLogger EventLoggerConfig `json:"event_logger,omitempty"`
|
|
LogLevel string `json:"log_level"`
|
|
}
|
|
|
|
// ServerConfig holds server-specific configuration
|
|
type ServerConfig struct {
|
|
Host string `json:"host"`
|
|
Port int `json:"port"`
|
|
DefaultCountryCode string `json:"default_country_code,omitempty"`
|
|
Username string `json:"username,omitempty"`
|
|
Password string `json:"password,omitempty"`
|
|
AuthKey string `json:"auth_key,omitempty"`
|
|
TLS TLSConfig `json:"tls,omitempty"`
|
|
}
|
|
|
|
// TLSConfig holds TLS/HTTPS configuration
|
|
type TLSConfig struct {
|
|
Enabled bool `json:"enabled"` // Enable HTTPS
|
|
Mode string `json:"mode"` // "self-signed", "custom", or "autocert"
|
|
CertFile string `json:"cert_file,omitempty"` // Path to certificate file (for custom mode)
|
|
KeyFile string `json:"key_file,omitempty"` // Path to key file (for custom mode)
|
|
|
|
// Self-signed certificate options
|
|
CertDir string `json:"cert_dir,omitempty"` // Directory to store generated certificates
|
|
|
|
// Let's Encrypt / autocert options
|
|
Domain string `json:"domain,omitempty"` // Domain name for Let's Encrypt
|
|
Email string `json:"email,omitempty"` // Email for Let's Encrypt notifications
|
|
CacheDir string `json:"cache_dir,omitempty"` // Cache directory for autocert
|
|
Production bool `json:"production,omitempty"` // Use Let's Encrypt production (default: staging)
|
|
}
|
|
|
|
// WhatsAppConfig holds configuration for a WhatsApp account
|
|
type WhatsAppConfig struct {
|
|
ID string `json:"id"`
|
|
Type string `json:"type"` // "whatsmeow" or "business-api"
|
|
PhoneNumber string `json:"phone_number"`
|
|
SessionPath string `json:"session_path,omitempty"`
|
|
ShowQR bool `json:"show_qr,omitempty"`
|
|
BusinessAPI *BusinessAPIConfig `json:"business_api,omitempty"`
|
|
}
|
|
|
|
// BusinessAPIConfig holds configuration for WhatsApp Business API
|
|
type BusinessAPIConfig struct {
|
|
PhoneNumberID string `json:"phone_number_id"`
|
|
AccessToken string `json:"access_token"`
|
|
BusinessAccountID string `json:"business_account_id,omitempty"`
|
|
APIVersion string `json:"api_version,omitempty"` // Default: v21.0
|
|
WebhookPath string `json:"webhook_path,omitempty"`
|
|
VerifyToken string `json:"verify_token,omitempty"`
|
|
}
|
|
|
|
// Hook represents a registered webhook
|
|
type Hook struct {
|
|
ID string `json:"id"`
|
|
Name string `json:"name"`
|
|
URL string `json:"url"`
|
|
Method string `json:"method"`
|
|
Headers map[string]string `json:"headers,omitempty"`
|
|
Active bool `json:"active"`
|
|
Events []string `json:"events,omitempty"`
|
|
Description string `json:"description,omitempty"`
|
|
}
|
|
|
|
// DatabaseConfig holds database connection information
|
|
type DatabaseConfig struct {
|
|
Type string `json:"type"`
|
|
Host string `json:"host"`
|
|
Port int `json:"port"`
|
|
Username string `json:"username"`
|
|
Password string `json:"password"`
|
|
Database string `json:"database"`
|
|
SQLitePath string `json:"sqlite_path,omitempty"` // Path to SQLite database file
|
|
}
|
|
|
|
// MediaConfig holds media storage and delivery configuration
|
|
type MediaConfig struct {
|
|
DataPath string `json:"data_path"`
|
|
Mode string `json:"mode"` // "base64", "link", or "both"
|
|
BaseURL string `json:"base_url,omitempty"` // Base URL for media links
|
|
}
|
|
|
|
// EventLoggerConfig holds event logging configuration
|
|
type EventLoggerConfig struct {
|
|
Enabled bool `json:"enabled"`
|
|
Targets []string `json:"targets"` // "file", "sqlite", "postgres", "mqtt"
|
|
|
|
// File-based logging
|
|
FileDir string `json:"file_dir,omitempty"` // Base directory for event files
|
|
|
|
// Database logging (uses main Database config for connection)
|
|
TableName string `json:"table_name,omitempty"` // Table name for event logs (default: "event_logs")
|
|
|
|
// MQTT logging
|
|
MQTT MQTTConfig `json:"mqtt,omitempty"` // MQTT broker configuration
|
|
}
|
|
|
|
// MQTTConfig holds MQTT broker configuration
|
|
type MQTTConfig struct {
|
|
Broker string `json:"broker"` // MQTT broker URL (e.g., "tcp://localhost:1883")
|
|
ClientID string `json:"client_id,omitempty"` // Client ID (auto-generated if empty)
|
|
Username string `json:"username,omitempty"` // Username for authentication
|
|
Password string `json:"password,omitempty"` // Password for authentication
|
|
TopicPrefix string `json:"topic_prefix,omitempty"` // Topic prefix (default: "whatshooked")
|
|
QoS int `json:"qos,omitempty"` // Quality of Service (0, 1, or 2; default: 1)
|
|
Retained bool `json:"retained,omitempty"` // Retain messages on broker
|
|
Events []string `json:"events,omitempty"` // Events to publish (empty = all events)
|
|
Subscribe bool `json:"subscribe,omitempty"` // Enable subscription for sending messages
|
|
}
|
|
|
|
// Load reads configuration from a file
|
|
func Load(path string) (*Config, error) {
|
|
data, err := os.ReadFile(path)
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
|
|
var cfg Config
|
|
if err := json.Unmarshal(data, &cfg); err != nil {
|
|
return nil, err
|
|
}
|
|
|
|
// Set defaults
|
|
if cfg.LogLevel == "" {
|
|
cfg.LogLevel = "info"
|
|
}
|
|
if cfg.Server.Host == "" {
|
|
cfg.Server.Host = "localhost"
|
|
}
|
|
if cfg.Server.Port == 0 {
|
|
cfg.Server.Port = 8080
|
|
}
|
|
if cfg.Media.DataPath == "" {
|
|
cfg.Media.DataPath = "./data/media"
|
|
}
|
|
if cfg.Media.Mode == "" {
|
|
cfg.Media.Mode = "link"
|
|
}
|
|
if cfg.EventLogger.FileDir == "" {
|
|
cfg.EventLogger.FileDir = "./data/events"
|
|
}
|
|
if cfg.EventLogger.TableName == "" {
|
|
cfg.EventLogger.TableName = "event_logs"
|
|
}
|
|
if cfg.Database.SQLitePath == "" {
|
|
cfg.Database.SQLitePath = "./data/events.db"
|
|
}
|
|
|
|
// Default WhatsApp account type to whatsmeow for backwards compatibility
|
|
for i := range cfg.WhatsApp {
|
|
if cfg.WhatsApp[i].Type == "" {
|
|
cfg.WhatsApp[i].Type = "whatsmeow"
|
|
}
|
|
// Set default API version for Business API
|
|
if cfg.WhatsApp[i].Type == "business-api" && cfg.WhatsApp[i].BusinessAPI != nil {
|
|
if cfg.WhatsApp[i].BusinessAPI.APIVersion == "" {
|
|
cfg.WhatsApp[i].BusinessAPI.APIVersion = "v21.0"
|
|
}
|
|
}
|
|
}
|
|
|
|
// Set TLS defaults if enabled
|
|
if cfg.Server.TLS.Enabled {
|
|
if cfg.Server.TLS.Mode == "" {
|
|
cfg.Server.TLS.Mode = "self-signed"
|
|
}
|
|
if cfg.Server.TLS.CertDir == "" {
|
|
cfg.Server.TLS.CertDir = "./data/certs"
|
|
}
|
|
if cfg.Server.TLS.CacheDir == "" {
|
|
cfg.Server.TLS.CacheDir = "./data/autocert"
|
|
}
|
|
}
|
|
|
|
return &cfg, nil
|
|
}
|
|
|
|
// Save writes configuration to a file
|
|
func Save(path string, cfg *Config) error {
|
|
data, err := json.MarshalIndent(cfg, "", " ")
|
|
if err != nil {
|
|
return err
|
|
}
|
|
|
|
return os.WriteFile(path, data, 0644)
|
|
}
|