This project is a Cloudflare Worker plus Cloudflare Pages proxy that turns public IMDb lists and watchlists into a Radarr RSS feed and a Sonarr Custom List feed.
Flow:
- Open the site on
imdbwatcharr.pages.dev - Paste a public IMDb watchlist or list URL
- Get back deterministic movie and TV list URLs derived from the IMDb identifier
- Use the movie URL in Radarr's
RSS Listand the TV URL in Sonarr'sCustom List
Examples:
- Radarr movie feed:
https://www.imdb.com/user/p.kdbeq6dtmzzpiin4k7t4fnunf4/watchlist/becomeshttps://imdbwatcharr.pages.dev/radarr/p/p.kdbeq6dtmzzpiin4k7t4fnunf4 - Sonarr custom list:
https://www.imdb.com/user/p.kdbeq6dtmzzpiin4k7t4fnunf4/watchlist/becomeshttps://imdbwatcharr.pages.dev/sonarr/p/p.kdbeq6dtmzzpiin4k7t4fnunf4 - Radarr movie feed:
https://www.imdb.com/list/ls006123300/becomeshttps://imdbwatcharr.pages.dev/radarr/l/ls006123300 - Sonarr custom list:
https://www.imdb.com/list/ls006123300/becomeshttps://imdbwatcharr.pages.dev/sonarr/l/ls006123300
- Cloudflare Worker serves the UI, API, and RSS generation logic
- Cloudflare Pages exposes the public
pages.devhostname and proxies requests to the Worker - D1 stores feed metadata plus the last successful snapshot of all IMDb items, any resolved TVDB IDs, and cached Radarr/Sonarr payloads
- Browser Rendering fetches IMDb pages and lets the parser extract data from stable page payloads such as
#__NEXT_DATA__ - The Worker tries a direct IMDb fetch first and only falls back to Browser Rendering when needed
- The Worker fingerprints the stable IMDb payload block instead of the whole HTML page, so unchanged lists can reuse the cached Radarr RSS or Sonarr JSON response without rebuilding it
GET /simple input formPOST /api/createnormalize an IMDb URL, create the feed record if needed, refresh it, resolve TVDB IDs for shows when possible, and return both public URLsGET /radarr/p/:profileIddynamically serve the Radarr movie feed for a watchlistGET /radarr/l/:listIddynamically serve the Radarr movie feed for a listGET /sonarr/p/:profileIddynamically serve the Sonarr Custom List JSON for a watchlistGET /sonarr/l/:listIddynamically serve the Sonarr Custom List JSON for a listGET /radarr/f/:imdbKeyoptional generic Radarr route that infers the source from values likels...,p...., orur...GET /sonarr/f/:imdbKeyoptional generic Sonarr route with the same inference rulesGET /p/:profileId,GET /l/:listId, andGET /f/:imdbKeyare legacy shortcuts that redirect to/radarr/...GET /f/:slug.xmllegacy slug route that redirects to the deterministic pathGET /api/feeds/:sluginternal metadata lookup for stored feed records
npm install
npm run check
npm run devFor remote D1 migrations after the database exists:
npm run db:migrate:remoteThis repo includes:
- ci.yml for fixture-based parser checks
- deploy-worker.yml for Worker deployment
- deploy-pages-proxy.yml for the public
pages.devproxy
Required GitHub repo secrets:
CLOUDFLARE_API_TOKENCLOUDFLARE_ACCOUNT_ID
IMDb access is the hardest part of the system. The Worker now tries a direct HTTP fetch first because it is lighter and avoids Browser Rendering rate limits in the common case. If IMDb returns a challenge page, the Worker falls back to Browser Rendering. If both fail, the route serves the last stored error or snapshot until a later refresh succeeds.
The /sonarr/... route is now designed for Sonarr's Custom List provider, which expects JSON entries with TvdbId. TVDB IDs are resolved from IMDb IDs through TVMaze when possible, so some IMDb TV entries may be skipped if no TVDB mapping is available.
When IMDb does respond, the Worker hashes the stable list payload extracted from the page. If that fingerprint has not changed, it keeps serving the cached list body with ETag headers so Radarr, Sonarr, and any upstream cache can avoid re-downloading the full payload unnecessarily.