-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathindex.js
308 lines (253 loc) · 11.5 KB
/
index.js
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
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
require('dotenv').config();
const express = require('express');
const SpotifyWebApi = require('spotify-web-api-node')
const path = require('path');
const app = express();
const port = 3000;
const spotifyApi = new SpotifyWebApi({
clientId: process.env.CLIENT_ID,
clientSecret: process.env.CLIENT_SECRET,
redirectUri:process.env.REDIRECT_URL
})
//get user to log in and request scopes, can alter scopes requested later
app.get('/login', (req, res) => {
const scopes = ['user-read-private', 'user-read-email', 'user-library-read',
'user-library-modify', 'user-read-playback-state', 'user-modify-playback-state', 'user-top-read',
'playlist-modify-public', 'playlist-modify-private'];
res.redirect(spotifyApi.createAuthorizeURL(scopes));
})
app.get('/', (req, res) => {
// res.sendFile(path.join(__dirname, 'index.html'));
const error = req.query.error;
const code = req.query.code;
const state = req.query.state;
if (error) {
console.error('Error:', error);
res.send(`Error: ${error}`);
return;
}
// If no error, exchange authorization code for access token
spotifyApi.authorizationCodeGrant(code).then(data => {
const accessToken = data.body['access_token']; // Corrected typo here
const refreshToken = data.body['refresh_token'];
const expiresIn = data.body['expires_in'];
// Set access token and refresh token
spotifyApi.setAccessToken(accessToken);
spotifyApi.setRefreshToken(refreshToken);
// Print out access token and refresh token in console
console.log('Access Token:', accessToken);
console.log('Refresh Token:', refreshToken);
// Refresh access token when it expires
setTimeout(async () => {
const data = await spotifyApi.refreshAccessToken();
const accessTokenRefreshed = data.body['access_token'];
spotifyApi.setAccessToken(accessTokenRefreshed);
console.log('Access Token Refreshed:', accessTokenRefreshed);
}, expiresIn * 1000); // Convert expiresIn to milliseconds
// Redirect to the search page
res.redirect('/search');
}).catch(error => {
console.error('Error:', error);
res.send('Error getting token');
});
});
// app.get('/search', (req,res) =>{
// const {q} = req.query;
// spotifyApi.searchTracks(q).then(searchData=>{
// const trackUri = searchData.body.tracks.items[0].uri;
// res.send({uri:trackUri});
// console.log({uri:trackUri});
// }).catch(err=>{
// res.send(`Error playing ${err}`);
// })
// })
//works well
// app.get('/search', (req, res) => {
// const { q } = req.query;
// if (!q) {
// res.sendFile(path.join(__dirname, 'search.html')); // Render the search form if no query is provided
// return;
// }
// spotifyApi.searchTracks(q).then(searchData => {
// const trackUri = searchData.body.tracks.items[0].uri;
// res.send({ uri: trackUri });
// console.log({ uri: trackUri });
// }).catch(err => {
// res.send(`Error playing ${err}`);
// });
// });
///redirect straight to play
app.get('/search', (req, res) => {
const { q } = req.query;
if (!q) {
res.sendFile(path.join(__dirname, 'search.html')); // Render the search form if no query is provided
return;
}
console.log(q);
spotifyApi.searchTracks(q).then(searchData => {
const trackUri = searchData.body.tracks.items[0].uri;
// Redirect to the play page with the track URI as a query parameter
res.redirect(`/play?uri=${encodeURIComponent(trackUri)}`);
}).catch(err => {
res.send(`Error searching for tracks: ${err}`);
});
});
//working
// app.get('/play', (req, res) => {
// const { uri } = req.query;
// spotifyApi.getMyDevices().then(data => {
// const devices = data.body.devices;
// // res.json(devices);
// if (devices.length > 0) {
// // Devices found, display the list
// let deviceList = '';
// devices.forEach(device => {
// deviceList += `${device.name} (${device.type})\n`;
// });
// deviceList = 'Available devices:\n' + deviceList;
// res.send(deviceList);
// // Start playback on the first device in the list
// const deviceId = devices[0].id;
// spotifyApi.play({ uris: [uri], device_id: deviceId }).then(() => {
// res.send('Playback started on ' + devices[0].name);
// }).catch(err => {
// res.send(`Error playing track: ${err.message}`);
// });
// } else {
// // No active devices found, inform the user
// res.send('No active devices found. Please open Spotify on your device and try again.');
// }
// }).catch(err => {
// res.send(`Error getting devices: ${err.message}`);
// });
// });
//testing
app.get('/play', (req, res) => {
const { uri } = req.query;
spotifyApi.getMyDevices().then(data => {
const devices = data.body.devices;
if (devices.length > 0) {
// Start playback on the first device in the list
const deviceId = devices[0].id;
spotifyApi.play({ uris: [uri], device_id: deviceId }).then(() => {
// Playback started successfully, now get recommendations
// Call the recommendation logic here
getRecommendationsAndRespond(res);
res.send(res);
}).catch(err => {
res.send(`Error playing track: ${err.message}`);
});
} else {
// No active devices found, inform the user
res.send('No active devices found. Please open Spotify on your device and try again.');
}
}).catch(err => {
res.send(`Error getting devices: ${err.message}`);
});
});
// Function to get recommendations and respond to the client
function getRecommendationsAndRespond(res) {
Promise.all([
spotifyApi.getMyTopArtists({ limit: 5 }), // Get your top 5 artists
spotifyApi.getMyTopTracks({ limit: 5 }), // Get your top 5 tracks
]).then(([topArtists, topTracks]) => {
// Extract necessary information from the response
const seedArtists = topArtists.body.items.map(artist => artist.id); // Get the IDs of your top artists
const seedTracks = topTracks.body.items.map(track => track.uri); // Get the URIs of your top tracks
// Retrieve additional information about the top artists and tracks
const artistNames = topArtists.body.items.map(artist => artist.name); // Get the names of your top artists
const trackNames = topTracks.body.items.map(track => track.name); // Get the names of your top tracks
const artistGenres = topArtists.body.items.map(artist => artist.genres); // Get the genres of your top artists
// Combine all genres into a single array
const seedGenres = artistGenres.flat().filter((genre, index, self) => self.indexOf(genre) === index);
// Now you have the necessary information to use as seed parameters for recommendations
console.log('Seed Artists:', seedArtists);
console.log('Seed Tracks:', seedTracks);
console.log('Top Artist Names:', artistNames);
console.log('Top Track Names:', trackNames);
console.log('Top Artist Genres:', artistGenres);
console.log('Seed Genres:', seedGenres);
// Use the retrieved seed parameters to get recommendations
spotifyApi.getRecommendations({
seed_artists: seedArtists,
seed_tracks: seedTracks,
seed_genres: seedGenres, // Add seed genres to the recommendation parameters
limit: 10 // Limit the number of recommendations to 10
}).then(data => {
const recommendations = data.body.tracks.map(track => track.name); // Get the names of the recommended tracks
console.log('Recommendations:', recommendations);
// Send the response with the recommendations
res.send({ recommendations }); // Send recommendations as JSON object
}).catch(error => {
console.error('Error getting recommendations:', error);
res.status(500).send('Error getting recommendations');
});
}).catch(error => {
console.error('Error getting top artists and tracks:', error);
res.status(500).send('Error getting top artists and tracks');
});
}
// app.get('/recommend', (req, res) =>{
// const { uri } = req.query;
// spotifyApi.getMyDevices().then(data => {
// const devices = data.body.devices;
// if (devices.length > 0) {
// // Devices found, display the list
// let deviceList = '';
// devices.forEach(device => {
// deviceList += `${device.name} (${device.type})\n`;
// });
// deviceList = 'Available devices:\n' + deviceList;
// res.send(deviceList);
// // Start playback on the first device in the list
// const deviceId = devices[0].id;
// spotifyApi.play({ uris: [uri], device_id: deviceId }).then(() => {
// // Playback started successfully
// console.log('Playback started on ' + devices[0].name);
// }).catch(err => {
// console.error(`Error playing track: ${err.message}`);
// });
// } else {
// // No active devices found, inform the user
// res.send('No active devices found. Please open Spotify on your device and try again.');
// }
// // Use the Spotify Web API's getMyTopArtists, getMyTopTracks, and getMySavedTracks endpoints to get your top artists, tracks, and saved tracks
// return Promise.all([
// spotifyApi.getMyTopArtists({ limit: 5 }), // Get your top 5 artists
// spotifyApi.getMyTopTracks({ limit: 5 }) // Get your top 5 tracks
// ]);
// }).then(([topArtists, topTracks]) => {
// // Extract necessary information from the response
// const seedArtists = topArtists.body.items.map(artist => artist.id); // Get the IDs of your top artists
// const seedTracks = topTracks.body.items.map(track => track.uri); // Get the URIs of your top tracks
// // You can also extract genres from top artists if needed
// // Now you have the necessary information to use as seed parameters for recommendations
// console.log('Seed Artists:', seedArtists);
// console.log('Seed Tracks:', seedTracks);
// }).catch(error => {
// console.error('Error getting top artists and tracks:', error);
// res.status(500).send('Internal server error');
// });
// });
// app.get('/play', (req, res) => {
// const { deviceId, uri } = req.query;
// if (!deviceId) {
// res.status(400).send('No device selected.');
// return;
// }
// spotifyApi.play({ uris: [uri], device_id: deviceId })
// .then(() => {
// res.sendStatus(200); // Playback started successfully
// })
// .catch(error => {
// if (error.statusCode === 404 && error.body.error.reason === 'NO_ACTIVE_DEVICE') {
// res.status(400).send('No active device found. Please open Spotify on your device and try again.');
// } else {
// console.error('Error playing track:', error);
// res.status(500).send('Error starting playback. Please try again.');
// }
// });
// });
app.listen(port,()=>{
console.log(`Listening at http://localhost:${port}/login`)
})