Spaces:
Paused
Paused
| const express = require('express'); | |
| const axios = require('axios'); | |
| const app = express(); | |
| const PORT = process.env.PORT || 7860; | |
| const SPOTIFY_API = { | |
| BASE: 'https://api.spotify.com/v1', | |
| AUTH: 'https://accounts.spotify.com/api/token', | |
| CLIENT_ID: 'b0cdfaef5b0b401299244ef88df29ffb', | |
| CLIENT_SECRET: '3e5949b78a214aecb2558b861911c1a9' | |
| }; | |
| const FAB_DL_API = 'https://api.fabdl.com'; | |
| let spotifyToken = null; | |
| let tokenExpiry = null; | |
| async function getSpotifyToken() { | |
| if (spotifyToken && Date.now() < tokenExpiry) { | |
| return spotifyToken; | |
| } | |
| try { | |
| const authString = Buffer.from(`${SPOTIFY_API.CLIENT_ID}:${SPOTIFY_API.CLIENT_SECRET}`).toString('base64'); | |
| const response = await axios.post(SPOTIFY_API.AUTH, 'grant_type=client_credentials', { | |
| headers: { | |
| 'Content-Type': 'application/x-www-form-urlencoded', | |
| 'Authorization': `Basic ${authString}` | |
| } | |
| }); | |
| spotifyToken = response.data.access_token; | |
| tokenExpiry = Date.now() + (response.data.expires_in * 1000); | |
| return spotifyToken; | |
| } catch (error) { | |
| console.error(error); | |
| throw new Error('Failed to get Spotify token'); | |
| } | |
| } | |
| function formatDuration(ms) { | |
| const minutes = Math.floor(ms / 60000); | |
| const seconds = Math.floor((ms % 60000) / 1000); | |
| return `${minutes}:${seconds.toString().padStart(2, '0')}`; | |
| } | |
| app.get('/api/spotify', async (req, res) => { | |
| try { | |
| const { url, search } = req.query; | |
| if (url) { | |
| const token = await getSpotifyToken(); | |
| const trackId = url.split('/').pop().split('?')[0]; | |
| const trackResponse = await axios.get(`${SPOTIFY_API.BASE}/tracks/${trackId}`, { | |
| headers: { 'Authorization': `Bearer ${token}` } | |
| }); | |
| const fabResponse = await axios.get(`${FAB_DL_API}/spotify/get?url=${url}`); | |
| const downloadResponse = await axios.get( | |
| `${FAB_DL_API}/spotify/mp3-convert-task/${fabResponse.data.result.gid}/${fabResponse.data.result.id}` | |
| ); | |
| res.json({ | |
| title: trackResponse.data.name, | |
| artist: trackResponse.data.artists.map(a => a.name).join(', '), | |
| duration: formatDuration(trackResponse.data.duration_ms), | |
| cover: trackResponse.data.album.images[0]?.url, | |
| downloadUrl: `${FAB_DL_API}${downloadResponse.data.result.download_url}` | |
| }); | |
| } else if (search) { | |
| const token = await getSpotifyToken(); | |
| const searchResponse = await axios.get( | |
| `${SPOTIFY_API.BASE}/search?q=${encodeURIComponent(search)}&type=track&limit=10`, | |
| { headers: { 'Authorization': `Bearer ${token}` } } | |
| ); | |
| const tracks = searchResponse.data.tracks.items.map(track => ({ | |
| id: track.id, | |
| title: track.name, | |
| artist: track.artists.map(a => a.name).join(', '), | |
| duration: formatDuration(track.duration_ms), | |
| cover: track.album.images[0]?.url, | |
| url: track.external_urls.spotify | |
| })); | |
| res.json(tracks); | |
| } else { | |
| res.status(400).json({ error: 'Missing url or search parameter' }); | |
| } | |
| } catch (error) { | |
| console.error(error); | |
| res.status(500).json({ error: 'Internal server error' }); | |
| } | |
| }); | |
| app.listen(PORT, () => { | |
| console.log(`Server running on port ${PORT}`); | |
| }); |