Skip to content

Commit 20ee504

Browse files
committed
update readme and include automation docs
1 parent d57b48a commit 20ee504

File tree

2 files changed

+258
-1
lines changed

2 files changed

+258
-1
lines changed

README.md

Lines changed: 21 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -105,6 +105,14 @@ SoulSync bridges streaming services to your media server with automated discover
105105

106106
### Automation
107107

108+
**Automation Engine** - Visual drag-and-drop builder for custom workflows
109+
- **Triggers**: Schedule (interval/daily/weekly), Track Downloaded, Batch Complete, Playlist Changed, Discovery Complete, and 10+ more event types
110+
- **Actions**: Process Wishlist, Scan Watchlist, Refresh Mirrored Playlist, Discover Playlist, Sync Playlist, Scan Library, Update Database, Run Duplicate Cleaner, Quality Scan, and more
111+
- **Notifications**: Discord webhooks, Pushbullet, Telegram — with variable substitution for dynamic messages
112+
- **Conditions**: Filter triggers by artist, title, playlist name, quality, and other fields with contains/equals/starts_with operators
113+
- **System Automations**: Built-in wishlist processing (every 30 min) and watchlist scanning (every 24 hr) — configurable but non-deletable
114+
- **Playlist Discovery Pipeline**: Automatically discovers official Spotify/iTunes metadata for YouTube/Tidal mirrored playlists, ensuring nothing syncs or downloads without verified context
115+
108116
**Watchlist** - Monitor unlimited artists with per-artist configuration
109117
- Choose which release types to track: Albums, EPs, Singles
110118
- Content filters: Live, Remixes, Acoustic, Compilations
@@ -116,6 +124,16 @@ SoulSync bridges streaming services to your media server with automated discover
116124
- Organized by category (albums vs singles)
117125
- Cleanup tool removes tracks you've since acquired
118126

127+
**Mirrored Playlists** - Mirror playlists from Spotify, Tidal, or YouTube and keep them synced
128+
- Automatic refresh detects track additions and removals from source
129+
- Discovery pipeline matches raw YouTube/Tidal tracks to official Spotify/iTunes metadata
130+
- Sync to media server using verified metadata — undiscovered tracks are held back, not synced with garbage data
131+
132+
**Local Profiles** - Multiple configuration profiles for different setups or users
133+
- Each profile maintains its own watchlist, wishlist, playlists, and automation settings
134+
- Switch between profiles from the UI — all settings and data are isolated
135+
- System automations (wishlist/watchlist) appear across all profiles
136+
119137
**Background Tasks** - Database sync, discovery pool updates, seasonal content, watchlist scanning
120138

121139
### Library Management
@@ -334,6 +352,8 @@ If you're using the Unraid template from Community Applications:
334352
| Quality Scanner + Duplicate Cleaner | ✓ | ✗ | ✗ | ✓ |
335353
| Template-Based Organization | ✓ | ✗ | ✗ | ✓ |
336354
| Built-in Streaming Player | ✓ | ✗ | ✗ | ✗ |
355+
| Visual Automation Builder | ✓ | ✗ | ✗ | ✗ |
356+
| Multi-Profile Support | ✓ | ✗ | ✗ | ✗ |
337357
| Import Existing Files | ✓ | ✓ | ✗ | ✓ |
338358
| Web UI | ✓ | ✓ | ✓ | ✗ |
339359

@@ -353,6 +373,7 @@ If you're using the Unraid template from Community Applications:
353373
- **Discovery System** — custom algorithms for personalized playlists, seasonal content, and similar artist exploration
354374
- **Metadata Pipeline** — dual-source (Spotify/iTunes) with MusicBrainz enrichment, AcoustID verification, LRC lyrics, album art embedding via mutagen
355375
- **Database Update Worker** — incremental sync from media servers with smart early-stopping (Jellyfin fast-path: ~2 API calls vs thousands)
376+
- **Automation Engine** — event-driven workflow builder with triggers, actions, conditions, notifications, and cross-action guards
356377
- **Web Scan Manager** — debounced media server scanning with completion callbacks
357378
- **Template-based File Organization** — configurable folder structures with automatic fallback
358379

@@ -402,7 +423,6 @@ Transfer/Artist/Artist - Album/01 - Track.flac
402423
- Batch wishlist operations
403424
- Download history browser UI
404425
- Source reliability tracking
405-
- Notification center
406426
- Mobile-responsive improvements
407427
408428
### Under Consideration

Support/AUTOMATIONS.md

Lines changed: 237 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,237 @@
1+
# Automations Guide
2+
3+
## Overview
4+
5+
The Automations page lets you build custom workflows that run automatically. Each automation connects a **trigger** (when to run) to an **action** (what to do), with optional **conditions** (filters) and **notifications** (alerts when it runs).
6+
7+
Navigate to the Automations page from the sidebar. You'll see your automation cards and a builder panel for creating new ones.
8+
9+
---
10+
11+
## Building an Automation
12+
13+
### The Builder
14+
15+
The builder has three slots:
16+
17+
- **WHEN** — drag a trigger here (required)
18+
- **DO** — drag an action here (required)
19+
- **NOTIFY** — drag a notification method here (optional)
20+
21+
Drag blocks from the sidebar into the slots. Each block expands to show its configuration fields. Give your automation a name and click **Save**.
22+
23+
### Conditions
24+
25+
Event-based triggers support conditions to filter when they fire. For example, a "Track Downloaded" trigger can have a condition like `artist contains "Taylor"` so it only fires for specific artists.
26+
27+
- **Match mode**: "All" (every condition must pass) or "Any" (at least one must pass)
28+
- **Operators**: contains, equals, starts_with, not_contains
29+
30+
### Delay
31+
32+
Action blocks have an optional **Delay** field (in minutes). The action waits that long after the trigger fires before executing. Useful for letting other processes finish first.
33+
34+
---
35+
36+
## Triggers
37+
38+
### Timer-Based
39+
40+
| Trigger | Description | Configuration |
41+
|---------|-------------|---------------|
42+
| **Schedule** | Run on a repeating interval | Interval + unit (minutes/hours/days) |
43+
| **Daily Time** | Run every day at a specific time | Time picker (e.g., 03:00) |
44+
| **Weekly Schedule** | Run on specific days at a set time | Day selector + time picker |
45+
46+
### Event-Based
47+
48+
| Trigger | Fires When | Condition Fields | Variables |
49+
|---------|-----------|-----------------|-----------|
50+
| **App Started** | SoulSync starts up |||
51+
| **Track Downloaded** | A track finishes downloading | artist, title, album, quality | artist, title, album, quality |
52+
| **Batch Complete** | An album/playlist download finishes | playlist_name | playlist_name, total_tracks, completed_tracks, failed_tracks |
53+
| **New Release Found** | Watchlist detects new music | artist | artist, new_tracks, added_to_wishlist |
54+
| **Playlist Synced** | A playlist sync completes | playlist_name | playlist_name, total_tracks, matched_tracks, synced_tracks, failed_tracks |
55+
| **Playlist Changed** | A mirrored playlist detects track changes | playlist_name | playlist_name, old_count, new_count, added, removed |
56+
| **Discovery Complete** | Playlist track discovery finishes | playlist_name | playlist_name, total_tracks, discovered_count, failed_count, skipped_count |
57+
| **Wishlist Processed** | Auto-wishlist processing finishes || tracks_processed, tracks_found, tracks_failed |
58+
| **Watchlist Scan Done** | Watchlist scan finishes || artists_scanned, new_tracks_found, tracks_added |
59+
| **Database Updated** | Library database refresh finishes || total_artists, total_albums, total_tracks |
60+
| **Download Failed** | A track permanently fails to download | artist, title, reason | artist, title, reason |
61+
| **File Quarantined** | AcoustID verification fails | artist, title | artist, title, reason |
62+
| **Wishlist Item Added** | A track is added to wishlist | artist, title | artist, title, reason |
63+
| **Artist Watched** | An artist is added to watchlist | artist | artist, artist_id |
64+
| **Artist Unwatched** | An artist is removed from watchlist | artist | artist, artist_id |
65+
| **Import Complete** | Album/track import finishes | artist, album_name | track_count, album_name, artist |
66+
| **Playlist Mirrored** | A new playlist is mirrored | playlist_name, source | playlist_name, source, track_count |
67+
| **Quality Scan Done** | Quality scan finishes || quality_met, low_quality, total_scanned |
68+
| **Duplicate Scan Done** | Duplicate cleaner finishes || files_scanned, duplicates_found, space_freed |
69+
70+
---
71+
72+
## Actions
73+
74+
| Action | Description | Configuration |
75+
|--------|-------------|---------------|
76+
| **Process Wishlist** | Retry failed downloads from wishlist | Category: All, Albums, or Singles |
77+
| **Scan Watchlist** | Check watched artists for new releases ||
78+
| **Scan Library** | Trigger media server library scan ||
79+
| **Refresh Mirrored Playlist** | Re-fetch playlist from source (Spotify/Tidal/YouTube) and update the mirror | Select playlist or "Refresh all" |
80+
| **Discover Playlist** | Find official Spotify/iTunes metadata for mirrored playlist tracks | Select playlist or "Discover all" |
81+
| **Sync Playlist** | Sync mirrored playlist to media server (only discovered tracks are included) | Select playlist |
82+
| **Notify Only** | No action — just send the notification ||
83+
| **Update Database** | Trigger library database refresh | Full refresh checkbox |
84+
| **Run Duplicate Cleaner** | Scan for and remove duplicate files ||
85+
| **Clear Quarantine** | Delete all quarantined files ||
86+
| **Clean Up Wishlist** | Remove duplicate/already-owned tracks from wishlist ||
87+
| **Update Discovery** | Refresh discovery pool with new tracks ||
88+
| **Run Quality Scan** | Scan for low-quality audio files | Scope: Watchlist Artists or Full Library |
89+
| **Backup Database** | Create timestamped database backup ||
90+
91+
---
92+
93+
## Notifications
94+
95+
Add a notification block to get alerted when an automation runs.
96+
97+
| Method | Configuration | Notes |
98+
|--------|---------------|-------|
99+
| **Discord Webhook** | Webhook URL + message template | Posts to a Discord channel |
100+
| **Pushbullet** | Access token + title + message | Push to phone/desktop |
101+
| **Telegram** | Bot token + chat ID + message | Sends via Telegram Bot API |
102+
103+
### Variable Substitution
104+
105+
Notification messages support `{variable}` placeholders that get replaced with actual values when the automation runs.
106+
107+
**Always available**: `{time}`, `{name}` (automation name), `{run_count}`, `{status}`
108+
109+
**Event-specific**: Each trigger provides additional variables (see the Variables column in the triggers table above). For example, a "Track Downloaded" trigger provides `{artist}`, `{title}`, `{album}`, `{quality}`.
110+
111+
**Example message**:
112+
```
113+
Downloaded {title} by {artist} from {album} — quality: {quality}
114+
```
115+
116+
---
117+
118+
## System Automations
119+
120+
SoulSync includes two built-in system automations that cannot be deleted:
121+
122+
| Automation | Schedule | Initial Delay |
123+
|-----------|----------|---------------|
124+
| **Auto-Process Wishlist** | Every 30 minutes | 1 minute after startup |
125+
| **Auto-Scan Watchlist** | Every 24 hours | 5 minutes after startup |
126+
127+
These appear with a "System" badge on their cards. You can:
128+
- Change the interval
129+
- Enable or disable them
130+
- Add notifications
131+
132+
You cannot:
133+
- Delete them
134+
- Change the trigger or action type
135+
136+
---
137+
138+
## Mirrored Playlist Sync Pipeline
139+
140+
For mirrored playlists (especially from YouTube and Tidal), a multi-step automation chain ensures tracks are synced with proper metadata:
141+
142+
### The Problem
143+
144+
YouTube and Tidal playlists have raw metadata — cleaned video titles, uploader names. If you sync these directly, unmatched tracks hit the wishlist with garbage data (no Spotify ID, wrong album, no cover art). Downloads would fail or get the wrong track.
145+
146+
### The Solution
147+
148+
Three automations chained via events:
149+
150+
**Step 1: Refresh** — Re-fetch the playlist from its source
151+
```
152+
WHEN: Schedule (every 6 hours)
153+
DO: Refresh Mirrored Playlist (all)
154+
```
155+
This detects added/removed tracks by comparing source track IDs. If changes are found, it emits a "Playlist Changed" event.
156+
157+
**Step 2: Discover** — Match raw tracks to official Spotify/iTunes metadata
158+
```
159+
WHEN: Playlist Changed
160+
DO: Discover Playlist (all)
161+
```
162+
For each undiscovered track, the discovery pipeline:
163+
1. Checks the discovery cache (instant if previously matched)
164+
2. Searches Spotify (preferred) or iTunes (fallback) using the matching engine
165+
3. Scores candidates with title/artist fuzzy matching
166+
4. Stores the official match (Spotify ID, proper title, artist, album) on the track
167+
168+
When done, emits a "Discovery Complete" event.
169+
170+
**Step 3: Sync** — Push to media server with verified metadata
171+
```
172+
WHEN: Discovery Complete
173+
DO: Sync Playlist (select playlist)
174+
```
175+
Only discovered tracks are included in the sync. Undiscovered tracks are skipped entirely — they never reach the wishlist with bad data. Unmatched discovered tracks go to the wishlist with proper Spotify/iTunes IDs and album context.
176+
177+
### Spotify Playlists
178+
179+
Spotify-sourced mirrored playlists skip Step 2 automatically. Their data is already official, so tracks are marked as discovered during refresh with confidence 1.0. You can go directly from "Playlist Changed" to "Sync Playlist".
180+
181+
### Discovery Caching
182+
183+
Discovery results are cached globally. If the same track appears in multiple playlists, or was discovered previously, the cache provides instant results without hitting the Spotify/iTunes API again. The cache persists across restarts.
184+
185+
---
186+
187+
## Examples
188+
189+
### Get notified when a watched artist drops new music
190+
```
191+
WHEN: New Release Found (artist contains "Kendrick")
192+
DO: Notify Only
193+
NOTIFY: Discord Webhook — "{artist} dropped {new_tracks} new tracks!"
194+
```
195+
196+
### Nightly library maintenance
197+
```
198+
WHEN: Daily Time (03:00)
199+
DO: Update Database (full refresh)
200+
```
201+
202+
### Auto-download wishlist failures every hour
203+
```
204+
WHEN: Schedule (every 1 hour)
205+
DO: Process Wishlist (all)
206+
NOTIFY: Telegram — "Wishlist processed: {tracks_found} found, {tracks_failed} failed"
207+
```
208+
209+
### Quality upgrade pipeline
210+
```
211+
WHEN: Database Updated
212+
DO: Run Quality Scan (watchlist artists)
213+
```
214+
215+
### Discord alert on download failures
216+
```
217+
WHEN: Download Failed
218+
DO: Notify Only
219+
NOTIFY: Discord Webhook — "Failed to download {title} by {artist}: {reason}"
220+
```
221+
222+
### Weekly database backup
223+
```
224+
WHEN: Weekly Schedule (Sun at 02:00)
225+
DO: Backup Database
226+
```
227+
228+
---
229+
230+
## Tips
231+
232+
- **Test with "Run Now"**: Every automation card has a play button that triggers it immediately, regardless of its schedule. Use this to verify your setup before waiting for the timer.
233+
- **Check the activity feed**: The Dashboard activity feed shows when automations run and their results.
234+
- **Conditions narrow, not widen**: Without conditions, an event trigger fires for every event of that type. Conditions filter it down to specific cases.
235+
- **Delay is per-execution**: If you set a 5-minute delay, the action waits 5 minutes after each trigger fire, not 5 minutes after the last execution.
236+
- **Cross-guards**: The system automations (wishlist/watchlist) have mutual exclusion — if one is running, the other waits until the next scheduled time rather than queueing up.
237+
- **Discovery is incremental**: Running "Discover Playlist" only processes tracks that haven't been discovered yet. Already-discovered tracks are skipped. Failed tracks are re-attempted on subsequent runs.

0 commit comments

Comments
 (0)