This repository was archived by the owner on Jul 23, 2026. It is now read-only.
-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathspotify-api.js
More file actions
95 lines (86 loc) · 3.46 KB
/
Copy pathspotify-api.js
File metadata and controls
95 lines (86 loc) · 3.46 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
// Spotify Web API actions
function generateCodeVerifier(length = 128) {
const possible = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789-._~';
let code_verifier = '';
for (let i = 0; i < length; i++) {
code_verifier += possible.charAt(Math.floor(Math.random() * possible.length));
}
return code_verifier;
}
async function generateCodeChallenge(code_verifier) {
const digest = await crypto.subtle.digest('SHA-256', new TextEncoder().encode(code_verifier));
return btoa(String.fromCharCode(...new Uint8Array(digest)))
.replace(/\+/g, '-').replace(/\//g, '_').replace(/=+$/, '');
}
const client_id = '5ed07e2a23384be495efff4d463aba54';
const redirect_uri = window.location.origin + window.location.pathname;
const scope = 'user-read-private user-read-email user-read-playback-state user-read-currently-playing';
export function loginWithSpotify() {
const code_verifier = generateCodeVerifier();
localStorage.setItem('code_verifier', code_verifier);
generateCodeChallenge(code_verifier).then(code_challenge => {
const params = new URLSearchParams({
response_type: 'code',
client_id,
scope,
redirect_uri,
code_challenge_method: 'S256',
code_challenge
});
window.location = 'https://accounts.spotify.com/authorize?' + params.toString();
});
}
export async function handleRedirect() {
const params = new URLSearchParams(window.location.search);
const code = params.get('code');
if (!code) return null;
const code_verifier = localStorage.getItem('code_verifier');
const body = new URLSearchParams({
client_id,
grant_type: 'authorization_code',
code,
redirect_uri,
code_verifier
});
const response = await fetch('https://accounts.spotify.com/api/token', {
method: 'POST',
headers: { 'Content-Type': 'application/x-www-form-urlencoded' },
body
});
const data = await response.json();
if (data.access_token) {
window.history.replaceState({}, document.title, window.location.pathname);
localStorage.removeItem('code_verifier');
localStorage.setItem('access_token', data.access_token);
return data.access_token;
} else {
document.getElementById('error-msg').textContent = 'Error: ' + JSON.stringify(data, null, 2);
return null;
}
}
// --- Profile and Current Track ---
export async function getProfile(access_token) {
const res = await fetch('https://api.spotify.com/v1/me', {
headers: { Authorization: 'Bearer ' + access_token }
});
if (!res.ok) return null;
return await res.json();
}
export async function getCurrentTrack(access_token) {
const res = await fetch('https://api.spotify.com/v1/me/player/currently-playing', {
headers: { Authorization: 'Bearer ' + access_token }
});
if (res.status === 204 || !res.ok) return null;
return await res.json();
}
async function playerCommand(access_token, endpoint, method='POST') {
const response = await fetch(`https://api.spotify.com/v1/me/player/${endpoint}`, {
method,
headers: { Authorization: 'Bearer ' + access_token }
});
if (!response.ok) {
const text = await response.text();
document.getElementById('data').innerText = `Spotify API Error (${endpoint}): ${response.status} ${text}`;
console.error(`Spotify API Error (${endpoint}):`, response.status, text);
}
}