From a87783d8c6bac2c250df454cc311e13569f84ebd Mon Sep 17 00:00:00 2001 From: Tim Van Wassenhove Date: Thu, 19 Feb 2026 09:23:41 +0100 Subject: [PATCH] feat: add Spotify, management, and ZeroConf CLI flags --- cmd/soundtouch-service/main.go | 65 ++++++++++++++++++++++++++++++++++ pkg/service/handlers/server.go | 42 ++++++++++++++++++++++ 2 files changed, 107 insertions(+) diff --git a/cmd/soundtouch-service/main.go b/cmd/soundtouch-service/main.go index db86c0c..df987fb 100644 --- a/cmd/soundtouch-service/main.go +++ b/cmd/soundtouch-service/main.go @@ -155,6 +155,45 @@ func main() { Value: ":53", EnvVars: []string{"DNS_BIND_ADDR"}, }, + &cli.StringFlag{ + Name: "spotify-client-id", + Usage: "Spotify OAuth client ID", + EnvVars: []string{"SPOTIFY_CLIENT_ID"}, + }, + &cli.StringFlag{ + Name: "spotify-client-secret", + Usage: "Spotify OAuth client secret", + EnvVars: []string{"SPOTIFY_CLIENT_SECRET"}, + }, + &cli.StringFlag{ + Name: "spotify-redirect-uri", + Usage: "Spotify OAuth redirect URI", + Value: "ueberboese-login://spotify", + EnvVars: []string{"SPOTIFY_REDIRECT_URI"}, + }, + &cli.StringFlag{ + Name: "mgmt-username", + Usage: "Management API username for HTTP Basic Auth", + Value: "admin", + EnvVars: []string{"MGMT_USERNAME"}, + }, + &cli.StringFlag{ + Name: "mgmt-password", + Usage: "Management API password for HTTP Basic Auth", + Value: "change_me!", + EnvVars: []string{"MGMT_PASSWORD"}, + }, + &cli.BoolFlag{ + Name: "zeroconf-primer-enabled", + Usage: "Enable ZeroConf Spotify primer for speakers", + Value: true, + EnvVars: []string{"ZEROCONF_PRIMER_ENABLED"}, + }, + &cli.StringFlag{ + Name: "base-url", + Usage: "External base URL for OAuth callbacks behind reverse proxy", + EnvVars: []string{"BASE_URL"}, + }, }, Action: func(c *cli.Context) error { config := loadConfig(c) @@ -184,6 +223,10 @@ func main() { server.SetVersionInfo(version, commit, date) server.SetDiscoverySettings(config.discoveryInterval, persisted.DiscoveryEnabled) server.SetDNSSettings(persisted.DNSEnabled, persisted.DNSUpstream, persisted.DNSBindAddr) + server.SetSpotifyConfig(config.spotifyClientID, config.spotifyClientSecret, config.spotifyRedirectURI) + server.SetMgmtConfig(config.mgmtUsername, config.mgmtPassword) + server.SetZeroconfEnabled(config.zeroconfEnabled) + server.SetBaseURL(config.baseURL) // Load and set initial DNS discoveries dnsDiscoveries, err := ds.LoadDNSDiscoveries() @@ -298,6 +341,13 @@ type serviceConfig struct { dnsBind string discoveryInterval time.Duration domains []string + spotifyClientID string + spotifyClientSecret string + spotifyRedirectURI string + mgmtUsername string + mgmtPassword string + zeroconfEnabled bool + baseURL string } func loadConfig(c *cli.Context) serviceConfig { @@ -356,6 +406,14 @@ func loadConfig(c *cli.Context) serviceConfig { discoveryInterval = 5 * time.Minute } + spotifyClientID := c.String("spotify-client-id") + spotifyClientSecret := c.String("spotify-client-secret") + spotifyRedirectURI := c.String("spotify-redirect-uri") + mgmtUsername := c.String("mgmt-username") + mgmtPassword := c.String("mgmt-password") + zeroconfEnabled := c.Bool("zeroconf-primer-enabled") + baseURL := c.String("base-url") + return serviceConfig{ port: port, bindAddr: bindAddr, @@ -374,6 +432,13 @@ func loadConfig(c *cli.Context) serviceConfig { dnsBind: dnsBind, discoveryInterval: discoveryInterval, domains: domains, + spotifyClientID: spotifyClientID, + spotifyClientSecret: spotifyClientSecret, + spotifyRedirectURI: spotifyRedirectURI, + mgmtUsername: mgmtUsername, + mgmtPassword: mgmtPassword, + zeroconfEnabled: zeroconfEnabled, + baseURL: baseURL, } } diff --git a/pkg/service/handlers/server.go b/pkg/service/handlers/server.go index 30f5234..3dd25e6 100644 --- a/pkg/service/handlers/server.go +++ b/pkg/service/handlers/server.go @@ -40,6 +40,13 @@ type Server struct { Version string Commit string Date string + mgmtUsername string + mgmtPassword string + spotifyClientID string + spotifyClientSecret string + spotifyRedirectURI string + zeroconfEnabled bool + baseURL string } // NewServer creates a new SoundTouch service server. @@ -215,6 +222,41 @@ func (s *Server) SetRecorder(r *proxy.Recorder) { } } +// SetSpotifyConfig sets the Spotify OAuth configuration. +func (s *Server) SetSpotifyConfig(clientID, clientSecret, redirectURI string) { + s.mu.Lock() + defer s.mu.Unlock() + + s.spotifyClientID = clientID + s.spotifyClientSecret = clientSecret + s.spotifyRedirectURI = redirectURI +} + +// SetMgmtConfig sets the management API authentication credentials. +func (s *Server) SetMgmtConfig(username, password string) { + s.mu.Lock() + defer s.mu.Unlock() + + s.mgmtUsername = username + s.mgmtPassword = password +} + +// SetZeroconfEnabled sets whether ZeroConf Spotify primer is enabled. +func (s *Server) SetZeroconfEnabled(enabled bool) { + s.mu.Lock() + defer s.mu.Unlock() + + s.zeroconfEnabled = enabled +} + +// SetBaseURL sets the external base URL for OAuth callbacks. +func (s *Server) SetBaseURL(baseURL string) { + s.mu.Lock() + defer s.mu.Unlock() + + s.baseURL = baseURL +} + // GetRecordEnabled returns whether recording is enabled. func (s *Server) GetRecordEnabled() bool { s.mu.RLock()