(If you have other created links, remove them the same way.)
2. The Reliable Solution: "Robocopy" Monitor
Since Chrome refuses to save directly to the NAS smartly, we will use a Two-Stage approach.
Chrome (Extension): Sorts files based on Source/Type into local folders (e.g., Downloads\Torrents).
Windows (Robocopy): Watches those folders and instantly moves files to the NAS.
This gives you the "Source URL" logic you want, with the "NAS Destination" you need, using zero extra software.
Step A: Configure the Extension (Locally)
Set your extension rules to save to local folders inside Downloads.
example.com $\to$ FromExample
bittorrent $\to$ Torrents
(No symlinks. Just let Chrome create real folders).
Step B: The Watcher Script
You are a sysadmin; you can run a background process. Use Windows' built-in Robocopy with the Monitor (/MON) switch. It watches a folder and moves files the second they appear.
Create a simple batch file (move_downloads.bat):
Code snippet
@echo off
:: Move Torrents to NAS
start "Watch Torrents" /min robocopy "C:\Users\GGPC\Downloads\Torrents" "\\SynologyDS416j\750nm\Red\Torrents" /E /MOVE /MOT:1
:: Move Example.com files to NAS
start "Watch Example" /min robocopy "C:\Users\GGPC\Downloads\FromExample" "\\SynologyDS416j\750nm\Red\Example" /E /MOVE /MOT:1
/E: Copy subdirectories (if any).
/MOVE: Deletes from source after copying.
/MOT:1: Monitor Time. It stays running and checks every 1 minute for new files.
Why this works:
Logic: The extension handles the "Smart" part (sorting by Source URL/Type).
Transport: Robocopy handles the "Heavy" part (moving to NAS).
Safety: No symlink recursion, no browser permission errors.
Drop this batch file in your Startup folder (shell:startup) and you are done.
build
RUN CGO_ENABLED=1 go build -ldflags="-s -w -linkmode external -extldflags '-static'" -o /rsslay cmd/rsslay/main.go
8s
# github.com/mattn/go-sqlite3
sqlite3-binding.c:38268:42: error: 'pread64' undeclared here (not in a function); did you mean 'pread'?
38268 | { "pread64", (sqlite3_syscall_ptr)pread64, 0 },
| ^~~~~~~
| pread
sqlite3-binding.c:38286:42: error: 'pwrite64' undeclared here (not in a function); did you mean 'pwrite'?
38286 | { "pwrite64", (sqlite3_syscall_ptr)pwrite64, 0 },
| ^~~~~~~~
| pwrite
sqlite3-binding.c: In function 'seekAndRead':
sqlite3-binding.c:38272:49: error: unknown type name 'off64_t'; did you mean 'off_t'?
38272 | #define osPread64 ((ssize_t(*)(int,void*,size_t,off64_t))aSyscall[10].pCurrent)
| ^~~~~~~
sqlite3-binding.c:41128:11: note: in expansion of macro 'osPread64'
41128 | got = osPread64(id->h, pBuf, cnt, offset);
| ^~~~~~~~~
sqlite3-binding.c:38272:58: error: expected ')' before 'aSyscall'
38272 | #define osPread64 ((ssize_t(*)(int,void*,size_t,off64_t))aSyscall[10].pCurrent)
| ~ ^~~~~~~~
sqlite3-binding.c:41128:11: note: in expansion of macro 'osPread64'
41128 | got = osPread64(id->h, pBuf, cnt, offset);
| ^~~~~~~~~
sqlite3-binding.c: In function 'seekAndWriteFd':
sqlite3-binding.c:38290:57: error: unknown type name 'off64_t'; did you mean 'off_t'?
38290 | #define osPwrite64 ((ssize_t(*)(int,const void*,size_t,off64_t))\
| ^~~~~~~
sqlite3-binding.c:41257:17: note: in expansion of macro 'osPwrite64'
41257 | do{ rc = (int)osPwrite64(fd, pBuf, nBuf, iOff);}while( rc<0 && errno==EINTR);
| ^~~~~~~~~~
sqlite3-binding.c:38291:21: error: expected ')' before 'aSyscall'
38291 | aSyscall[13].pCurrent)
| ^~~~~~~~
sqlite3-binding.c:41257:17: note: in expansion of macro 'osPwrite64'
41257 | do{ rc = (int)osPwrite64(fd, pBuf, nBuf, iOff);}while( rc<0 && errno==EINTR);
| ^~~~~~~~~~
sqlite3-binding.c:38290:21: note: to match this '('
38290 | #define osPwrite64 ((ssize_t(*)(int,const void*,size_t,off64_t))\
| ^
sqlite3-binding.c:41257:17: note: in expansion of macro 'osPwrite64'
41257 | do{ rc = (int)osPwrite64(fd, pBuf, nBuf, iOff);}while( rc<0 && errno==EINTR);
| ^~~~~~~~~~