{"id":50956743,"url":"https://github.com/botify-network/soundsync","last_synced_at":"2026-06-18T08:01:58.273Z","repository":{"id":359182349,"uuid":"1120303115","full_name":"Botify-Network/soundsync","owner":"Botify-Network","description":"SoundSync by Botify — Windows Electron tray app that auto-syncs SoundCloud likes + playlists to a local folder via yt-dlp + ffmpeg.","archived":false,"fork":false,"pushed_at":"2026-06-10T07:39:03.000Z","size":18141,"stargazers_count":0,"open_issues_count":3,"forks_count":0,"subscribers_count":0,"default_branch":"master","last_synced_at":"2026-06-10T09:17:53.246Z","etag":null,"topics":["botify","desktop-app","electron","ffmpeg","music","soundcloud","windows","yt-dlp"],"latest_commit_sha":null,"homepage":null,"language":"JavaScript","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":null,"status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/Botify-Network.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":null,"code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null,"zenodo":null,"notice":null,"maintainers":null,"copyright":null,"agents":null,"dco":null,"cla":null}},"created_at":"2025-12-20T23:06:46.000Z","updated_at":"2026-06-10T07:36:49.000Z","dependencies_parsed_at":null,"dependency_job_id":null,"html_url":"https://github.com/Botify-Network/soundsync","commit_stats":null,"previous_names":["high-texas-list/sc-auto-downloader","botify-network/soundsync"],"tags_count":5,"template":false,"template_full_name":null,"purl":"pkg:github/Botify-Network/soundsync","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/Botify-Network%2Fsoundsync","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/Botify-Network%2Fsoundsync/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/Botify-Network%2Fsoundsync/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/Botify-Network%2Fsoundsync/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/Botify-Network","download_url":"https://codeload.github.com/Botify-Network/soundsync/tar.gz/refs/heads/master","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/Botify-Network%2Fsoundsync/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":34481332,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-05-26T15:22:16.424Z","status":"online","status_checked_at":"2026-06-18T02:00:06.871Z","response_time":128,"last_error":null,"robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":true,"can_crawl_api":true,"host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["botify","desktop-app","electron","ffmpeg","music","soundcloud","windows","yt-dlp"],"created_at":"2026-06-18T08:01:57.393Z","updated_at":"2026-06-18T08:01:58.260Z","avatar_url":"https://github.com/Botify-Network.png","language":"JavaScript","funding_links":[],"categories":[],"sub_categories":[],"readme":"# SoundSync by Botify\n\n\u003cp align=\"center\"\u003e\n  \u003cimg src=\"assets/brand/SoundSync_transparent_banner_trimmed.png\" alt=\"SoundSync by Botify\" width=\"640\"/\u003e\n\u003c/p\u003e\n\n\u003cp align=\"center\"\u003e\n  \u003ca href=\"https://github.com/Botify-Network/soundsync/releases/latest\"\u003e\u003cimg alt=\"Latest release\" src=\"https://img.shields.io/github/v/release/Botify-Network/soundsync?display_name=tag\u0026sort=semver\"\u003e\u003c/a\u003e\n  \u003cimg alt=\"Platform\" src=\"https://img.shields.io/badge/platform-Windows%20x64-0078d6\"\u003e\n  \u003cimg alt=\"Runtime\" src=\"https://img.shields.io/badge/runtime-Electron%2028-2b2e3a\"\u003e\n  \u003cimg alt=\"License\" src=\"https://img.shields.io/badge/license-MIT-22c55e\"\u003e\n  \u003cimg alt=\"Governance\" src=\"https://img.shields.io/badge/governed%20by-Botify-8a5cff\"\u003e\n\u003c/p\u003e\n\n**SoundSync by Botify** — Windows Electron tray app that auto-syncs SoundCloud likes and playlists to a local folder using **yt-dlp** + **ffmpeg**.\n\n\u003e Previously released as *SoundCloud Auto Sync / SC Auto Downloader*. Rebranded to **SoundSync** in v2.0.6.\n\n**Current version:** v2.0.7\n\n---\n\n## Contents\n\n- [What it does](#what-it-does)\n- [Install / update](#install--update)\n- [Basic usage](#basic-usage)\n- [Update controls](#update-controls)\n- [Architecture](#architecture)\n- [Security](#security)\n- [Developer setup](#developer-setup)\n- [Troubleshooting](#troubleshooting)\n- [CLI](#cli)\n- [Brand assets](#brand-assets)\n- [Project links](#project-links)\n- [License](#license)\n\n---\n\n## What it does\n\n- Runs in the system tray; no foreground window required.\n- Monitors a list of SoundCloud usernames (their public likes) and playlist URLs.\n- On an interval, fetches new tracks and downloads them as MP3 with embedded metadata + artwork.\n- One-off **Download URL...** entry point for any SoundCloud track or playlist.\n- Tray menu surfaces status (Syncing / Idle / Error), last-sync time, and download count.\n- Auto-update via GitHub Releases through `electron-updater` (configurable — see [Update controls](#update-controls)).\n\n## Install / update\n\nInstall via the released NSIS installer published on GitHub:\n\n- Releases: https://github.com/Botify-Network/soundsync/releases\n- Latest release: see the **Latest release** badge above.\n\n### Auto-updater artifact requirement\n\n`electron-updater` only detects an update when the target GitHub Release has **both** the packaged installer **and** the manifest attached:\n\n- `SoundSync Setup \u003cversion\u003e.exe` — NSIS installer produced by `electron-builder`\n- `latest.yml` — manifest `electron-updater` reads\n\nA notes-only release (tag + body, no binaries) **will not be detected** by installed clients. See [`docs/deployment.md`](docs/deployment.md) for the full release flow.\n\n## Basic usage\n\n1. Launch the app (it minimizes to the tray; double-click the tray icon to open Settings).\n2. **Downloads** page → choose a download folder.\n3. **Monitoring** page → add SoundCloud usernames (their `/likes` are followed) and/or full playlist URLs (must contain `/sets/`).\n4. Toggle **Auto-sync on launch** in **Startup** to begin monitoring immediately on app start.\n5. Set **Sync interval** (default 15 min).\n6. **Sync Now** from the tray menu or footer button forces an immediate sync.\n\nSee [`docs/operator.md`](docs/operator.md) for the full tray + settings walkthrough.\n\n## Update controls\n\nSettings → Startup / App Updates card:\n\n| Setting | Default | Effect |\n|---|---|---|\n| **Check for updates automatically** | on | Startup check + background download via `electron-updater` |\n| **Install updates on next restart** | on | Apply downloaded update silently when app quits. Off = wait for explicit \"Install now\" |\n| **Check for updates** (button) | n/a | Manual on-demand check; works regardless of the auto-check toggle |\n| **Install now** (button) | n/a | Triggers `quitAndInstall()` when a downloaded update is pending |\n\nUpdate errors surface as tray balloons.\n\n## Architecture\n\n```\n┌─ Tray menu ────────┐    ┌─ Settings window (Electron renderer) ─┐\n│ Status / Sync Now  │    │  Dashboard · Downloads · Monitoring   │\n│ Pause / Auto-Sync  │    │  Engine · Diagnostics                 │\n└─────────┬──────────┘    └────────────────┬──────────────────────┘\n          │                                │\n          │   IPC (contextIsolation: true) │\n          └────────────────┬───────────────┘\n                           │\n                  ┌────────▼──────────────────────────────────────┐\n                  │ Electron main (src/main.js)                   │\n                  │ · Lifecycle · Tray · IPC handlers · Updater   │\n                  │ · electron-store settings                     │\n                  └──┬──────────────┬─────────────────┬───────────┘\n                     │              │                 │\n        ┌────────────▼──┐  ┌────────▼─────────┐  ┌────▼──────────────────┐\n        │ services/     │  │ services/        │  │ services/paths.js      │\n        │ downloader.js │  │ soundcloud-      │  │ (yt-dlp / ffmpeg path  │\n        │ (queue +      │  │ monitor.js       │  │  resolution: bundled   │\n        │  rate-limit + │  │ (sync loop +     │  │  resources/ → PATH     │\n        │  encode)      │  │  URL validation) │  │  fallback)             │\n        └────────┬──────┘  └────────┬─────────┘  └────┬───────────────────┘\n                 │                  │                 │\n                 └──────────────────┴─────┬───────────┘\n                                          │\n                              ┌───────────▼──────────────┐\n                              │ Bundled tools            │\n                              │ resources/yt-dlp.exe     │\n                              │ resources/ffmpeg.exe     │\n                              └──────────────────────────┘\n```\n\nFull architecture details: [`docs/architecture.md`](docs/architecture.md).\n\n## Security\n\nHighlights (full policy in [`SECURITY.md`](SECURITY.md), full hardening notes in [`docs/security.md`](docs/security.md)):\n\n- **Renderer XSS fix** — settings UI never injects user-supplied usernames / playlist URLs / titles via `innerHTML`. All list-item construction uses `createElement` + `textContent`.\n- **Safer process execution** — main-process diagnostics and `fetch-playlist-metadata` (which receives a user-controlled URL) do not shell-interpolate. All `yt-dlp` and `ffmpeg` invocations use argv arrays via `spawn` / `execFile`.\n- **CLI hardening** — `cli.js` shell-interpolated calls converted to `execFileSync` with argv arrays.\n- **Rate-limit / network hardening** — `yt-dlp` calls pass `--retries 10`, `--retry-sleep http:exp=1:30`, `--socket-timeout 30`, `--sleep-requests 1`; 3-attempt app-level retry with 15s/30s/60s backoff; 90s queue cooldown on 429.\n- **Configurable auto-updater** — checks, downloads, and install-on-quit can each be disabled.\n- **Electron security** — `contextIsolation: true`, `nodeIntegration: false`, whitelisted preload bridge.\n\n## Developer setup\n\n```bash\nnpm install\nnpm start                  # launches Electron pointing at src/main.js\n```\n\nRequires `yt-dlp` and `ffmpeg` either bundled in `resources/` (preferred — picked up by `getYtDlpPath()` / `getFfmpegPath()`) or on `PATH`.\n\n### Syntax checks (no test suite yet — see [#2](https://github.com/Botify-Network/soundsync/issues/2))\n\n```bash\nnode --check src/main.js\nnode --check src/preload.js\nnode --check cli.js\nnode --check src/services/downloader.js\nnode --check src/services/soundcloud-monitor.js\n```\n\n### Build (Windows installer)\n\n```bash\nnpm run build:win\n```\n\n- `prebuild` / `prebuild:win` auto-run `scripts/bump-version.js` (patch bump). To build without bumping, run `electron-builder --win` directly.\n- Output goes to `dist/`. Both `SoundSync Setup \u003cversion\u003e.exe` and `latest.yml` must be uploaded to the GitHub Release for the auto-updater to detect the new version.\n\n### Version bump (manual)\n\n```bash\nnpm run bump            # patch:  2.0.7 → 2.0.8\nnpm run bump:minor      # minor:  2.0.7 → 2.1.0\nnpm run bump:major      # major:  2.0.7 → 3.0.0\n```\n\nFull developer guide: [`docs/developer.md`](docs/developer.md).\n\n## Troubleshooting\n\n| Symptom | Cause | Fix |\n|---|---|---|\n| Sync stalls, no new downloads | SoundCloud rate-limit (429) | App auto-applies 90s queue cooldown + 3-attempt backoff. Wait or reduce monitored sources. |\n| `yt-dlp not found` in diagnostics | Bundled `resources/yt-dlp.exe` missing and not on `PATH` | Install yt-dlp globally or restore the bundled binary. |\n| `ffmpeg not found` in diagnostics | Same as above for ffmpeg. | Install ffmpeg globally or restore the bundled binary. |\n| Auto-updater never finds new version | Release missing `latest.yml` or `SoundSync Setup \u003cversion\u003e.exe` | Re-upload both artifacts to the release; see [auto-updater artifact requirement](#auto-updater-artifact-requirement). |\n| Google Drive File Stream download path errors | Drive virtual mount not present | Diagnostics now hints when `My Drive` is unavailable; mount Drive or pick a local folder. |\n| Tray icon missing after install | App didn't acquire single-instance lock | Quit any existing SoundSync process, relaunch. |\n\nFull guide: [`docs/troubleshooting.md`](docs/troubleshooting.md).\n\n## CLI\n\n`cli.js` provides a console interface independent of the Electron app:\n\n```bash\nnode cli.js test        # diagnostics\nnode cli.js config      # interactive configure\nnode cli.js settings    # show current config\nnode cli.js sync        # run a sync now\nnode cli.js install     # install deps + check bundled tools\nnode cli.js gui         # launch the Electron app\n```\n\n\u003e ⚠️ The CLI maintains its own config at `%APPDATA%\\soundsync\\config.json` (separate from the Electron app's `electron-store`). It reads the legacy `%APPDATA%\\soundcloud-auto-sync\\config.json` if the new path doesn't exist. **The CLI's `sync` path does not yet share the rate-limit hardening that the Electron sync uses** — tracked in [#2](https://github.com/Botify-Network/soundsync/issues/2).\n\n## Brand assets\n\nLocal brand pack lives in [`assets/brand/`](assets/brand/) and is governed by the Botify design tokens. Runtime assets used by the app:\n\n- `SoundSync_app_icon_{64,128,256,512}.png` — app icon (rounded-square master with radar rings)\n- `SoundSync_badge_orb_512.png` — circular badge variant\n- `SoundSync_sidebar_logo_{128,256,512}.png` — sharpened sidebar mark (minimal style, optimized for small render)\n- `SoundSync_favicon_{16,32}.png` — favicon set\n- `SoundSync_taskbar_icon.ico` — multi-size Windows .ico (16/32/48/64/128/256)\n- `SoundSync_transparent_banner_{2048x682,trimmed}.png` — README / about banner\n\nSource 1254×1254 masters and the runtime contact sheet live in [`design/soundsync-template-review/`](design/soundsync-template-review/).\n\n## Project links\n\n- **Repository:** https://github.com/Botify-Network/soundsync\n- **Releases:** https://github.com/Botify-Network/soundsync/releases\n- **Issues:** https://github.com/Botify-Network/soundsync/issues\n- **Docs initiative:** [#1](https://github.com/Botify-Network/soundsync/issues/1)\n- **Engineering cleanup initiative:** [#2](https://github.com/Botify-Network/soundsync/issues/2)\n- **Governance hub (parent org):** Botify-Network/botify-network-site\n\n## Contributing\n\nSee [`CONTRIBUTING.md`](CONTRIBUTING.md). All PRs require operator approval before merge. No deploys without explicit operator approval. No secrets in any commit, issue, comment, or attachment.\n\n## Changelog\n\nSee [`CHANGELOG.md`](CHANGELOG.md).\n\n## License\n\nMIT — see [`package.json`](package.json).\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fbotify-network%2Fsoundsync","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fbotify-network%2Fsoundsync","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fbotify-network%2Fsoundsync/lists"}