├── README.md ├── requirements.txt ├── vercel.json ├── app.py └── templates └── status.html /README.md: -------------------------------------------------------------------------------- 1 | ## SOON GUYS 2 | -------------------------------------------------------------------------------- /requirements.txt: -------------------------------------------------------------------------------- 1 | Flask 2 | spotipy 3 | requests 4 | beautifulsoup4 5 | -------------------------------------------------------------------------------- /vercel.json: -------------------------------------------------------------------------------- 1 | { 2 | "version": 2, 3 | "builds": [ 4 | { 5 | "src": "app.py", 6 | "use": "@vercel/python" 7 | } 8 | ], 9 | "routes": [ 10 | { 11 | "src": "/(.*)", 12 | "dest": "app.py" 13 | } 14 | ], 15 | "env": { 16 | "PYTHON_VERSION": "3.9" 17 | } 18 | } -------------------------------------------------------------------------------- /app.py: -------------------------------------------------------------------------------- 1 | from flask import Flask, request, jsonify, render_template 2 | import spotipy 3 | from spotipy.oauth2 import SpotifyClientCredentials 4 | import requests 5 | from bs4 import BeautifulSoup 6 | import re 7 | 8 | app = Flask(__name__) 9 | 10 | # Spotify credentials 11 | CLIENT_ID = '' 12 | CLIENT_SECRET = '' 13 | 14 | # Initialize Spotify client 15 | sp = spotipy.Spotify(auth_manager=SpotifyClientCredentials(client_id=CLIENT_ID, client_secret=CLIENT_SECRET)) 16 | 17 | def is_spotify_url(input_string): 18 | """Check if input is a Spotify track URL.""" 19 | return bool(re.match(r'^https://open\.spotify\.com/track/[a-zA-Z0-9]+', input_string)) 20 | 21 | def get_spotmate_download(spotify_url): 22 | """Get download link from spotmate.online.""" 23 | try: 24 | headers = { 25 | 'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/91.0.4472.124 Safari/537.36', 26 | 'Accept': 'text/html', 27 | } 28 | response = requests.get('https://spotmate.online', headers=headers, timeout=10) 29 | response.raise_for_status() 30 | 31 | soup = BeautifulSoup(response.text, 'html.parser') 32 | csrf_token = soup.find('meta', {'name': 'csrf-token'}) 33 | if not csrf_token: 34 | raise ValueError("CSRF token not found") 35 | csrf_token = csrf_token['content'] 36 | 37 | session_cookie = response.cookies.get('spotmateonline_session') 38 | if not session_cookie: 39 | raise ValueError("Session cookie not found") 40 | 41 | headers.update({ 42 | 'Content-Type': 'application/json', 43 | 'x-csrf-token': csrf_token, 44 | 'cookie': f'spotmateonline_session={session_cookie}', 45 | 'referer': 'https://spotmate.online/en', 46 | 'origin': 'https://spotmate.online', 47 | }) 48 | convert_response = requests.post( 49 | 'https://spotmate.online/convert', 50 | json={'urls': str(spotify_url)}, 51 | headers=headers, 52 | timeout=10 53 | ) 54 | convert_response.raise_for_status() 55 | data = convert_response.json() 56 | 57 | if data.get('error') or not data.get('url'): 58 | raise ValueError("Failed to get download link") 59 | 60 | return data['url'] 61 | except Exception: 62 | return None 63 | 64 | def get_track_metadata(track_id): 65 | """Get track metadata from Spotify, including cover art.""" 66 | try: 67 | track = sp.track(track_id) 68 | # Get the largest available cover art (usually at index 0) 69 | cover_art = track['album']['images'][0]['url'] if track['album']['images'] else None 70 | return { 71 | 'id': track['id'], 72 | 'title': track['name'], 73 | 'artists': ", ".join(artist['name'] for artist in track['artists']), 74 | 'album': track['album']['name'], 75 | 'release_date': track['album']['release_date'], 76 | 'duration': f"{track['duration_ms'] // 60000}:{(track['duration_ms'] % 60000) // 1000:02d}", 77 | 'isrc': track['external_ids'].get('isrc', 'N/A'), 78 | 'cover_art': cover_art 79 | } 80 | except Exception: 81 | return None 82 | 83 | def search_spotify(query, limit=5): 84 | """Search Spotify for tracks.""" 85 | try: 86 | results = sp.search(q=query, type='track', limit=limit) 87 | return [(track['name'], ", ".join(artist['name'] for artist in track['artists']), track['id']) for track in results['tracks']['items']] 88 | except Exception: 89 | return [] 90 | 91 | @app.route('/') 92 | def home(): 93 | """Render the status.html template.""" 94 | return render_template('status.html') 95 | 96 | @app.route('/sp/dl', methods=['GET']) 97 | def download_track(): 98 | """Download track by Spotify URL.""" 99 | spotify_url = request.args.get('url') 100 | if not spotify_url or not is_spotify_url(spotify_url): 101 | return jsonify({ 102 | 'status': False, 103 | 'message': 'Valid Spotify track URL required ❌', 104 | 'example': '/sp/dl?url=https://open.spotify.com/track/TRACK_ID' 105 | }), 400 106 | 107 | try: 108 | track_id = spotify_url.split('/track/')[1].split('?')[0] 109 | metadata = get_track_metadata(track_id) 110 | if not metadata: 111 | return jsonify({ 112 | 'status': False, 113 | 'message': 'Failed to fetch metadata ❌' 114 | }), 500 115 | 116 | download_url = get_spotmate_download(spotify_url) 117 | if not download_url: 118 | return jsonify({ 119 | 'status': False, 120 | 'message': 'Sorry Song Not Available ❌' 121 | }), 500 122 | 123 | return jsonify({ 124 | 'status': True, 125 | 'title': metadata['title'], 126 | 'artist': metadata['artists'], 127 | 'track_id': track_id, 128 | 'track_url': f"https://open.spotify.com/track/{track_id}", 129 | 'download_url': download_url, 130 | 'album': metadata['album'], 131 | 'release_date': metadata['release_date'], 132 | 'duration': metadata['duration'], 133 | 'isrc': metadata['isrc'], 134 | 'cover_art': metadata['cover_art'], 135 | 'credit': 'Downloaded By @TheSmartDev And API Developer @TheSmartDev Organization github.com/TheSmartDevs' 136 | }) 137 | 138 | except Exception as e: 139 | return jsonify({ 140 | 'status': False, 141 | 'message': f'Error: {str(e)} ❌' 142 | }), 500 143 | 144 | @app.route('/sp/search', methods=['GET']) 145 | def search_tracks(): 146 | """Search tracks by query.""" 147 | query = request.args.get('q') 148 | if not query: 149 | return jsonify({ 150 | 'status': False, 151 | 'message': 'Search query required ❌', 152 | 'example': '/sp/search?q=Tomake+Chai' 153 | }), 400 154 | 155 | try: 156 | tracks = search_spotify(query) 157 | if not tracks: 158 | return jsonify({ 159 | 'status': False, 160 | 'message': 'No tracks found ❌' 161 | }), 404 162 | 163 | results = [] 164 | for name, artist, track_id in tracks: 165 | track_url = f"https://open.spotify.com/track/{track_id}" 166 | metadata = get_track_metadata(track_id) 167 | if not metadata: 168 | continue 169 | 170 | download_url = get_spotmate_download(track_url) 171 | results.append({ 172 | 'title': name, 173 | 'artist': artist, 174 | 'track_id': track_id, 175 | 'track_url': track_url, 176 | 'download_url': download_url if download_url else None, 177 | 'album': metadata['album'], 178 | 'release_date': metadata['release_date'], 179 | 'duration': metadata['duration'], 180 | 'isrc': metadata['isrc'], 181 | 'cover_art': metadata['cover_art'], 182 | 'credit': 'Downloaded By @TheSmartDev And API Developer @TheSmartDev Organization github.com/TheSmartDevs' if download_url else '' 183 | }) 184 | 185 | return jsonify({ 186 | 'status': True, 187 | 'results': results 188 | }) 189 | 190 | except Exception as e: 191 | return jsonify({ 192 | 'status': False, 193 | 'message': f'Error: {str(e)} ❌' 194 | }), 500 195 | 196 | if __name__ == '__main__': 197 | app.run(host='0.0.0.0', port=5000) 198 | -------------------------------------------------------------------------------- /templates/status.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | TheSmartDev's Spotify API 7 | 8 | 9 | 10 | 11 | 40 | 41 | 42 |
43 | 44 |
45 |
46 | 47 | 48 | 49 | 50 |

51 | TheSmartDev's Spotify API 52 | 53 | 54 | 55 | 56 |

57 |
58 |
59 | 60 | 61 |
62 |
63 |

64 | Welcome to TheSmartDev's Spotify API! 🚀 This API allows you to download Spotify tracks or search for songs with ease. Explore the endpoints below to get started. 65 |

66 |
67 | 68 | 69 |
70 | 71 |
72 |
73 | 74 | 75 | 76 |

GET /sp/dl

77 |
78 |

Description: Retrieve a download link for a Spotify track using its URL.

79 |
80 |

Parameters:

81 |
    82 |
  • url: A valid Spotify track URL (required)
  • 83 |
84 |
85 |
86 |

Example:

87 |
/sp/dl?url=https://open.spotify.com/track/2QbFklmXzH2C8dS8U8U1PS
88 |
89 |
90 |

Response Format:

91 |
 92 | {
 93 |     "status": boolean,
 94 |     "title": string,
 95 |     "artist": string,
 96 |     "track_id": string,
 97 |     "track_url": string,
 98 |     "download_url": string,
 99 |     "album": string,
100 |     "release_date": string,
101 |     "duration": string,
102 |     "isrc": string,
103 |     "credit": string
104 | }
105 |                         
106 |
107 |
108 | 109 | 110 |
111 |
112 | 113 | 114 | 115 |

GET /sp/search

116 |
117 |

Description: Search for tracks on Spotify (returns up to 5 results).

118 |
119 |

Parameters:

120 |
    121 |
  • q: Search query for the track (required)
  • 122 |
123 |
124 |
125 |

Example:

126 |
/sp/search?q=Tomake+Chai
127 |
128 |
129 |

Response Format:

130 |
131 | {
132 |     "status": boolean,
133 |     "results": [
134 |         {
135 |             "title": string,
136 |             "artist": string,
137 |             "track_id": string,
138 |             "track_url": string,
139 |             "download_url": string or null,
140 |             "album": string,
141 |             "release_date": string,
142 |             "duration": string,
143 |             "isrc": string,
144 |             "credit": string
145 |         }
146 |     ]
147 | }
148 |                         
149 |
150 |
151 |
152 |
153 | 154 | 155 | 184 |
185 | 186 | --------------------------------------------------------------------------------