diff --git a/src/lib/server/playlist/spotifyPlaylistAdder.ts b/src/lib/server/playlist/spotifyPlaylistAdder.ts index 63ad2ec..a449efc 100644 --- a/src/lib/server/playlist/spotifyPlaylistAdder.ts +++ b/src/lib/server/playlist/spotifyPlaylistAdder.ts @@ -4,6 +4,7 @@ import type { OauthResponse } from '$lib/mastodon/response'; import type { SongInfo } from '$lib/odesliResponse'; import { OauthPlaylistAdder } from './oauthPlaylistAdder'; import type { PlaylistAdder } from './playlistAdder'; +import type { SpotifyAlbumTracksResponse } from './spotifyResponse'; export class SpotifyPlaylistAdder extends OauthPlaylistAdder implements PlaylistAdder { public constructor() { @@ -94,12 +95,39 @@ export class SpotifyPlaylistAdder extends OauthPlaylistAdder implements Playlist return; }*/ - //const searchParams = new URLSearchParams([['part', 'snippet']]); + let uris: string[] = []; + if (song.type === 'album') { + const albumId = song.spotifyUri.split(':').pop(); + // This only fetches max. 50 tracks, otherwise we would have to implement paging + // Maybe in the future, for now it should be enough to get the first 50 tracks + const albumTracksUrl = new URL(`${this.apiBase}/albums/${albumId}/tracks?limit=50`); + const options: RequestInit = { + method: 'GET', + headers: { Authorization: `${token.token_type} ${token.access_token}` } + }; + let trackResponse = await fetch(albumTracksUrl, options); + let tracks: SpotifyAlbumTracksResponse = await trackResponse.json(); + if (tracks.error && tracks.error.status === 401) { + this.logger.info('Token expired, refreshing and retrying'); + this.refreshToken(true); + trackResponse = await fetch(albumTracksUrl, options); + tracks = await trackResponse.json(); + } else if (tracks.error) { + this.logger.error('Fetching album trackas failed', tracks.error); + } + if (tracks.items) { + uris = tracks.items.map((x) => x.uri); + } + } else { + uris = [song.spotifyUri]; + } + + // Maximum is 100 items, but we'Re requesting only max. 50 anyways const options: RequestInit = { method: 'POST', headers: { Authorization: `${token.token_type} ${token.access_token}` }, body: JSON.stringify({ - uris: [song.spotifyUri] + uris: uris }) }; const apiUrl = new URL(`${this.apiBase}/playlists/${SPOTIFY_PLAYLIST_ID}/tracks`); diff --git a/src/lib/server/playlist/spotifyResponse.ts b/src/lib/server/playlist/spotifyResponse.ts new file mode 100644 index 0000000..5004859 --- /dev/null +++ b/src/lib/server/playlist/spotifyResponse.ts @@ -0,0 +1,33 @@ +export type SpotifyAlbumTracksResponse = { + href?: string; + limit?: number; + offset?: number; + total?: number; + next?: string | null; + previous?: string | null; + items?: SpotifyAlbumTrack[]; + error?: SpotifyError; +}; + +export type SpotifyAlbumTrack = { + artists: { + id: string; + uri: string; + name: string; + type: 'artist'; + }[]; + available_markets: string[]; + external_urls: { + spotify: string; + }; + href: string; + name: string; + type: 'track'; + id: string; + uri: string; +}; + +export type SpotifyError = { + status: number; + message: string; +};