mirror of
https://github.com/gesellix/Bose-SoundTouch.git
synced 2026-08-31 14:57:17 +00:00
Compare commits
@@ -0,0 +1,87 @@
|
||||
Draft a "News & Updates" blog post for AfterTouch covering recent git activity, then open a draft PR for review.
|
||||
|
||||
## Step 1 — Determine lookback window
|
||||
|
||||
Run:
|
||||
```
|
||||
git log --format="%ad" --date=short -- docs/content/blog/ | grep -v '_index' | head -1
|
||||
```
|
||||
|
||||
If a date is returned, use it as SINCE.
|
||||
If the output is empty (no posts yet), compute SINCE = 30 days before today:
|
||||
- macOS: `date -v-30d +%Y-%m-%d`
|
||||
- Linux: `date -d '30 days ago' +%Y-%m-%d`
|
||||
|
||||
## Step 2 — Collect commits since SINCE
|
||||
|
||||
Run:
|
||||
```
|
||||
git log --format="%ad %h %s" --date=short --since="$SINCE" --no-merges
|
||||
```
|
||||
|
||||
Exclude these (they are noise):
|
||||
- Subjects matching: `^(ci|chore|deps|bump|Bump|test|lint|style|code style|debug)`
|
||||
- Dependabot bumps (subject contains "bump" and includes a package name pattern)
|
||||
- Routine doc link/URL fixes
|
||||
|
||||
Group the remaining commits into categories:
|
||||
- **NEW FEATURES** — subjects starting with `feat(` or `feat:`
|
||||
- **BUG FIXES** — subjects starting with `fix(` or `fix:`
|
||||
- **SECURITY** — subjects starting with `sec` or containing "security", "inject", "path expression"
|
||||
- **DOCS** — user-visible doc changes only (new guides, major restructures)
|
||||
- **MAINTENANCE** — everything else that passed the filter
|
||||
|
||||
Omit empty categories entirely.
|
||||
|
||||
## Step 3 — Current version
|
||||
|
||||
Run: `git tag --sort=-version:refname | head -1`
|
||||
|
||||
## Step 4 — Determine the period label
|
||||
|
||||
Use the first and last commit dates from Step 2 to produce a human-readable label,
|
||||
e.g. "May 2026" or "April – May 2026".
|
||||
|
||||
## Step 5 — Write the blog post
|
||||
|
||||
Create the file at: `docs/content/blog/YYYY-MM-slug.md`
|
||||
- YYYY-MM = today's year-month
|
||||
- slug = short kebab-case summary of the biggest theme
|
||||
|
||||
Use this exact frontmatter shape:
|
||||
```yaml
|
||||
---
|
||||
title: "AfterTouch PERIOD: <one-line theme>"
|
||||
date: YYYY-MM-DD
|
||||
description: "<one sentence, ≤200 chars, suitable as a standalone teaser>"
|
||||
tags:
|
||||
- <up to 4 tags from: security, tls, discovery, docs, cli, web, spotify, amazon, health, migration, fixes, ci>
|
||||
sidebar:
|
||||
exclude: true
|
||||
---
|
||||
```
|
||||
|
||||
Body structure:
|
||||
1. Opening paragraph (3–5 sentences) explaining what happened and why it matters to someone running AfterTouch.
|
||||
2. One `##` section per non-empty category. Use bullet points written for an operator audience — no raw git subjects, no internal Go package paths.
|
||||
3. End with: `**Current release:** vX.Y.Z`
|
||||
|
||||
Target length: 300–600 words. Never include real IPs, MAC addresses, account IDs, or device names.
|
||||
|
||||
## Step 6 — Create a branch and open a draft PR
|
||||
|
||||
```bash
|
||||
git checkout -b blog/YYYY-MM-update
|
||||
git add docs/content/blog/YYYY-MM-slug.md
|
||||
git commit -m "docs(blog): add PERIOD update post"
|
||||
git push -u origin blog/YYYY-MM-update
|
||||
gh pr create --draft \
|
||||
--title "Blog: PERIOD update post" \
|
||||
--body "Automated draft from /blog-update skill. Review content before merging — deployment is automatic on merge to main."
|
||||
```
|
||||
|
||||
If the `documentation` label exists on the repo, add `--label documentation`.
|
||||
|
||||
## Step 7 — Done
|
||||
|
||||
Report the PR URL. Do not merge, approve, or request review.
|
||||
@@ -27,7 +27,7 @@
|
||||
"pattern": "^https://pkg.go.dev.*badge"
|
||||
},
|
||||
{
|
||||
"pattern": "^/images/[^/]+\\.png$"
|
||||
"pattern": "^/images/"
|
||||
},
|
||||
{
|
||||
"pattern": "https://www.contributor-covenant.org/version/2/0/code_of_conduct.html"
|
||||
|
||||
@@ -33,6 +33,7 @@ jobs:
|
||||
run: hugo --source docs/ --minify --destination ../_site --baseURL "${{ steps.pages.outputs.base_url }}"
|
||||
env:
|
||||
HUGO_ENVIRONMENT: production
|
||||
HUGO_PARAMS_GITHASH: ${{ github.sha }}
|
||||
- name: Upload artifact
|
||||
uses: actions/upload-pages-artifact@fc324d3547104276b827a68afc52ff2a11cc49c9 # v5.0.0
|
||||
with:
|
||||
|
||||
+2
-1
@@ -48,7 +48,8 @@ node_modules/
|
||||
# IDE and editor files
|
||||
.vscode/
|
||||
.idea/
|
||||
.claude/
|
||||
.claude/*
|
||||
!.claude/commands/
|
||||
.junie/
|
||||
*.swp
|
||||
*.swo
|
||||
|
||||
@@ -182,6 +182,12 @@ unless the user has already authorised that specific action in this
|
||||
session. Prefer reversible alternatives (`git stash` over
|
||||
`git reset --hard`).
|
||||
|
||||
**Force-flags also require explicit approval.** `git add -f` (force-add
|
||||
a gitignored file), `git push --force`, `git push --force-with-lease`,
|
||||
and any other flag that overrides a git safety mechanism must be
|
||||
proposed and confirmed before running, for the same reason: they
|
||||
bypass protections that exist intentionally.
|
||||
|
||||
## What never goes into this repo
|
||||
|
||||
This repository is public. The following must never be committed:
|
||||
|
||||
@@ -458,7 +458,7 @@ screenshots:
|
||||
# First run: make dev-docs-tidy (downloads Hextra, writes docs/go.sum)
|
||||
# Then: make dev-docs (http://localhost:1313, live reload)
|
||||
dev-docs:
|
||||
docker compose -f docker-compose.docs.yml up
|
||||
HUGO_PARAMS_GITHASH=$(shell git rev-parse HEAD) docker compose -f docker-compose.docs.yml up
|
||||
|
||||
dev-docs-tidy:
|
||||
docker compose -f docker-compose.docs.yml run --rm hugo mod tidy --source docs/
|
||||
|
||||
@@ -15,6 +15,8 @@ Bose shut down SoundTouch cloud services on **May 6, 2026**. Presets, music serv
|
||||
|
||||
See the [Survival Guide](https://gesellix.github.io/Bose-SoundTouch/docs/guides/SURVIVAL-GUIDE/) for the full picture.
|
||||
|
||||
[](https://gesellix.github.io/Bose-SoundTouch/)
|
||||
|
||||
---
|
||||
|
||||
## Tools
|
||||
|
||||
@@ -0,0 +1,13 @@
|
||||
package main
|
||||
|
||||
import "strings"
|
||||
|
||||
// sanitizeLog strips newline characters from s to prevent log-injection
|
||||
// (CodeQL go/log-injection). Values from speakers, HTTP requests, and
|
||||
// external APIs may contain attacker-controlled newlines.
|
||||
func sanitizeLog(s string) string {
|
||||
s = strings.ReplaceAll(s, "\n", `\n`)
|
||||
s = strings.ReplaceAll(s, "\r", `\r`)
|
||||
|
||||
return s
|
||||
}
|
||||
@@ -43,10 +43,10 @@ func main() {
|
||||
log.Fatalf("start fake speaker: %v", err)
|
||||
}
|
||||
|
||||
log.Printf("fake speaker HTTP listening on http://%s", s.HTTPAddr())
|
||||
log.Printf("fake speaker HTTP listening on http://%s", sanitizeLog(s.HTTPAddr()))
|
||||
|
||||
if addr := s.TelnetAddr(); addr != "" {
|
||||
log.Printf("fake speaker telnet listening on tcp://%s", addr)
|
||||
log.Printf("fake speaker telnet listening on tcp://%s", sanitizeLog(addr))
|
||||
}
|
||||
|
||||
if *register != "" {
|
||||
@@ -58,7 +58,7 @@ func main() {
|
||||
if err := registerWithService(*register, target); err != nil {
|
||||
log.Printf("self-register failed: %v (continuing anyway)", err)
|
||||
} else {
|
||||
log.Printf("registered %s with service at %s", target, *register)
|
||||
log.Printf("registered %s with service at %s", sanitizeLog(target), sanitizeLog(*register))
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -0,0 +1,13 @@
|
||||
package main
|
||||
|
||||
import "strings"
|
||||
|
||||
// sanitizeLog strips newline characters from s to prevent log-injection
|
||||
// (CodeQL go/log-injection). Values from speakers, HTTP requests, and
|
||||
// external APIs may contain attacker-controlled newlines.
|
||||
func sanitizeLog(s string) string {
|
||||
s = strings.ReplaceAll(s, "\n", `\n`)
|
||||
s = strings.ReplaceAll(s, "\r", `\r`)
|
||||
|
||||
return s
|
||||
}
|
||||
@@ -116,7 +116,7 @@ func main() {
|
||||
defer close(entries)
|
||||
|
||||
if *verbose {
|
||||
log.Printf("mDNS: Starting scan for service '%s' with timeout %v", *service, *timeout)
|
||||
log.Printf("mDNS: Starting scan for service '%s' with timeout %v", sanitizeLog(*service), *timeout)
|
||||
}
|
||||
|
||||
// Query for services
|
||||
@@ -196,7 +196,7 @@ func parseServiceEntry(entry *mdns.ServiceEntry, verbose bool) *ServiceInfo {
|
||||
|
||||
if verbose {
|
||||
log.Printf("mDNS: Received service entry: Name='%s', Host='%s', Port=%d, AddrV4=%v, AddrV6=%v",
|
||||
entry.Name, entry.Host, entry.Port, entry.AddrV4, entry.AddrV6)
|
||||
sanitizeLog(entry.Name), sanitizeLog(entry.Host), entry.Port, entry.AddrV4, entry.AddrV6)
|
||||
}
|
||||
|
||||
service := &ServiceInfo{
|
||||
|
||||
@@ -568,7 +568,7 @@ type VerboseLogger struct{}
|
||||
|
||||
func (v *VerboseLogger) Printf(format string, args ...interface{}) {
|
||||
timestamp := time.Now().Format("15:04:05")
|
||||
fmt.Printf("[%s] [WebSocket] %s\n", timestamp, fmt.Sprintf(format, args...))
|
||||
fmt.Printf("[%s] [WebSocket] %s\n", timestamp, sanitizeLog(fmt.Sprintf(format, args...)))
|
||||
}
|
||||
|
||||
type SilentLogger struct{}
|
||||
|
||||
@@ -332,7 +332,7 @@ func PrintSuccess(message string) {
|
||||
|
||||
// PrintError prints a standard error message
|
||||
func PrintError(message string) {
|
||||
fmt.Printf("✗ %s\n", message)
|
||||
fmt.Printf("✗ %s\n", sanitizeLog(message))
|
||||
}
|
||||
|
||||
// PrintWarning prints a standard warning message
|
||||
|
||||
@@ -0,0 +1,13 @@
|
||||
package main
|
||||
|
||||
import "strings"
|
||||
|
||||
// sanitizeLog strips newline characters from s to prevent log-injection
|
||||
// (CodeQL go/log-injection). Values from speakers, HTTP requests, and
|
||||
// external APIs may contain attacker-controlled newlines.
|
||||
func sanitizeLog(s string) string {
|
||||
s = strings.ReplaceAll(s, "\n", `\n`)
|
||||
s = strings.ReplaceAll(s, "\r", `\r`)
|
||||
|
||||
return s
|
||||
}
|
||||
@@ -0,0 +1,13 @@
|
||||
package main
|
||||
|
||||
import "strings"
|
||||
|
||||
// sanitizeLog strips newline characters from s to prevent log-injection
|
||||
// (CodeQL go/log-injection). Values from speakers, HTTP requests, and
|
||||
// external APIs may contain attacker-controlled newlines.
|
||||
func sanitizeLog(s string) string {
|
||||
s = strings.ReplaceAll(s, "\n", `\n`)
|
||||
s = strings.ReplaceAll(s, "\r", `\r`)
|
||||
|
||||
return s
|
||||
}
|
||||
@@ -71,7 +71,7 @@ func initializeDefaultSources(ds *datastore.DataStore) {
|
||||
for i := range allDevices {
|
||||
dev := &allDevices[i]
|
||||
if sources, errGet := ds.GetConfiguredSources(dev.AccountID, dev.DeviceID); errGet == nil {
|
||||
log.Printf("Initializing default Sources.xml for existing device %s", dev.DeviceID)
|
||||
log.Printf("Initializing default Sources.xml for existing device %s", sanitizeLog(dev.DeviceID))
|
||||
|
||||
// Find default sources and merge them if missing or outdated tokens.
|
||||
// claimed tracks which stored sources have already been matched by a default,
|
||||
@@ -103,13 +103,13 @@ func initializeDefaultSources(ds *datastore.DataStore) {
|
||||
claimed[foundIdx] = true
|
||||
|
||||
if sources[foundIdx].Secret == "" && def.Secret != "" {
|
||||
log.Printf("Initializing missing token for source %s on device %s", def.SourceKeyType, dev.DeviceID)
|
||||
log.Printf("Initializing missing token for source %s on device %s", sanitizeLog(def.SourceKeyType), sanitizeLog(dev.DeviceID))
|
||||
sources[foundIdx].Secret = def.Secret
|
||||
sources[foundIdx].SecretType = def.SecretType
|
||||
modified = true
|
||||
}
|
||||
} else {
|
||||
log.Printf("Adding missing default source %s (providerID=%s) to device %s", def.SourceKeyType, def.SourceProviderID, dev.DeviceID)
|
||||
log.Printf("Adding missing default source %s (providerID=%s) to device %s", sanitizeLog(def.SourceKeyType), sanitizeLog(def.SourceProviderID), sanitizeLog(dev.DeviceID))
|
||||
sources = append(sources, def)
|
||||
modified = true
|
||||
}
|
||||
@@ -117,7 +117,7 @@ func initializeDefaultSources(ds *datastore.DataStore) {
|
||||
|
||||
if modified {
|
||||
if errSave := ds.SaveConfiguredSources(dev.AccountID, dev.DeviceID, sources); errSave != nil {
|
||||
log.Printf("Failed to save updated sources for %s: %v", dev.DeviceID, errSave)
|
||||
log.Printf("Failed to save updated sources for %s: %v", sanitizeLog(dev.DeviceID), errSave)
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -147,7 +147,7 @@ func initMusicServices(config serviceConfig, server *handlers.Server) {
|
||||
clientIDPrefix = clientIDPrefix[:8]
|
||||
}
|
||||
|
||||
log.Printf("Spotify service initialized (client ID: %s...)", clientIDPrefix)
|
||||
log.Printf("Spotify service initialized (client ID: %s...)", sanitizeLog(clientIDPrefix))
|
||||
}
|
||||
|
||||
if config.amazonClientID != "" {
|
||||
@@ -172,7 +172,7 @@ func initMusicServices(config serviceConfig, server *handlers.Server) {
|
||||
clientIDPrefix = clientIDPrefix[:8]
|
||||
}
|
||||
|
||||
log.Printf("Amazon Music service initialized (client ID: %s...)", clientIDPrefix)
|
||||
log.Printf("Amazon Music service initialized (client ID: %s...)", sanitizeLog(clientIDPrefix))
|
||||
}
|
||||
}
|
||||
|
||||
@@ -188,7 +188,7 @@ func logBufferCapacityFromEnv(defaultCap int) int {
|
||||
|
||||
v, err := strconv.Atoi(raw)
|
||||
if err != nil {
|
||||
log.Printf("[Logs] Invalid SOUNDTOUCH_LOG_BUFFER_LINES=%q, using default %d", raw, defaultCap)
|
||||
log.Printf("[Logs] Invalid SOUNDTOUCH_LOG_BUFFER_LINES=%q, using default %d", sanitizeLog(raw), defaultCap)
|
||||
return defaultCap
|
||||
}
|
||||
|
||||
@@ -415,7 +415,7 @@ func main() {
|
||||
persisted := applyPersistedSettings(ds, &config)
|
||||
|
||||
if persisted.ServerURL == "" {
|
||||
log.Printf("Creating default settings.json in %s", config.dataDir)
|
||||
log.Printf("Creating default settings.json in %s", sanitizeLog(config.dataDir))
|
||||
persisted = createDefaultSettings(ds, config)
|
||||
}
|
||||
|
||||
@@ -468,7 +468,7 @@ func main() {
|
||||
server.SetShortcuts(persisted.Shortcuts)
|
||||
|
||||
for path, status := range persisted.Shortcuts {
|
||||
log.Printf("Warning: configured shortcut: %s -> %d", path, status)
|
||||
log.Printf("Warning: configured shortcut: %s -> %d", sanitizeLog(path), status)
|
||||
}
|
||||
|
||||
recorder := proxy.NewRecorder(config.dataDir)
|
||||
@@ -477,11 +477,11 @@ func main() {
|
||||
|
||||
patterns, err := proxy.LoadPatterns(patternsPath)
|
||||
if err != nil {
|
||||
log.Printf("Warning: Failed to load patterns from %s: %v", patternsPath, err)
|
||||
log.Printf("Warning: Failed to load patterns from %s: %v", sanitizeLog(patternsPath), err)
|
||||
}
|
||||
|
||||
if len(patterns) == 0 {
|
||||
log.Printf("Creating default patterns at %s", patternsPath)
|
||||
log.Printf("Creating default patterns at %s", sanitizeLog(patternsPath))
|
||||
|
||||
patterns = proxy.DefaultPatterns()
|
||||
|
||||
@@ -512,17 +512,17 @@ func main() {
|
||||
} else {
|
||||
stockholmHandler = sh
|
||||
|
||||
log.Printf("Stockholm frontend enabled from %s", config.stockholmDir)
|
||||
log.Printf("Stockholm frontend enabled from %s", sanitizeLog(config.stockholmDir))
|
||||
}
|
||||
}
|
||||
|
||||
r := setupRouter(server, stockholmHandler)
|
||||
|
||||
log.Printf("Go service starting on %s", config.serverURL)
|
||||
log.Printf("Go service starting on %s", sanitizeLog(config.serverURL))
|
||||
|
||||
// TLS cert generation can be slow on constrained hardware; run it in the
|
||||
// background so the HTTP server is available immediately.
|
||||
log.Printf("HTTPS setup running in background; %s will be available shortly", config.httpsServerURL)
|
||||
log.Printf("HTTPS setup running in background; %s will be available shortly", sanitizeLog(config.httpsServerURL))
|
||||
|
||||
go func() {
|
||||
tlsConfig, err := cm.GetServerTLSConfig(config.domains)
|
||||
@@ -652,7 +652,7 @@ func loadConfig(c *cli.Context) serviceConfig {
|
||||
|
||||
discoveryInterval, err := time.ParseDuration(discoveryIntervalStr)
|
||||
if err != nil {
|
||||
log.Printf("Warning: Failed to parse discovery interval %s, using default 5m: %v", discoveryIntervalStr, err)
|
||||
log.Printf("Warning: Failed to parse discovery interval %s, using default 5m: %v", sanitizeLog(discoveryIntervalStr), err)
|
||||
|
||||
discoveryInterval = 5 * time.Minute
|
||||
}
|
||||
@@ -1294,7 +1294,7 @@ func startHTTPSServer(httpsAddr string, r http.Handler, tlsConfig *tls.Config, h
|
||||
return &tlsConfig.Certificates[0], nil
|
||||
}
|
||||
|
||||
log.Printf("[TLS] ❌ No certificate available for %s", clientHello.ServerName)
|
||||
log.Printf("[TLS] ❌ No certificate available for %s", sanitizeLog(clientHello.ServerName))
|
||||
|
||||
return nil, fmt.Errorf("no certificate available for %s", clientHello.ServerName)
|
||||
}
|
||||
@@ -1306,7 +1306,7 @@ func startHTTPSServer(httpsAddr string, r http.Handler, tlsConfig *tls.Config, h
|
||||
ErrorLog: log.Default(), // Ensure error logging is enabled
|
||||
}
|
||||
|
||||
log.Printf("Go service starting HTTPS on %s", httpsServerURL)
|
||||
log.Printf("Go service starting HTTPS on %s", sanitizeLog(httpsServerURL))
|
||||
|
||||
go func() {
|
||||
listener, err := net.Listen("tcp", httpsAddr)
|
||||
@@ -1361,9 +1361,9 @@ func runHTTPSPreflight(httpsServerURL, serverURL string, dnsEnabled bool, resolv
|
||||
case res.Skipped:
|
||||
// Listener already on :443 — nothing to say.
|
||||
case res.NotApplicable:
|
||||
log.Printf("HTTPS pre-flight: :443 check skipped — %s", res.Reason)
|
||||
log.Printf("HTTPS pre-flight: :443 check skipped — %s", sanitizeLog(res.Reason))
|
||||
default:
|
||||
log.Printf("HTTPS pre-flight: :443 reachable at localhost and %s ✓", res.LANHost)
|
||||
log.Printf("HTTPS pre-flight: :443 reachable at localhost and %s ✓", sanitizeLog(res.LANHost))
|
||||
}
|
||||
|
||||
return
|
||||
@@ -1438,7 +1438,7 @@ func (c *loggingTLSConn) Read(b []byte) (n int, err error) {
|
||||
if strings.Contains(err.Error(), "tls:") ||
|
||||
strings.Contains(err.Error(), "handshake") ||
|
||||
strings.Contains(err.Error(), "certificate") {
|
||||
log.Printf("[TLS] ❌ Handshake failed from %s: %v", c.addr, err)
|
||||
log.Printf("[TLS] ❌ Handshake failed from %s: %v", sanitizeLog(c.addr.String()), err)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,13 @@
|
||||
package main
|
||||
|
||||
import "strings"
|
||||
|
||||
// sanitizeLog strips newline characters from s to prevent log-injection
|
||||
// (CodeQL go/log-injection). Values from speakers, HTTP requests, and
|
||||
// external APIs may contain attacker-controlled newlines.
|
||||
func sanitizeLog(s string) string {
|
||||
s = strings.ReplaceAll(s, "\n", `\n`)
|
||||
s = strings.ReplaceAll(s, "\r", `\r`)
|
||||
|
||||
return s
|
||||
}
|
||||
@@ -86,7 +86,7 @@ func main() {
|
||||
}
|
||||
|
||||
if rawBind != "" && bindAddr != rawBind {
|
||||
log.Printf("Resolved --bind %q to %s", rawBind, bindAddr)
|
||||
log.Printf("Resolved --bind %q to %s", sanitizeLog(rawBind), sanitizeLog(bindAddr))
|
||||
}
|
||||
|
||||
rawIface := c.String("interface")
|
||||
@@ -94,7 +94,7 @@ func main() {
|
||||
|
||||
ifaceName := defaultDiscoveryInterface(rawIface, rawBind, bindAddr)
|
||||
if rawIface == "" && ifaceName != "" {
|
||||
log.Printf("Defaulting --interface to %q from --bind", ifaceName)
|
||||
log.Printf("Defaulting --interface to %q from --bind", sanitizeLog(ifaceName))
|
||||
}
|
||||
|
||||
addr := ":" + port
|
||||
@@ -131,7 +131,7 @@ func main() {
|
||||
r := chi.NewRouter()
|
||||
webApp.Mount(r, discoveryService)
|
||||
|
||||
log.Printf("AfterTouch Web UI starting on http://%s", addr)
|
||||
log.Printf("AfterTouch Web UI starting on http://%s", sanitizeLog(addr))
|
||||
|
||||
return http.ListenAndServe(addr, r)
|
||||
},
|
||||
|
||||
@@ -0,0 +1,13 @@
|
||||
package main
|
||||
|
||||
import "strings"
|
||||
|
||||
// sanitizeLog strips newline characters from s to prevent log-injection
|
||||
// (CodeQL go/log-injection). Values from speakers, HTTP requests, and
|
||||
// external APIs may contain attacker-controlled newlines.
|
||||
func sanitizeLog(s string) string {
|
||||
s = strings.ReplaceAll(s, "\n", `\n`)
|
||||
s = strings.ReplaceAll(s, "\r", `\r`)
|
||||
|
||||
return s
|
||||
}
|
||||
@@ -573,7 +573,7 @@ type VerboseLogger struct{}
|
||||
|
||||
func (v *VerboseLogger) Printf(format string, args ...interface{}) {
|
||||
timestamp := time.Now().Format("15:04:05")
|
||||
fmt.Printf("[%s] [WebSocket] %s\n", timestamp, fmt.Sprintf(format, args...))
|
||||
fmt.Printf("[%s] [WebSocket] %s\n", timestamp, sanitizeLog(fmt.Sprintf(format, args...)))
|
||||
}
|
||||
|
||||
// SilentLogger provides no-op WebSocket logging
|
||||
|
||||
@@ -27,6 +27,8 @@ services:
|
||||
# downloads Hextra once.
|
||||
- hugo-mod-cache:/root/.cache/hugo_cache
|
||||
working_dir: /src
|
||||
environment:
|
||||
- HUGO_PARAMS_GITHASH
|
||||
|
||||
volumes:
|
||||
hugo-mod-cache:
|
||||
|
||||
@@ -22,7 +22,7 @@ layout: hextra-home
|
||||
</div>
|
||||
|
||||
<div class="hx-mb-6">
|
||||
{{< hextra/hero-button text="Get Started" link="docs/guides/GETTING-STARTED" >}}
|
||||
{{< hextra/hero-button text="Get Started" link="docs/guides/MIGRATION-GUIDE" >}}
|
||||
{{< hextra/hero-button text="Survival Guide" link="docs/guides/SURVIVAL-GUIDE" style="outline" >}}
|
||||
</div>
|
||||
|
||||
|
||||
@@ -0,0 +1,120 @@
|
||||
---
|
||||
title: "Welcome to AfterTouch: Your SoundTouch Speakers, Still Alive"
|
||||
date: 2026-05-24
|
||||
description: "Bose shut down SoundTouch cloud services in May 2026. AfterTouch replaces everything your speakers relied on — migration, radio, Spotify, presets, and more."
|
||||
tags:
|
||||
- migration
|
||||
- web
|
||||
- spotify
|
||||
- cli
|
||||
sidebar:
|
||||
exclude: true
|
||||
---
|
||||
|
||||
On May 6, 2026, Bose shut down the SoundTouch cloud services that millions of speakers
|
||||
depended on for account sync, presets, internet radio, and streaming. Speakers kept
|
||||
working locally, but remote features stopped and first-time setup became impossible.
|
||||
|
||||
AfterTouch was built to change that. It is a self-hosted replacement for the Bose
|
||||
cloud infrastructure — a drop-in local service that your speakers talk to instead of
|
||||
`streaming.bose.com`. This post covers what works today and how to get started.
|
||||
|
||||
## What works right now
|
||||
|
||||
### Migration and first-time setup
|
||||
|
||||
If your speaker was registered with Bose before the shutdown, AfterTouch can **migrate
|
||||
your existing account and presets** in a single step — no reconfiguration on the
|
||||
speaker side. If you are setting up a factory-reset or brand-new speaker, AfterTouch
|
||||
handles that path too, guiding you through Wi-Fi pairing and account creation locally.
|
||||
See the [Migration Guide](../docs/guides/MIGRATION-GUIDE.md) for step-by-step instructions.
|
||||
|
||||
### Internet radio — TuneIn and RadioBrowser
|
||||
|
||||
Both **TuneIn** and **RadioBrowser** are fully supported for browsing and playback.
|
||||
Navigate categories and search for stations exactly as you did with the original Bose
|
||||
app. TuneIn delivers the same station catalogue; RadioBrowser provides an open,
|
||||
community-maintained alternative.
|
||||
|
||||
### Spotify
|
||||
|
||||
**Spotify** works via both OAuth (account linking) and Spotify Connect (the ZeroConf
|
||||
"connect to device" flow from the Spotify app). Once linked, playback and device
|
||||
selection behave the same as before.
|
||||
|
||||
### Presets
|
||||
|
||||
Your six preset buttons work. AfterTouch stores preset bindings locally and serves them
|
||||
back to the speaker on request. You can also **save new presets** — via the API,
|
||||
via `soundtouch-cli`, or through the soundtouch-web UI.
|
||||
|
||||
### ST-10 stereo pairing
|
||||
|
||||
**SoundTouch 10 stereo pairs** (and other ST pairing configurations) are supported
|
||||
end-to-end: creation, management, and playback routing all go through AfterTouch.
|
||||
|
||||
### soundtouch-web — browser UI
|
||||
|
||||
**soundtouch-web** is an early-stage but functional browser UI bundled with AfterTouch.
|
||||
It gives you:
|
||||
|
||||
- TuneIn and RadioBrowser browsing and playback
|
||||
- Speaker management and device discovery
|
||||
- Recent tracks panel
|
||||
- Multi-room zone management
|
||||
|
||||
It runs as part of the AfterTouch service — no separate install needed.
|
||||
|
||||

|
||||
|
||||
### Automation with soundtouch-cli
|
||||
|
||||
The **`soundtouch-cli`** command-line tool covers every speaker control: play, pause,
|
||||
volume, source selection, preset recall, group management, migration, and more.
|
||||
It is well-suited for home-automation scripts, cron jobs, and shell one-liners.
|
||||
|
||||
## Three ways to install
|
||||
|
||||
AfterTouch runs on any machine your speakers can reach:
|
||||
|
||||
1. **On the speaker itself** — install directly on supported SoundTouch hardware via
|
||||
the on-device installer. The speaker hosts its own replacement cloud, with no
|
||||
additional hardware required.
|
||||
|
||||
2. **On a local network host** — run AfterTouch on any machine on your LAN. A
|
||||
**Raspberry Pi Zero 2W** handles the load without breaking a sweat, making this
|
||||
path remarkably low-cost and low-power.
|
||||
|
||||
3. **On a cloud or VPS host** — deploy to a remote server for access outside your
|
||||
home network. AfterTouch handles TLS certificate generation and DNS configuration
|
||||
for this scenario.
|
||||
|
||||
All three paths are documented in the [Deployment Overview](../docs/guides/DEPLOYMENT-OVERVIEW.md).
|
||||
|
||||
## Current release
|
||||
|
||||
**v0.93.1** — released May 24, 2026
|
||||
|
||||
## Community
|
||||
|
||||
AfterTouch would not be where it is without the people who opened issues, tested
|
||||
pre-release builds, reported edge cases, and contributed code. A significant share of
|
||||
the fixes and features shipped in the lead-up to the cloud shutdown were driven by
|
||||
real-world feedback from the community — from migration quirks to stereo-pair
|
||||
specifics to Spotify Connect timing issues. Thank you to everyone who helped.
|
||||
|
||||
If you run into something or have an idea, the
|
||||
[GitHub issue tracker](https://github.com/gesellix/Bose-SoundTouch/issues) and
|
||||
[Discussions](https://github.com/gesellix/Bose-SoundTouch/discussions) are the
|
||||
right places to start.
|
||||
|
||||
## What's next
|
||||
|
||||
The soundtouch-web UI will gain richer preset management — browsing, editing, and
|
||||
reordering presets directly from the browser. Longer term, merging
|
||||
`soundtouch-service` and `soundtouch-web` into a single binary is on the table,
|
||||
which would simplify deployment to a single process with no extra flags.
|
||||
|
||||
This blog will be updated monthly — or whenever something significant ships.
|
||||
Subscribe to the [GitHub releases](https://github.com/gesellix/Bose-SoundTouch/releases)
|
||||
for individual version notes.
|
||||
@@ -1,3 +1,5 @@
|
||||
---
|
||||
title: News & Updates
|
||||
---
|
||||
|
||||
Project updates, release notes, and development notes for AfterTouch — the local replacement for the Bose SoundTouch cloud.
|
||||
|
||||
@@ -1,9 +1,6 @@
|
||||
---
|
||||
title: "Placeholder values for examples"
|
||||
---
|
||||
|
||||
# Placeholder values for examples
|
||||
|
||||
This repo is public. Documentation, READMEs, example configs, and test
|
||||
fixtures must never carry real LAN IPs, real device MACs, real Bose
|
||||
account IDs, or personal device names from any maintainer or
|
||||
|
||||
@@ -1,9 +1,6 @@
|
||||
---
|
||||
title: "Bose SoundTouch API Coverage Analysis"
|
||||
---
|
||||
|
||||
# Bose SoundTouch API Coverage Analysis
|
||||
|
||||
**Last Updated:** February 2026
|
||||
**API Version:** Official Bose SoundTouch Web API v1.0
|
||||
**Implementation Status:** 100% Official Coverage + Extended Features
|
||||
|
||||
@@ -1,9 +1,6 @@
|
||||
---
|
||||
title: "Bose SoundTouch Traffic Interception Runbook"
|
||||
---
|
||||
|
||||
# Bose SoundTouch Traffic Interception Runbook
|
||||
|
||||
Intercept HTTPS/WebSocket traffic from the Bose SoundTouch Android app using an Android emulator, mitmproxy, and Frida. Tested on Apple Silicon (ARM64) Mac.
|
||||
|
||||
## Automated Setup
|
||||
|
||||
@@ -1,9 +1,6 @@
|
||||
---
|
||||
title: "Bose SoundTouch – Traffic Analysis Runbook"
|
||||
---
|
||||
|
||||
# Bose SoundTouch – Traffic Analysis Runbook
|
||||
|
||||
> **Goal:** Set up a Raspberry Pi as a transparent access point to fully observe the traffic of the Bose SoundTouch app – specifically the pairing flow with the Bose Cloud. This serves as a basis for later reverse engineering / simulation of the cloud endpoints.
|
||||
|
||||
---
|
||||
|
||||
@@ -1,9 +1,6 @@
|
||||
---
|
||||
title: "Device Redirect Methods & Custom Service Setup"
|
||||
---
|
||||
|
||||
# Device Redirect Methods & Custom Service Setup
|
||||
|
||||
To enable offline operation or use custom services like **SoundCork** or **ÜberBöse API**, SoundTouch devices must be redirected from Bose's official cloud endpoints to a local or custom server. This document outlines the three known methods to achieve this, gathered from community reverse-engineering efforts in the **SoundCork** and **ÜberBöse API** projects.
|
||||
|
||||
> A fourth, **SSH-free** path — driving the device's diagnostic shell on TCP port 17000 — is being added as a peer to the XML and DNS methods. See **[TELNET-MIGRATION-METHOD.md](TELNET-MIGRATION-METHOD.md)** for the use cases, community findings, and feasibility analysis. The `/etc/hosts` method documented below is now deprecated and will not be exposed in the web UI.
|
||||
|
||||
@@ -1,9 +1,6 @@
|
||||
---
|
||||
title: "What a SoundTouch speaker does during factory reset"
|
||||
---
|
||||
|
||||
# What a SoundTouch speaker does during factory reset
|
||||
|
||||
Observed live on ST10 firmware `27.0.6.46330.5043500` (build `epdbuild.trunk.hepdswbld04.2022-08-04`) on 2026-05-12, by running `soundtouch-cli setup factory-reset` and tailing the speaker's `logread` over SSH. The trace is preserved at `_/logs/factory-reset.txt` for reference.
|
||||
|
||||
## Sequence
|
||||
|
||||
@@ -1,9 +1,6 @@
|
||||
---
|
||||
title: "IoT Configuration Quick Reference"
|
||||
---
|
||||
|
||||
# IoT Configuration Quick Reference
|
||||
|
||||
## Key Files and Locations
|
||||
|
||||
| File/Location | Purpose | Notes |
|
||||
|
||||
@@ -1,9 +1,6 @@
|
||||
---
|
||||
title: "IoT Configuration Analysis"
|
||||
---
|
||||
|
||||
# IoT Configuration Analysis
|
||||
|
||||
## Overview
|
||||
|
||||
This document provides a detailed analysis of the AWS IoT configuration system used by Bose SoundTouch devices, based on firmware backup analysis from ST10 and ST20 models.
|
||||
|
||||
@@ -1,9 +1,6 @@
|
||||
---
|
||||
title: "Spotify Account Addition Implementation Status"
|
||||
---
|
||||
|
||||
# Spotify Account Addition Implementation Status
|
||||
|
||||
To fully replace Bose cloud services for the Spotify account addition flow in the "Stockholm" SoundTouch application, the following routes have been implemented in the `soundtouch-service`:
|
||||
|
||||
## 1. OAuth Token Exchange (Bose Cloud)
|
||||
|
||||
@@ -1,9 +1,6 @@
|
||||
---
|
||||
title: "Experiment: Does bare `setMargeAccount` work outside the SETUP bracket?"
|
||||
---
|
||||
|
||||
# Experiment: Does bare `setMargeAccount` work outside the SETUP bracket?
|
||||
|
||||
## Why we are doing this
|
||||
|
||||
Our captured pairing flow (`docs/reference/DEVICE-PAIRING-FLOW.md`) shows the official Bose app always sends `setMargeAccount` *inside* a `SETUP_START` → `SETUP_ENTER` → `SETUP_LEAVE` state-machine bracket over WebSocket. The question this experiment answers:
|
||||
|
||||
@@ -1,9 +1,6 @@
|
||||
---
|
||||
title: "SoundTouch supportedURLs Endpoint Analysis"
|
||||
---
|
||||
|
||||
# SoundTouch supportedURLs Endpoint Analysis
|
||||
|
||||
This document provides a comprehensive analysis of the `/supportedURLs` endpoint response from real Bose SoundTouch devices and compares it with our current implementation.
|
||||
|
||||
## Discovery Summary
|
||||
|
||||
@@ -1,9 +1,6 @@
|
||||
---
|
||||
title: "Bose SoundTouch Telnet (Port 17000) Command Reference"
|
||||
---
|
||||
|
||||
# Bose SoundTouch Telnet (Port 17000) Command Reference
|
||||
|
||||
A consolidated reference for the diagnostic shell that listens on TCP port
|
||||
17000 across the SoundTouch line. Compiled from multiple community sources
|
||||
to give a single map of what's been observed in the wild — useful both for
|
||||
|
||||
@@ -1,9 +1,6 @@
|
||||
---
|
||||
title: "Telnet (Port 17000) Migration Method — Analysis"
|
||||
---
|
||||
|
||||
# Telnet (Port 17000) Migration Method — Analysis
|
||||
|
||||
This document captures the use cases, community findings, and feasibility analysis
|
||||
for adding a **Telnet/port 17000** migration path to `soundtouch-service` as a
|
||||
peer of the existing XML and DNS-based methods. The `/etc/hosts` method stays
|
||||
@@ -12,7 +9,7 @@ deprecated and is intentionally kept off the visible UI options.
|
||||
> **Sources** — community discussion synthesised from
|
||||
> [gesellix/Bose-SoundTouch#221](https://github.com/gesellix/Bose-SoundTouch/issues/221),
|
||||
> [gesellix/Bose-SoundTouch#236](https://github.com/gesellix/Bose-SoundTouch/issues/236),
|
||||
> [scheilch/opencloudtouch#167](https://github.com/scheilch/opencloudtouch/issues/167),
|
||||
> [scheilch/opencloudtouch#167](https://github.com/opencloudtouch/opencloudtouch/issues/167),
|
||||
> [deborahgu/soundcork#228](https://github.com/deborahgu/soundcork/issues/228),
|
||||
> [deborahgu/soundcork#141](https://github.com/deborahgu/soundcork/issues/141),
|
||||
> the post-EOS walkthrough PDF in `docs/`,
|
||||
|
||||
@@ -1,9 +1,6 @@
|
||||
---
|
||||
title: "Upstream URLs & Domains Analysis"
|
||||
---
|
||||
|
||||
# Upstream URLs & Domains Analysis
|
||||
|
||||
This document provides a comprehensive overview of the upstream Bose cloud services and domains that SoundTouch devices communicate with. These details were gathered from firmware analysis of ST10/ST20 devices, binary string extraction, and community research from the **SoundCork** project (Issue #128).
|
||||
|
||||
## Core Service Domains
|
||||
|
||||
@@ -1,9 +1,6 @@
|
||||
---
|
||||
title: "SoundTouch API Comparison: Community Wiki vs Current Implementation"
|
||||
---
|
||||
|
||||
# SoundTouch API Comparison: Community Wiki vs Current Implementation
|
||||
|
||||
**Date:** January 2026
|
||||
**Source:** [SoundTouch Plus Wiki](https://github.com/thlucas1/homeassistantcomponent_soundtouchplus/wiki/SoundTouch-WebServices-API)
|
||||
**Our Implementation:** Bose-SoundTouch Go Library v1.0
|
||||
|
||||
@@ -1,9 +1,6 @@
|
||||
---
|
||||
title: "Bose SoundTouch — Community Tools for Post-EOL Preservation"
|
||||
---
|
||||
|
||||
# Bose SoundTouch — Community Tools for Post-EOL Preservation
|
||||
|
||||
> **Context:** Bose announced the shutdown of SoundTouch cloud services, extended to **May 6, 2026**. On that date the official SoundTouch app will update to a local-only version. Bose has released the [SoundTouch Web API documentation](https://assets.bosecreative.com/m/496577402d128874/original/SoundTouch-Web-API.pdf) as open-source to enable community-driven development. This document surveys the active community projects, their feature coverage, and open development opportunities.
|
||||
|
||||
---
|
||||
|
||||
@@ -3,9 +3,6 @@ title: "Navigation API Reference"
|
||||
sidebar:
|
||||
exclude: true
|
||||
---
|
||||
|
||||
# Navigation API Reference
|
||||
|
||||
## Overview
|
||||
|
||||
This document provides a complete API reference for the Bose SoundTouch navigation and station management functionality. For usage examples and workflows, see [NAVIGATION-GUIDE.md](NAVIGATION-GUIDE.md).
|
||||
|
||||
@@ -3,9 +3,6 @@ title: "CLAUDE.md - Development Guidelines for Bose SoundTouch Project"
|
||||
sidebar:
|
||||
exclude: true
|
||||
---
|
||||
|
||||
# CLAUDE.md - Development Guidelines for Bose SoundTouch Project
|
||||
|
||||
## Documentation Overview
|
||||
|
||||
This document contains important development guidelines for working on the Bose SoundTouch project. Please also read the following documentation:
|
||||
|
||||
@@ -3,9 +3,6 @@ title: "Content Selection Implementation Summary"
|
||||
sidebar:
|
||||
exclude: true
|
||||
---
|
||||
|
||||
# Content Selection Implementation Summary
|
||||
|
||||
This document summarizes the implementation of advanced content selection features for the Bose SoundTouch Go client, including full support for the LOCAL_INTERNET_RADIO streamUrl format and LOCAL_MUSIC/STORED_MUSIC content selection.
|
||||
|
||||
## ✅ Implementation Status: COMPLETE
|
||||
|
||||
@@ -3,9 +3,6 @@ title: "Device Customization Setup Guide"
|
||||
sidebar:
|
||||
exclude: true
|
||||
---
|
||||
|
||||
# Device Customization Setup Guide
|
||||
|
||||
This guide documents the manual steps required to configure your Bose SoundTouch device for customization using the SoundCork approach.
|
||||
|
||||
Based on: https://github.com/deborahgu/soundcork
|
||||
|
||||
@@ -3,9 +3,6 @@ title: "Device Logging & Troubleshooting"
|
||||
sidebar:
|
||||
exclude: true
|
||||
---
|
||||
|
||||
# Device Logging & Troubleshooting
|
||||
|
||||
Accessing logs from SoundTouch devices is critical for debugging custom service integrations and understanding internal device behavior. This document outlines the methods for collecting logs, as discovered by the **SoundCork** and **ÜberBöse API** communities.
|
||||
|
||||
## Log Types
|
||||
|
||||
@@ -3,9 +3,6 @@ title: "Bose SoundTouch Device Setup Flow"
|
||||
sidebar:
|
||||
exclude: true
|
||||
---
|
||||
|
||||
# Bose SoundTouch Device Setup Flow
|
||||
|
||||
This document details the multi-step process required to fully set up a Bose SoundTouch device, as derived from the Stockholm firmware (`setup/js/`) analysis.
|
||||
|
||||
A complete setup flow involves a sequence of local (WebSocket) and cloud (HTTP) actions that move the device from a factory-reset state to a fully registered, functional system.
|
||||
|
||||
@@ -3,9 +3,6 @@ title: "Encrypted Diagnostic Export"
|
||||
sidebar:
|
||||
exclude: true
|
||||
---
|
||||
|
||||
# Encrypted Diagnostic Export
|
||||
|
||||
AfterTouch can produce an encrypted diagnostic report that users can download and
|
||||
send to the project maintainer without exposing sensitive data to third parties.
|
||||
The report is encrypted with an SSH public key using
|
||||
|
||||
@@ -3,9 +3,6 @@ title: "Technical Proposal: External Service Provider Abstraction"
|
||||
sidebar:
|
||||
exclude: true
|
||||
---
|
||||
|
||||
# Technical Proposal: External Service Provider Abstraction
|
||||
|
||||
This document outlines a strategy to refactor the SoundTouch Service's content handling into a modular provider-based system.
|
||||
|
||||
## 1. Problem Statement
|
||||
|
||||
@@ -3,9 +3,6 @@ title: "Feature Development History"
|
||||
sidebar:
|
||||
exclude: true
|
||||
---
|
||||
|
||||
# Feature Development History
|
||||
|
||||
This document tracks the detailed evolution of features and capabilities in the Bose SoundTouch API client library.
|
||||
|
||||
## Development Timeline
|
||||
|
||||
@@ -3,9 +3,6 @@ title: "Host:Port Parsing Feature"
|
||||
sidebar:
|
||||
exclude: true
|
||||
---
|
||||
|
||||
# Host:Port Parsing Feature
|
||||
|
||||
This document describes the automatic host:port parsing functionality added to the SoundTouch CLI, which allows users to specify both host and port in a single `-host` flag.
|
||||
|
||||
## Overview
|
||||
|
||||
@@ -3,9 +3,6 @@ title: "Manual Network Discovery on macOS"
|
||||
sidebar:
|
||||
exclude: true
|
||||
---
|
||||
|
||||
# Manual Network Discovery on macOS
|
||||
|
||||
This document provides comprehensive guidance for manually discovering network services and devices using built-in macOS tools and command-line utilities. This is particularly useful for troubleshooting network discovery issues or understanding what services are available on your local network.
|
||||
|
||||
## Overview
|
||||
|
||||
@@ -3,9 +3,6 @@ title: "Navigation and Station Management Guide"
|
||||
sidebar:
|
||||
exclude: true
|
||||
---
|
||||
|
||||
# Navigation and Station Management Guide
|
||||
|
||||
## Overview
|
||||
|
||||
The Bose SoundTouch Go client provides comprehensive navigation and station management functionality that allows you to:
|
||||
|
||||
@@ -3,9 +3,6 @@ title: "Official SoundTouch Web API Verification"
|
||||
sidebar:
|
||||
exclude: true
|
||||
---
|
||||
|
||||
# Official SoundTouch Web API Verification
|
||||
|
||||
**Source**: Official Bose SoundTouch Web API v1.0 Documentation (January 7, 2026)
|
||||
**Verification Date**: January 9, 2026
|
||||
**Project Status**: Complete API coverage verification
|
||||
|
||||
@@ -3,9 +3,6 @@ title: "Parity Analysis: Bose-SoundTouch (Go) vs. OpenCloudTouch (Python)"
|
||||
sidebar:
|
||||
exclude: true
|
||||
---
|
||||
|
||||
# Parity Analysis: Bose-SoundTouch (Go) vs. OpenCloudTouch (Python)
|
||||
|
||||
This document provides a comparative analysis of the current Go implementation and the `scheilch/opencloudtouch` project, identifying functional gaps and potential improvements.
|
||||
|
||||
## 1. Core Architecture and Language
|
||||
|
||||
@@ -3,9 +3,6 @@ title: "Parity Analysis: Bose-SoundTouch (Go) vs. SoundCork (Python)"
|
||||
sidebar:
|
||||
exclude: true
|
||||
---
|
||||
|
||||
# Parity Analysis: Bose-SoundTouch (Go) vs. SoundCork (Python)
|
||||
|
||||
This document provides a comparative analysis of the current Go implementation and the `deborahgu/soundcork` project, identifying functional gaps and potential improvements.
|
||||
|
||||
## 1. Core Architecture and Language
|
||||
|
||||
@@ -3,9 +3,6 @@ title: "Preset Management Quick Start Guide"
|
||||
sidebar:
|
||||
exclude: true
|
||||
---
|
||||
|
||||
# Preset Management Quick Start Guide
|
||||
|
||||
**Save your favorite music, radio stations, and playlists as 1-6 presets for instant access.**
|
||||
|
||||
## Overview
|
||||
|
||||
@@ -3,8 +3,6 @@ title: "Project Structure Patterns: Bose SoundTouch API Client"
|
||||
sidebar:
|
||||
exclude: true
|
||||
---
|
||||
|
||||
# Project Structure Patterns: Bose SoundTouch API Client
|
||||
## Summary for Reuse in API Client Projects
|
||||
|
||||
This document describes the most important patterns for the Bose SoundTouch API client, especially for XML-based API clients with Web UI, CLI tool, and WASM support.
|
||||
|
||||
@@ -3,9 +3,6 @@ title: "Request Recording Concept"
|
||||
sidebar:
|
||||
exclude: true
|
||||
---
|
||||
|
||||
# Request Recording Concept
|
||||
|
||||
## Problem Statement
|
||||
|
||||
The current request recording system has fundamental issues when dealing with request cloning, body consumption, and multiple response scenarios. Specifically:
|
||||
|
||||
@@ -3,9 +3,6 @@ title: "SCMUDC Enrichment Implementation Summary"
|
||||
sidebar:
|
||||
exclude: true
|
||||
---
|
||||
|
||||
# SCMUDC Enrichment Implementation Summary
|
||||
|
||||
## Overview
|
||||
|
||||
This document summarizes the implementation of SCMUDC (Sound Control Management Usage Data Collection) event enrichment in the AfterTouch toolkit. The enhancement provides human-readable analysis of device telemetry data to improve usability and debugging capabilities.
|
||||
|
||||
@@ -3,9 +3,6 @@ title: "Service Availability Implementation Summary"
|
||||
sidebar:
|
||||
exclude: true
|
||||
---
|
||||
|
||||
# Service Availability Implementation Summary
|
||||
|
||||
## Overview
|
||||
|
||||
This document summarizes the implementation of the `/serviceAvailability` endpoint support in the Bose SoundTouch Go client library. This feature enables applications to query which music services and input sources are available on a SoundTouch device, providing better user feedback about supported stations and sources.
|
||||
|
||||
@@ -3,9 +3,6 @@ title: "🎉 Introducing SoundTouch Service: Local Cloud Service Emulation"
|
||||
sidebar:
|
||||
exclude: true
|
||||
---
|
||||
|
||||
# 🎉 Introducing SoundTouch Service: Local Cloud Service Emulation
|
||||
|
||||
**Date**: February 2026
|
||||
**Version**: v2.0.0+
|
||||
**Status**: Production Ready
|
||||
|
||||
@@ -3,8 +3,6 @@ title: "Undocumented Community Features & API Discoveries"
|
||||
sidebar:
|
||||
exclude: true
|
||||
---
|
||||
|
||||
# Undocumented Community Features & API Discoveries
|
||||
This document captures advanced API endpoints and device behaviors discovered by the SoundTouch community through reverse engineering projects like **SoundCork** and **ÜberBöse API**. These features are not documented in the official Bose SoundTouch Web API v1.0 but are crucial for full device emulation and offline operation.
|
||||
## Cloud Emulation (Marge/BMX) Discoveries
|
||||
While the local `/8090` API is well-documented, the cloud-side service emulation reveals deeper device integration points.
|
||||
|
||||
@@ -3,9 +3,6 @@ title: "Unimplemented SoundTouch API Endpoints"
|
||||
sidebar:
|
||||
exclude: true
|
||||
---
|
||||
|
||||
# Unimplemented SoundTouch API Endpoints
|
||||
|
||||
**Last Updated:** January 2026
|
||||
**Source:** [SoundTouch Plus Wiki](https://github.com/thlucas1/homeassistantcomponent_soundtouchplus/wiki/SoundTouch-WebServices-API)
|
||||
**Current Implementation:** 35 endpoints (including preset & navigation management discovered via SoundTouch Plus Wiki)
|
||||
|
||||
@@ -3,9 +3,6 @@ title: "Device Lifecycle and /power_on Enhancement"
|
||||
sidebar:
|
||||
exclude: true
|
||||
---
|
||||
|
||||
# Device Lifecycle and /power_on Enhancement
|
||||
|
||||
## Overview
|
||||
|
||||
This document provides a comprehensive analysis of the current SoundTouch device registration and lifecycle management implementation, and proposes enhancements using the `/power_on` endpoint to reduce dependency on local network connectivity.
|
||||
|
||||
@@ -3,9 +3,6 @@ title: "Device Lifecycle Analysis - Executive Summary"
|
||||
sidebar:
|
||||
exclude: true
|
||||
---
|
||||
|
||||
# Device Lifecycle Analysis - Executive Summary
|
||||
|
||||
## Current State Assessment
|
||||
|
||||
The SoundTouch service currently relies heavily on local network connectivity for device discovery and management:
|
||||
|
||||
@@ -3,9 +3,6 @@ title: "/power_on Implementation Guide"
|
||||
sidebar:
|
||||
exclude: true
|
||||
---
|
||||
|
||||
# /power_on Implementation Guide
|
||||
|
||||
## Overview
|
||||
|
||||
This guide provides detailed technical specifications for implementing `/power_on` endpoint enhancements to reduce network dependency and improve device lifecycle management in the SoundTouch service.
|
||||
|
||||
@@ -3,9 +3,6 @@ title: "SoundTouch `/storePreset` Implementation Guide"
|
||||
sidebar:
|
||||
exclude: true
|
||||
---
|
||||
|
||||
# SoundTouch `/storePreset` Implementation Guide
|
||||
|
||||
## Overview
|
||||
|
||||
This document analyzes the feasibility and implementation approach for adding `/storePreset` functionality to the Bose SoundTouch API client, based on [GitHub Issue #14](https://github.com/gesellix/Bose-SoundTouch/issues/14) and endpoints discovered through the comprehensive [SoundTouch Plus Wiki](https://github.com/thlucas1/homeassistantcomponent_soundtouchplus/wiki/SoundTouch-WebServices-API).
|
||||
|
||||
@@ -3,9 +3,6 @@ title: "SCMUDC Events Analysis"
|
||||
sidebar:
|
||||
exclude: true
|
||||
---
|
||||
|
||||
# SCMUDC Events Analysis
|
||||
|
||||
## Overview
|
||||
|
||||
SCMUDC (Sound Control Management Usage Data Collection) events are telemetry data sent from SoundTouch devices to `events.api.bosecm.com` via `/v1/scmudc/{deviceId}` endpoints. These events track user interactions and device behaviors for analytics and monitoring.
|
||||
|
||||
@@ -3,9 +3,6 @@ title: "soundtouch-web: remaining features"
|
||||
sidebar:
|
||||
exclude: true
|
||||
---
|
||||
|
||||
# soundtouch-web: remaining features
|
||||
|
||||
Four features complete the parity gap between soundtouch-web and the Stockholm
|
||||
app's local-control functionality. Everything else in Stockholm (OAuth flows,
|
||||
setup wizard, service account linking, onboarding, analytics) is cloud
|
||||
|
||||
@@ -3,9 +3,6 @@ title: "Stockholm Backend — Port Guide for Bose-SoundTouch (Go)"
|
||||
sidebar:
|
||||
exclude: true
|
||||
---
|
||||
|
||||
# Stockholm Backend — Port Guide for Bose-SoundTouch (Go)
|
||||
|
||||
This document describes everything needed to integrate the
|
||||
[krahl/soundcork-stockholm-app](https://github.com/krahl/soundcork-stockholm-app)
|
||||
functionality into the Go service. It is written as a reference; nothing here
|
||||
|
||||
@@ -1,9 +1,6 @@
|
||||
---
|
||||
title: "Device-Local Install: Four User Journeys"
|
||||
---
|
||||
|
||||
# Device-Local Install: Four User Journeys
|
||||
|
||||
> **Looking for how to actually install AfterTouch?**
|
||||
> See the [Deployment Overview](../guides/DEPLOYMENT-OVERVIEW.md) for user-friendly
|
||||
> step-by-step guides for both deployment scenarios (external host and on-device).
|
||||
|
||||
@@ -1,9 +1,6 @@
|
||||
---
|
||||
title: "Encrypting Sensitive Data Exports with SSH/age or GPG"
|
||||
---
|
||||
|
||||
# Encrypting Sensitive Data Exports with SSH/age or GPG
|
||||
|
||||
## Problem
|
||||
|
||||
Allow users of our software to export potentially sensitive data, encrypt it locally, and send it to us. We decrypt on our side. Goal: no key exchange, minimal user friction.
|
||||
|
||||
@@ -1,9 +1,6 @@
|
||||
---
|
||||
title: "Amazon Music OAuth Integration"
|
||||
---
|
||||
|
||||
# Amazon Music OAuth Integration
|
||||
|
||||
This document describes the plan and specification for adding Amazon Music OAuth support to the SoundTouch service, enabling continued Amazon Music playback after the Bose cloud shutdown (May 2026).
|
||||
|
||||
The implementation mirrors the [Spotify OAuth integration](spotify-oauth.md) closely. Read that document first — this one calls out only the differences.
|
||||
|
||||
@@ -1,9 +1,6 @@
|
||||
---
|
||||
title: "Spotify OAuth Integration"
|
||||
---
|
||||
|
||||
# Spotify OAuth Integration
|
||||
|
||||
> **New here?** Start with [spotify-overview.md](spotify-overview.md) for the
|
||||
> mental model (Spotify Connect vs OAuth-intercept, DNS rewrite gotcha,
|
||||
> end-to-end token lifecycle). This document zooms in on the OAuth flows and
|
||||
|
||||
@@ -1,9 +1,6 @@
|
||||
---
|
||||
title: "Spotify on SoundTouch — Overview"
|
||||
---
|
||||
|
||||
# Spotify on SoundTouch — Overview
|
||||
|
||||
This is the entry point for understanding how Spotify works on a SoundTouch
|
||||
speaker behind AfterTouch. Read this first; the deeper docs assume you already
|
||||
have the mental model below.
|
||||
|
||||
@@ -1,9 +1,6 @@
|
||||
---
|
||||
title: "Spotify Priming Strategy"
|
||||
---
|
||||
|
||||
# Spotify Priming Strategy
|
||||
|
||||
> **New here?** Start with [spotify-overview.md](spotify-overview.md) for the
|
||||
> mental model. This document goes deep on the priming protocol, ZeroConf DH
|
||||
> exchange, and deployment topologies.
|
||||
|
||||
@@ -1,9 +1,6 @@
|
||||
---
|
||||
title: "Migration Flow Diagrams"
|
||||
---
|
||||
|
||||
# Migration Flow Diagrams
|
||||
|
||||
This document specifies the diagrams needed for the migration guide, with descriptions that can be used to create actual visual diagrams.
|
||||
|
||||
## 1. Overall Migration Process Flow
|
||||
|
||||
@@ -1,9 +1,6 @@
|
||||
---
|
||||
title: "Capture Device Pairing Traffic"
|
||||
---
|
||||
|
||||
# Capture Device Pairing Traffic
|
||||
|
||||
Step-by-step runbook for factory-resetting a SoundTouch speaker, pairing it to a Bose cloud account, and capturing every cloud request via mitmproxy. Tested on Apple Silicon Mac.
|
||||
|
||||
**Goal:** obtain a full `.mitm` recording of the account-pairing flow (streaming.bose.com) triggered by the official Android app.
|
||||
|
||||
@@ -1,9 +1,6 @@
|
||||
---
|
||||
title: "Capture Speaker Migration Traffic"
|
||||
---
|
||||
|
||||
# Capture Speaker Migration Traffic
|
||||
|
||||
Runbook for migrating a SoundTouch speaker to `soundtouch-service` and capturing
|
||||
all traffic (App→Service and Speaker→Service) to identify unimplemented endpoints.
|
||||
|
||||
|
||||
@@ -1,9 +1,6 @@
|
||||
---
|
||||
title: "SoundTouch CLI Reference"
|
||||
---
|
||||
|
||||
# SoundTouch CLI Reference
|
||||
|
||||
**Complete command reference for the soundtouch-cli tool**
|
||||
|
||||
This document provides comprehensive documentation for all available commands and options in the `soundtouch-cli` tool.
|
||||
|
||||
@@ -1,9 +1,6 @@
|
||||
---
|
||||
title: "Cloud Deployment Walkthrough"
|
||||
---
|
||||
|
||||
# Cloud Deployment Walkthrough
|
||||
|
||||
A step-by-step guide to running AfterTouch on a VPS or cloud server and
|
||||
pointing your local Bose SoundTouch speakers at it.
|
||||
|
||||
|
||||
@@ -1,9 +1,6 @@
|
||||
---
|
||||
title: "AfterTouch Deployment Overview"
|
||||
---
|
||||
|
||||
# AfterTouch Deployment Overview
|
||||
|
||||
AfterTouch replaces the Bose SoundTouch cloud, which shut down on 2026-05-06. There are
|
||||
three ways to run it — pick the one that fits your situation.
|
||||
|
||||
|
||||
@@ -1,9 +1,6 @@
|
||||
---
|
||||
title: "SoundTouch Production Deployment Guide"
|
||||
---
|
||||
|
||||
# SoundTouch Production Deployment Guide
|
||||
|
||||
**Best practices for deploying SoundTouch Go applications in production environments**
|
||||
|
||||
This guide covers everything you need to know to deploy robust, scalable SoundTouch applications in production, including configuration management, monitoring, security, and operational considerations.
|
||||
|
||||
@@ -1,9 +1,6 @@
|
||||
---
|
||||
title: "SoundTouch Device Initial Setup Variants"
|
||||
---
|
||||
|
||||
# SoundTouch Device Initial Setup Variants
|
||||
|
||||
Based on community research from the **SoundCork** and **ÜberBöse API** projects, as well as analysis of the Stockholm firmware (`firmware/Stockholm/.../setup/`), this document outlines the methods used for the "out-of-the-box" setup of SoundTouch devices.
|
||||
|
||||
## Setup Overview
|
||||
|
||||
@@ -1,9 +1,6 @@
|
||||
---
|
||||
title: "External Host Walkthrough"
|
||||
---
|
||||
|
||||
# External Host Walkthrough
|
||||
|
||||
A step-by-step guide to running AfterTouch on a Raspberry Pi (or any always-on
|
||||
computer) and migrating your Bose SoundTouch speakers to use it.
|
||||
|
||||
@@ -43,7 +40,7 @@ starts on boot.
|
||||
To install a specific version:
|
||||
|
||||
```bash
|
||||
sudo bash install.sh v0.92.0
|
||||
sudo bash install.sh v0.93.1
|
||||
```
|
||||
|
||||
Check that the service is running:
|
||||
@@ -219,7 +216,7 @@ curl -s http://192.0.2.1:8090/presets
|
||||
|
||||
```bash
|
||||
sudo bash install.sh # updates to latest release
|
||||
sudo bash install.sh v0.93.0 # updates to a specific version
|
||||
sudo bash install.sh v0.93.1 # updates to a specific version
|
||||
```
|
||||
|
||||
The installer stops the service, downloads the new binary, and restarts
|
||||
|
||||
@@ -1,9 +1,6 @@
|
||||
---
|
||||
title: "Getting Started with SoundTouch Go Client"
|
||||
---
|
||||
|
||||
# Getting Started with SoundTouch Go Client
|
||||
|
||||
**A complete guide to controlling your Bose SoundTouch devices with Go**
|
||||
|
||||
This guide will get you up and running with the SoundTouch Go client in under 10 minutes. By the end, you'll be able to discover devices, control playback, manage volume, and monitor real-time events.
|
||||
|
||||
@@ -1,9 +1,6 @@
|
||||
---
|
||||
title: "HTTPS & Custom CA Certificate"
|
||||
---
|
||||
|
||||
# HTTPS & Custom CA Certificate
|
||||
|
||||
SoundTouch speakers communicate with cloud services over HTTPS. For the local service to work over HTTPS, speakers must trust the AfterTouch Root CA. The service manages this automatically — it generates a CA on first start and the web UI guides you through installing it on each speaker as part of the migration flow.
|
||||
|
||||
> ### ⚠️ Speakers connect to `:443`, AfterTouch defaults to `:8443`
|
||||
|
||||
@@ -1,9 +1,6 @@
|
||||
---
|
||||
title: "IoT Implementation Guide"
|
||||
---
|
||||
|
||||
# IoT Implementation Guide
|
||||
|
||||
## Overview
|
||||
|
||||
This guide provides technical implementation details for integrating with the Bose SoundTouch IoT configuration system. It covers the AWS IoT Core integration, certificate management, and device shadow operations.
|
||||
|
||||
@@ -1,9 +1,6 @@
|
||||
---
|
||||
title: "MAC Address to Serial Number Mapping"
|
||||
---
|
||||
|
||||
# MAC Address to Serial Number Mapping
|
||||
|
||||
**Understanding and troubleshooting device identification in SoundTouch service**
|
||||
|
||||
This guide explains how the SoundTouch service handles device identification through MAC address to serial number mapping, and how to troubleshoot related issues.
|
||||
|
||||
@@ -1,9 +1,6 @@
|
||||
---
|
||||
title: "Migration Guide: From Bose Cloud to AfterTouch"
|
||||
---
|
||||
|
||||
# Migration Guide: From Bose Cloud to AfterTouch
|
||||
|
||||
This guide walks through the complete process of migrating your SoundTouch speakers from Bose's cloud services to **AfterTouch**, the replacement provided by `soundtouch-service`. By the end, your speakers will work fully independently of Bose's servers.
|
||||
|
||||
For a shorter overview, see the [Survival Guide](SURVIVAL-GUIDE.md). For safety considerations and rollback options, see the [Migration & Safety Guide](MIGRATION-SAFETY.md).
|
||||
@@ -23,15 +20,28 @@ For a shorter overview, see the [Survival Guide](SURVIVAL-GUIDE.md). For safety
|
||||
|
||||
Choose the option that fits your setup.
|
||||
|
||||
### Binary (go install)
|
||||
### Download a pre-built binary (no Go required)
|
||||
|
||||
Download the latest release for your platform from the
|
||||
[GitHub releases page](https://github.com/gesellix/Bose-SoundTouch/releases).
|
||||
Unzip, make executable, and run:
|
||||
|
||||
```bash
|
||||
go install github.com/gesellix/bose-soundtouch/cmd/soundtouch-service@latest
|
||||
soundtouch-service
|
||||
# Linux / macOS example
|
||||
chmod +x soundtouch-service
|
||||
./soundtouch-service
|
||||
```
|
||||
|
||||
The service starts on port 8000. Open `http://localhost:8000` in your browser.
|
||||
|
||||
### Install script (Raspberry Pi or on-device)
|
||||
|
||||
A one-line installer handles download, installation as a system service, and
|
||||
auto-start on boot. See the
|
||||
[On-Device Install Walkthrough](ON-DEVICE-INSTALL-WALKTHROUGH.md) and
|
||||
[External Host Walkthrough](EXTERNAL-HOST-WALKTHROUGH.md) for the exact
|
||||
commands for each platform.
|
||||
|
||||
### Docker Compose (recommended for home servers and VMs)
|
||||
|
||||
The repository ships a `docker-compose.yml` ready for this use case. Clone or download it, copy the example config, then edit `.env` before starting:
|
||||
@@ -76,8 +86,17 @@ docker run -d \
|
||||
|
||||
On macOS/Windows, device discovery via mDNS won't work inside the container — you'll add devices by IP address in Step 4.
|
||||
|
||||
### go install (if you have Go installed)
|
||||
|
||||
```bash
|
||||
go install github.com/gesellix/bose-soundtouch/cmd/soundtouch-service@latest
|
||||
soundtouch-service
|
||||
```
|
||||
|
||||
See [Raspberry Pi Setup](RASPBERRY-PI.md) and the [SoundTouch Service Guide](SOUNDTOUCH-SERVICE.md) for more deployment options.
|
||||
|
||||
> **Data directory**: all methods store device state, presets, and settings in a `data/` directory next to the binary (or mounted at `/app/data` in Docker). This directory is the single thing you need to back up — copying it is enough to restore a complete AfterTouch installation on a new machine.
|
||||
|
||||
---
|
||||
|
||||
## Step 2: Configure the service URL
|
||||
@@ -110,6 +129,15 @@ The XML migration writes updated configuration to the speaker's filesystem, whic
|
||||
|
||||
You only need to do this once per speaker. SSH can remain enabled for future maintenance or be disabled after migration — your choice.
|
||||
|
||||
**To disable SSH after migration:**
|
||||
|
||||
- **USB stick only (no persistent file written):** remove the stick and reboot the speaker — SSH will not be available after the next boot.
|
||||
- **Persistent `remote_services` file** (written automatically during XML migration): remove it via the admin UI → *Migrate* tab → **Disable SSH (Remove remote_services)** button, then reboot. Or via the CLI:
|
||||
```shell
|
||||
soundtouch-cli --host <SPEAKER-IP> setup remote-services --remove
|
||||
```
|
||||
Then reboot the speaker for the change to take effect.
|
||||
|
||||
### Telnet:17000 (fallback when SSH isn't possible)
|
||||
|
||||
If the USB-stick unlock doesn't work on your speaker (some firmware revisions refuse it — notably SA-5, ST520, and recent ST Portables), the wizard falls back to the speaker's **built-in diagnostic shell on TCP port 17000**. No setup required — most SoundTouch firmware exposes it automatically. The wizard detects which transports are available and picks the right one; you don't have to choose manually.
|
||||
|
||||
@@ -1,9 +1,6 @@
|
||||
---
|
||||
title: "Migration & Safety Guide"
|
||||
---
|
||||
|
||||
# Migration & Safety Guide
|
||||
|
||||
Starting a migration on real hardware requires a "Safety First" approach. This guide outlines the safety features implemented in the `soundtouch-service` and provides a checklist for a successful migration.
|
||||
|
||||
#### 🛠 Technical Safety Enhancements
|
||||
|
||||
@@ -1,9 +1,6 @@
|
||||
---
|
||||
title: "MQTT Integration Design for SoundTouch Service"
|
||||
---
|
||||
|
||||
# MQTT Integration Design for SoundTouch Service
|
||||
|
||||
## Overview
|
||||
|
||||
This document outlines the design for integrating MQTT support into the existing SoundTouch service to simulate AWS IoT Core functionality. The integration will provide real-time device communication, shadow state management, and prepare for the AWS IoT service shutdown in May 2026.
|
||||
|
||||
@@ -1,9 +1,6 @@
|
||||
---
|
||||
title: "Connecting Music Services (Spotify & Amazon Music)"
|
||||
---
|
||||
|
||||
# Connecting Music Services (Spotify & Amazon Music)
|
||||
|
||||
This guide explains how to link your Spotify or Amazon Music account to AfterTouch so your speakers can stream music from those services.
|
||||
|
||||
> For Spotify, a higher-level mental model of how the integration works —
|
||||
|
||||
@@ -1,9 +1,6 @@
|
||||
---
|
||||
title: "On-Device Install Walkthrough"
|
||||
---
|
||||
|
||||
# On-Device Install Walkthrough
|
||||
|
||||
A complete end-to-end runbook for installing AfterTouch directly on a
|
||||
Bose SoundTouch speaker — from first SSH connection through verified
|
||||
radio preset playback.
|
||||
@@ -103,7 +100,7 @@ Verify the installed version:
|
||||
wget -qO- http://localhost:8000/health
|
||||
```
|
||||
|
||||
The JSON response should include `"version":"v0.92.0"` (or whichever
|
||||
The JSON response should include `"version":"v0.93.1"` (or whichever
|
||||
version you installed).
|
||||
|
||||
---
|
||||
@@ -191,13 +188,13 @@ next reboot — which is fine for a one-time setup run):
|
||||
cd /tmp
|
||||
|
||||
curl -L --fail -o soundtouch-cli \
|
||||
https://github.com/gesellix/Bose-SoundTouch/releases/download/v0.92.0/soundtouch-cli-v0.92.0-linux-armv7
|
||||
https://github.com/gesellix/Bose-SoundTouch/releases/download/v0.93.1/soundtouch-cli-v0.93.1-linux-armv7
|
||||
chmod +x soundtouch-cli
|
||||
|
||||
/tmp/soundtouch-cli --version
|
||||
```
|
||||
|
||||
Replace `v0.92.0` with the version you installed.
|
||||
Replace `v0.93.1` with the version you installed.
|
||||
|
||||
---
|
||||
|
||||
|
||||
@@ -1,9 +1,6 @@
|
||||
---
|
||||
title: "Raspberry Pi Installation Guide"
|
||||
---
|
||||
|
||||
# Raspberry Pi Installation Guide
|
||||
|
||||
This guide explains how to install the `soundtouch-service` as a persistent systemd service on a Raspberry Pi (tested on Raspberry Pi Zero 2W, 3, and 4).
|
||||
|
||||
For a complete walkthrough — from install through speaker migration and preset setup — see
|
||||
@@ -39,7 +36,7 @@ You can customize the installation using environment variables:
|
||||
|
||||
```bash
|
||||
sudo \
|
||||
VERSION=v0.92.0 \
|
||||
VERSION=v0.93.1 \
|
||||
HOSTNAME_FQDN=soundtouch.local \
|
||||
HTTP_PORT=80 \
|
||||
HTTPS_PORT=443 \
|
||||
@@ -51,7 +48,7 @@ sudo \
|
||||
To update the service to a specific version, run the installer with the version as an argument:
|
||||
|
||||
```bash
|
||||
sudo bash install.sh v0.92.0
|
||||
sudo bash install.sh v0.93.1
|
||||
```
|
||||
|
||||
The installer will automatically fetch the latest version of itself for that release and then update the service binary and restart it.
|
||||
|
||||
@@ -1,9 +1,6 @@
|
||||
---
|
||||
title: "Self-Hosting AfterTouch"
|
||||
---
|
||||
|
||||
# Self-Hosting AfterTouch
|
||||
|
||||
This guide walks you through running AfterTouch on your own computer or server. No programming knowledge required.
|
||||
|
||||
---
|
||||
|
||||
@@ -1,9 +1,6 @@
|
||||
---
|
||||
title: "SoundTouch Service"
|
||||
---
|
||||
|
||||
# SoundTouch Service
|
||||
|
||||
The `soundtouch-service` is a comprehensive local server that emulates Bose's cloud services, enabling offline SoundTouch device operation and advanced debugging capabilities. This service is particularly valuable given Bose's announcement that cloud support will end in May 2026.
|
||||
|
||||
## Overview
|
||||
@@ -28,10 +25,13 @@ The service consists of several key components:
|
||||
|
||||
### BMX Services (Bose Media eXchange)
|
||||
- **TuneIn Integration**: Direct playback of radio stations and podcasts
|
||||
- **RadioBrowser Integration**: Open community radio directory alongside TuneIn
|
||||
- **Custom Streams**: Flexible playback of any internet radio URL via dynamic proxy
|
||||
- **Service Registry**: Media service discovery and configuration
|
||||
- **Playback Control**: Stream URL resolution and audio metadata
|
||||
|
||||

|
||||
|
||||
### Marge Services (Account & Device Management)
|
||||
- **Account Management**: User account simulation and device association
|
||||
- **Preset Synchronization**: Cross-device preset storage and sync
|
||||
|
||||
@@ -1,9 +1,6 @@
|
||||
---
|
||||
title: "Keeping Your Speakers Alive After the Bose Cloud Shutdown"
|
||||
---
|
||||
|
||||
# Keeping Your Speakers Alive After the Bose Cloud Shutdown
|
||||
|
||||
Bose shut down SoundTouch cloud services on **May 6, 2026**. Per the [official end-of-life page](https://www.bose.com/soundtouch-end-of-life), the following no longer work:
|
||||
|
||||
- **Presets** — preset buttons on the product and in the app
|
||||
|
||||
@@ -1,9 +1,6 @@
|
||||
---
|
||||
title: "SoundTouch Troubleshooting Guide"
|
||||
---
|
||||
|
||||
# SoundTouch Troubleshooting Guide
|
||||
|
||||
**Complete guide to diagnosing and fixing common SoundTouch Go client issues**
|
||||
|
||||
This guide helps you quickly identify and resolve problems with the SoundTouch Go client library. Issues are organized by category with step-by-step solutions.
|
||||
|
||||
@@ -1,9 +1,6 @@
|
||||
---
|
||||
title: "SoundTouch API Cookbook"
|
||||
---
|
||||
|
||||
# SoundTouch API Cookbook
|
||||
|
||||
**Real-world patterns, recipes, and best practices for the SoundTouch Go client**
|
||||
|
||||
This cookbook provides practical solutions to common SoundTouch integration challenges. Each recipe includes working code, error handling, and production considerations.
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user