I am working on a HTML, and CSS web app that uses the Spotify API. Login works great, the only problem that I have is that if I don’t add the account I’m trying to login to the user dashboard, it doesn’t work and shows an error code of “Failed to load resource: the server responded with a status of 403 ()” and “results.html?code=AQ…WKGIbYgl3eGcTtIF:89 Error fetching artist data: Check settings on developer.spotify.com/dashboard, the user may not be registered.”
index.html
<!DOCTYPE html>
<html lang="en">
<head style="background-color: #061e3e;">
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Spotify Outfit - Landing Page</title>
<link rel="stylesheet" href="LandingPage.css">
</head>
<body style="background-color: #061e3e;">
<!-- Landing Page Section -->
<div id="landing-page" class="landing-page">
<div class="container">
<h1 class="title">
<div>YOUR</div>
<div>SPOTIFY</div>
<div>OUTFIT</div>
</h1>
<p class="subtitle">Your Outfit, Inspired by Your Music Taste</p>
<a href="https://accounts.spotify.com/authorize?client_id=ceae01a497814f499f7aebd4830653cb&response_type=token&redirect_uri=<redacted for privacy purposes>&scope=user-read-private,user-top-read,user-read-email,user-read-recently-played,user-read-playback-state,user-read-currently-playing&state=STATE&show_dialog=true" class="connect-button">
<img src="spotify-logo.png" alt="Spotify Logo" class="spotify-logo">
Connect Spotify
</a>
</div>
</div>
<!-- Results Page Section (Initially Hidden) -->
<div id="results-page" class="results-page" style="display: none;">
<div class="container">
<h2>Your Top Genre:</h2>
<p id="genre-name">Loading...</p>
<h3>Your Top Artist:</h3>
<p id="artist-name"></p>
<img id="artist-image" src="outfit-placeholder.png" alt="Top Artist Image" class="artist-image">
</div>
</div>
<script>
// Function to extract access token from URL
function getAccessTokenFromURL() {
const hash = window.location.hash.substring(1);
const params = new URLSearchParams(hash);
return params.get("access_token");
}
// Fetch user's top artist data from Spotify
function getAccessTokenFromURL() {
var accessToken = null;
var hash = window.location.hash.substring(1);
var params = hash.split('&');
for (var i = 0; i < params.length; i++) {
var param = params[i].split('=');
if (param[0] === 'access_token') {
accessToken = param[1];
break;
}
}
return accessToken;
}
// Check if the URL contains an access token
window.addEventListener("load", function() {
var accessToken = getAccessTokenFromURL();
if (accessToken) {
// If access token is present, store it in sessionStorage
sessionStorage.setItem('accessToken', accessToken);
// Redirect to the main page or perform other actions
window.location.href = <redacted for privacy purposes>
}
});
</script>
</body>
</html>
results.html
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Spotify Outfit - Results Page</title>
<link rel="stylesheet" href="ResultsPage.css">
<script src="https://code.jquery.com/jquery-3.6.0.min.js"></script>
<script>
document.addEventListener("DOMContentLoaded", function() {
var clientId = 'ceae01a497814f499f7aebd4830653cb'; // Replace with your actual client_id
var clientSecret = <redacted for privacy purposes>
const redirectUri = <redacted for privacy purposes>
const urlParams = new URLSearchParams(window.location.search);
const authCode = urlParams.get('code');
console.log("Auth Code:", authCode); // Check if the code is present
if (authCode) {
exchangeCodeForToken(authCode);
} else {
redirectToSpotifyAuth();
}
function redirectToSpotifyAuth() {
const scopes ='user-read-private user-read-email user-read-playback-state user-modify-playback-state user-read-recently-played user-top-read';
const authUrl = `https://accounts.spotify.com/authorize?client_id=${clientId}&response_type=code&redirect_uri=${encodeURIComponent(redirectUri)}&scope=${encodeURIComponent(scopes)}`;
window.location.href = authUrl;
}
function exchangeCodeForToken(code) {
$.ajax({
url: "https://accounts.spotify.com/api/token",
type: "POST",
headers: {
"Authorization": "Basic " + btoa(`${clientId}:${clientSecret}`)
},
data: {
grant_type: "authorization_code",
code: code,
redirect_uri: redirectUri
},
success: function(response) {
console.log("Access Token Response:", response);
const accessToken = response.access_token;
fetchUserTopArtistAndGenre(accessToken);
},
error: function(xhr, status, error) {
console.error("Error exchanging code for token:", xhr.responseText || error);
}
});
}
function fetchUserTopArtistAndGenre(accessToken) {
$.ajax({
url: "https://api.spotify.com/v1/me/top/artists?time_range=short_term&limit=1",
type: "GET",
headers: {
"Authorization": "Bearer " + accessToken
},
success: function(response) {
console.log("API Response:", response);
const mainGenreElement = $('#mainGenre');
const artistContainer = $('#artist-container');
const artistNameElement = $('#artistName');
const artistImageElement = $('#artistImage');
if (response.items.length > 0) {
const topArtist = response.items[0];
const genres = topArtist.genres;
const artistName = topArtist.name;
const artistImage = topArtist.images.length > 0 ? topArtist.images[0].url : null;
const mainGenre = genres.length > 0 ? genres[0] : "No genre available";
mainGenreElement.text(mainGenre);
artistNameElement.text(artistName);
if (artistImage) {
artistImageElement.attr('src', artistImage).show();
} else {
artistImageElement.hide();
}
artistContainer.show();
} else {
mainGenreElement.text("No genre available.");
artistContainer.hide();
}
},
error: function(xhr, status, error) {
console.error("Error fetching artist data:", xhr.responseText || error);
}
});
}
});
</script>
</head>
<body>
<div class="results-page">
<div class="results-container">
<h1 class="main-genre">Your main genre is...</h1>
<h2 id="mainGenre" class="genre">Loading...</h2>
<div id="artist-container" class="artist-container" style="display: none;">
<h3 class="artist-title">Your Top Artist:</h3>
<p id="artistName" class="artist-name"></p>
<img id="artistImage" alt="Top Artist" class="artist-image" style="width: 200px; height: auto; border-radius: 10px;" />
</div>
<h3 class="outfit-title">Here is your outfit!</h3>
<img id="outfit-image" src="outfit-placeholder.png" alt="Outfit" class="outfit-image" />
</div>
</div>
</body>
</html>
Initially, I thought it was the scope parameters because it was set to user-read-private, I added the ones I think I needed (‘user-read-private user-read-email user-read-playback-state user-modify-playback-state user-read-recently-played user-top-read’) and it still didn’t work out for me. So, I’m quite stuck as someone newer to this.