diff --git a/src/js/music.ts b/src/js/music.ts index d0c71d5..7b1f17f 100644 --- a/src/js/music.ts +++ b/src/js/music.ts @@ -9,40 +9,71 @@ interface Scrobble { track: Track; } -interface LastFMAlbumInfo { - album: { - image: { "#text": string; size: string }[]; - }; -} +const SPOTIFY_ID = "7d152bfca7e545a5801cc2a0b5b9dcb0"; +const SPOTIFY_SECRET = "ff9db43e1ec7420bacd4e553f09ee555"; -const LASTFM_API_KEY = "0a210a4a6741f2ec8f27a791b9d5d971"; - -async function fetchAlbumCover( - artist: string, - album: string, -): Promise { - const encodedArtist = encodeURIComponent(artist); - const encodedAlbum = encodeURIComponent(album); - const url = `https://ws.audioscrobbler.com/2.0/?method=album.getinfo&api_key=${LASTFM_API_KEY}&artist=${encodedArtist}&album=${encodedAlbum}&format=json`; +async function getSpotifyToken(): Promise { + const encoded = btoa(`${SPOTIFY_ID}:${SPOTIFY_SECRET}`); try { - const response = await fetch(url); + const response = await fetch("https://accounts.spotify.com/api/token", { + method: "POST", + headers: { + "Content-Type": "application/x-www-form-urlencoded", + Authorization: `Basic ${encoded}`, + }, + body: "grant_type=client_credentials", + }); + if (!response.ok) { throw new Error(`HTTP error! status: ${response.status}`); } - const data: LastFMAlbumInfo = await response.json(); + const data = await response.json(); + return data.access_token; + } catch (error) { + console.error("Error getting Spotify token:", error); + return null; + } +} - if (data?.album?.image) { - const largeImage = data.album.image.find( - (image) => image.size === "large", - ); - return largeImage ? largeImage["#text"] : null; +async function fetchSpotifyCover( + artist: string, + track: string, +): Promise { + const token = await getSpotifyToken(); + if (!token) { + return null; + } + + const encodedArtist = encodeURIComponent(artist); + const encodedTrack = encodeURIComponent(track); + const query = `track:${encodedTrack} artist:${encodedArtist}`; + + try { + const response = await fetch( + `https://api.spotify.com/v1/search?q=${query}&type=track&limit=1`, + { + headers: { + Authorization: `Bearer ${token}`, + }, + }, + ); + + if (!response.ok) { + throw new Error(`Spotify API error! status: ${response.status}`); + } + + const data = await response.json(); + + if (data?.tracks?.items?.length > 0) { + const imageUrl = data.tracks.items[0].album.images[0].url; + return imageUrl; } return null; } catch (error) { - console.error("Error fetching album cover:", error); + console.error("Error fetching Spotify cover:", error); return null; } } @@ -78,9 +109,9 @@ async function fetchAndDisplayLastTrack() { } if (lastTrack) { - const albumCover = await fetchAlbumCover( + const albumCover = await fetchSpotifyCover( lastTrack.artists[0], - lastTrack.album.albumtitle, + lastTrack.title, ); let imageElement = "";