Hi,
First off, thanks for creating this!
Unfortunately, the current implementation doesn't work for playlists with more than 100 tracks, because the endpoint that is currently used, has a limit of responding with 100 tracks.
I have adjusted the implementation, but was not able to push my branch to this repository.
So if you want to take over the implementation, here is the code:
import { SPOTIFY_API_BASE, SPOTIFY_TOKEN_SOURCE } from "../data/config.ts" ;
export async function getSpotifyToken(): Promise<string> {
const response = await fetch(`${SPOTIFY_TOKEN_SOURCE}`, {
mode: 'cors',
headers: {
'Accept': 'application/json'
}
});
const data = await response.json();
console.log(data)
return data['token'];
}
export function extractPlaylistId(url: string): string {
const patterns = [
/spotify:playlist:([a-zA-Z0-9]+)/, // Spotify URI
/playlist\/([a-zA-Z0-9]+)/, // Web URL
/^([a-zA-Z0-9]+)$/, // Direct ID
];
for (const pattern of patterns) {
const match = url.match(pattern);
if (match) {
return match[1];
}
}
throw new Error('Invalid Spotify playlist URL or ID');
}
export async function getTotalTrackNumber(playlistId: string, token: string): promise<number> {
const response = await fetch(
`${SPOTIFY_API_BASE}/playlists/${playlistId}`,
{
headers: {
Authorization: `Bearer ${token}`,
},
}
);
if (!response.ok) {
throw new Error('Failed to fetch playlist data');
}
const data = await response.json();
const total_songs = data.tracks.total;
return total_songs;
}
export async function fetchPlaylistTracks(playlistId: string): Promise<Song[]> {
const token = await getSpotifyToken();
const total_songs = await getTotalTrackNumber(playlistId, token);
const step = 100; // NOTE: You can fetch 100 tracks in one request
var all_tracks = [];
for (let i = 0; i <= total_songs; i += step) {
const tracks_response = await fetch(
`${SPOTIFY_API_BASE}/playlists/${playlistId}/tracks?fields=items(track(uri,name,artists(name),album(release_date)))&offset=${i}`,
{
headers: {
Authorization: `Bearer ${token}`,
},
}
);
if (!tracks_response.ok) {
throw new Error('Failed to fetch playlist data');
}
const track_data = await tracks_response.json();
const tracks = track_data.items
.filter((item: { track: SpotifyTrack | null }) => item.track)
.map((item: { track: SpotifyTrack }) => ({
title: item.track.name,
artist: item.track.artists[0].name,
year: parseInt(item.track.album.release_date.substring(0, 4), 10),
spotifyUri: item.track.uri,
}));
all_tracks = [...all_tracks, ...tracks];
}
return all_tracks;
}
Basically, in the above code, first you fetch the total of numbers of tracks and then you request the tracks (100 at a time) until you got everything.
Kind regards,
Mees
Hi,
First off, thanks for creating this!
Unfortunately, the current implementation doesn't work for playlists with more than 100 tracks, because the endpoint that is currently used, has a limit of responding with 100 tracks.
I have adjusted the implementation, but was not able to push my branch to this repository.
So if you want to take over the implementation, here is the code:
Basically, in the above code, first you fetch the total of numbers of tracks and then you request the tracks (100 at a time) until you got everything.
Kind regards,
Mees