feat: use spotdl (TzurSoffer fork) as primary Spotify resolver
Replaces rate-limited api.spotify.com calls with spotdl's SpotAPI approach, which uses Spotify's internal browser endpoints — no developer credentials needed, no api.spotify.com rate limits. TOTP anonymous token kept as automatic fallback. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
1 parent
8cc6653898
commit
3c85deab40
3 files changed
+129
-3
No files matched your search
@@ -376,7 +376,33 @@ app.get('/api/health', (req, res) => {
|
||||
});
|
||||
});
|
||||
|
||||
async function _resolveSpotify(type, id) {
|
||||
async function _resolveSpotifyViaSpotdl(url) {
|
||||
const { execFile } = require('child_process');
|
||||
const scriptPath = path.join(__dirname, 'spotify_resolve.py');
|
||||
return new Promise((resolve, reject) => {
|
||||
execFile('python3', [scriptPath, url], { timeout: 90000, maxBuffer: 10 * 1024 * 1024 }, (err, stdout, stderr) => {
|
||||
if (err) return reject(new Error(`spotdl: ${stderr?.trim() || err.message}`));
|
||||
try {
|
||||
const data = JSON.parse(stdout.trim());
|
||||
if (data.error) return reject(new Error(data.error));
|
||||
resolve(data);
|
||||
} catch {
|
||||
reject(new Error(`spotdl: ungültige Ausgabe — ${stdout.slice(0, 200)}`));
|
||||
}
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
async function _resolveSpotify(type, id, originalUrl) {
|
||||
// Primary: spotdl (TzurSoffer fork) — uses SpotAPI, no rate limits
|
||||
try {
|
||||
console.log('[spotify] trying spotdl resolver');
|
||||
return await _resolveSpotifyViaSpotdl(originalUrl);
|
||||
} catch (e) {
|
||||
console.log('[spotify] spotdl failed:', e.message, '— falling back to TOTP');
|
||||
}
|
||||
|
||||
// Fallback: TOTP anonymous token
|
||||
const token = await fetchSpotifyToken();
|
||||
|
||||
if (type === 'track') {
|
||||
@@ -419,7 +445,7 @@ app.post('/api/spotify/resolve', async (req, res) => {
|
||||
const timeout = new Promise((_, reject) =>
|
||||
setTimeout(() => reject(new Error('Zeitüberschreitung — Spotify API antwortet nicht (>120s)')), 120000)
|
||||
);
|
||||
const data = await Promise.race([_resolveSpotify(type, id), timeout]);
|
||||
const data = await Promise.race([_resolveSpotify(type, id, url), timeout]);
|
||||
res.json(data);
|
||||
} catch(e) {
|
||||
console.error('[spotify/resolve]', e.message);
|
||||
|
||||
Reference in new issue
Block a user