Handling refresh tokens

main
Félix MIELCAREK 12 months ago
parent cc7d383d49
commit cd0969f997

1
.gitignore vendored

@ -131,3 +131,4 @@ dist
# Specific to Gold Digger # Specific to Gold Digger
spotify_access_token spotify_access_token
.vscode/

@ -6,17 +6,19 @@ const { Client } = require('pg');
//#region CONSTANTS //#region CONSTANTS
const spotifyRequestsLimit = 50; const spotifyRequestsLimit = 50;
const thresholdLove = 0.6; const thresholdLove = 0.6;
const clientId = process.env.CLIENT_ID;
const clientSecret = process.env.CLIENT_SECRET;
const client = new Client({ const client = new Client({
user: process.env.DB_USER, user: process.env.DB_USER,
host: 'localhost', host: 'localhost',
database: 'bigbrother', database: 'bigbrother',
password: process.env.DB_PASSWORD, password: process.env.DB_PASSWORD,
port: 5432 port: 5432
}); });
//#endregion //#endregion
//#region STRUCTURE //#region STRUCTURE
var albumDataStructure = { let albumDataStructure = {
savedTracks: [], savedTracks: [],
totalTracks: 0, totalTracks: 0,
name: "", name: "",
@ -31,7 +33,7 @@ async function getSavedTracks(accessToken, albums, href=`https://api.spotify.com
response.data.items.forEach(t => { response.data.items.forEach(t => {
if(t.track.album.total_tracks > 1) { if(t.track.album.total_tracks > 1) {
if(!albums[t.track.album.id]) { if(!albums[t.track.album.id]) {
var albumData = Object.create(albumDataStructure); let albumData = Object.create(albumDataStructure);
albumData.savedTracks = []; albumData.savedTracks = [];
albumData.totalTracks = t.track.album.total_tracks; albumData.totalTracks = t.track.album.total_tracks;
albums[t.track.album.id] = albumData; albums[t.track.album.id] = albumData;
@ -55,17 +57,17 @@ async function addAlbums(accessToken, idsString) {
} }
async function tresholdAlgorithm(albums, accessToken) { async function tresholdAlgorithm(albums, accessToken) {
var lovedAlbum = [] let lovedAlbum = []
for(let album in albums) { for(let album in albums) {
if(albums[album].savedTracks.length >= albums[album].totalTracks * thresholdLove) { if(albums[album].savedTracks.length >= albums[album].totalTracks * thresholdLove) {
lovedAlbum.push(album); lovedAlbum.push(album);
} }
} }
var idsString = ""; let idsString = "";
var idsList = []; let idsList = [];
var idsCounter = 0; let idsCounter = 0;
for(var album of lovedAlbum ) { for(let album of lovedAlbum ) {
idsList.push(album); idsList.push(album);
idsString = idsString.concat(album,','); idsString = idsString.concat(album,',');
idsCounter = idsCounter+1; idsCounter = idsCounter+1;
@ -93,17 +95,17 @@ async function checkAlbums(accessToken, idsString, idsList, albums) {
try { try {
const response = await axios.get(`https://api.spotify.com/v1/me/albums/contains?ids=${idsString}`, { headers: { 'Authorization': 'Bearer ' + accessToken, } }); const response = await axios.get(`https://api.spotify.com/v1/me/albums/contains?ids=${idsString}`, { headers: { 'Authorization': 'Bearer ' + accessToken, } });
var idsToDelete = ""; let idsToDelete = "";
var idsCounter = 0; let idsCounter = 0;
for(var i in response.data) { for(let i in response.data) {
if(response.data[i]) { if(response.data[i]) {
for(var track of albums[idsList[i]].savedTracks) { for(let track of albums[idsList[i]].savedTracks) {
idsToDelete = idsToDelete.concat(track, ','); idsToDelete = idsToDelete.concat(track, ',');
idsCounter = idsCounter+1; idsCounter = idsCounter+1;
if(idsCounter == 50) { if(idsCounter == 50) {
await removeTracks(accessToken, idsToDelete); await removeTracks(accessToken, idsToDelete);
var idsToDelete = ""; let idsToDelete = "";
var idsCounter = 0; let idsCounter = 0;
} }
} }
} }
@ -114,11 +116,11 @@ async function checkAlbums(accessToken, idsString, idsList, albums) {
} }
async function removeTracksAlgorithm(albums, accessToken) { async function removeTracksAlgorithm(albums, accessToken) {
var idsString = ""; let idsString = "";
var idsList = []; let idsList = [];
var idsCounter = 0; let idsCounter = 0;
for(var album in albums) { for(let album in albums) {
idsList.push(album); idsList.push(album);
idsString = idsString.concat(album,','); idsString = idsString.concat(album,',');
idsCounter = idsCounter+1; idsCounter = idsCounter+1;
@ -153,34 +155,66 @@ function stepBeggining(step) {
//#endregion //#endregion
//#region MAIN //#region MAIN
async function mainAlgorithm(accessToken) {
let albums = {};
const step1 = "Get liked tracks";
const step2 = "Apply treshold algorithm";
const step3 = "Remove saved tracks from saved albums";
try {
stepBeggining(step1);
await getSavedTracks(accessToken, albums);
stepSuccess(step1);
stepBeggining(step2);
await tresholdAlgorithm(albums, accessToken);
stepSuccess(step2);
stepBeggining(step3);
await removeTracksAlgorithm(albums, accessToken);
stepSuccess(step3);
} catch (error) { }
}
async function main() { async function main() {
await client.connect();
try { try {
await client.connect(); const selectQuery = 'SELECT * FROM public.users';
const query = 'SELECT accesstoken FROM public.users'; const selectResult = await client.query(selectQuery);
const result = await client.query(query);
for(let row of selectResult.rows) {
result.rows.forEach(async (row) => { const spotifyId = row.spotifyid;
var albums = {}; const refreshToken = row.refreshtoken;
var accessToken = row.accesstoken
let authOptions = {
const step1 = "Get liked tracks"; url: 'https://accounts.spotify.com/api/token',
const step2 = "Apply treshold algorithm"; method: 'post',
const step3 = "Remove saved tracks from saved albums"; data: {
try { refresh_token: refreshToken,
stepBeggining(step1); grant_type: 'refresh_token',
await getSavedTracks(accessToken, albums); },
stepSuccess(step1); headers: {
'content-type': 'application/x-www-form-urlencoded',
stepBeggining(step2); 'Authorization': 'Basic ' + (new Buffer.from(clientId + ':' + clientSecret).toString('base64'))
await tresholdAlgorithm(albums, accessToken); },
stepSuccess(step2); json: true
};
stepBeggining(step3);
await removeTracksAlgorithm(albums, accessToken); const response = await axios(authOptions);
stepSuccess(step3); const newAccessToken = response.data.access_token;
} catch (error) { } const newRefreshToken = response.data.refresh_token;
});
} catch (error) { console.error('Error executing query:', error) } finally { await client.end() } const updateQuery = `
UPDATE public.users
SET accesstoken = $2, refreshtoken = $3
WHERE spotifyid = $1;
`;
await client.query(updateQuery, [spotifyId, newAccessToken, newRefreshToken])
await mainAlgorithm(newAccessToken);
}
} catch (error) { console.error('Error executing select query:', error) } finally { await client.end() }
} }
//#endregion //#endregion

@ -4,13 +4,11 @@ const express = require('express')
const cookieParser = require('cookie-parser'); const cookieParser = require('cookie-parser');
const axios = require('axios'); const axios = require('axios');
const queryString = require('querystring'); const queryString = require('querystring');
const fs = require('node:fs');
const pg = require('pg'); const pg = require('pg');
//#endregion //#endregion
//#region CONSTANTS //#region CONSTANTS
const staticDir = path.join(__dirname, '../public'); const staticDir = path.join(__dirname, '../public');
const commonDir = path.join(__dirname, '../../common');
const port = 3000 const port = 3000
const clientId = process.env.CLIENT_ID; const clientId = process.env.CLIENT_ID;
const clientSecret = process.env.CLIENT_SECRET; const clientSecret = process.env.CLIENT_SECRET;
@ -99,34 +97,29 @@ app.get('/callback', (req, res) => {
axios(authOptions) axios(authOptions)
.then(async response => { .then(async response => {
/*fs.writeFile(commonDir + '/spotify_access_token', response.data.access_token, err => {
if (err) {
console.error(err);
} else {
console.log("Spotify access token recovered.")
}
});*/
const accessToken = response.data.access_token const accessToken = response.data.access_token
const refreshToken = response.data.refresh_token
try { try {
const response = await axios.get(`https://api.spotify.com/v1/me`, { headers: { 'Authorization': 'Bearer ' + accessToken, } }); const response = await axios.get(`https://api.spotify.com/v1/me`, { headers: { 'Authorization': 'Bearer ' + accessToken, } });
const data = { const data = {
SpotifyId: response.data.id, SpotifyId: response.data.id,
AccessToken: accessToken AccessToken: accessToken,
RefreshToken: refreshToken
}; };
await client.connect() await client.connect()
const sqlQuery = ` const sqlQuery = `
INSERT INTO public.users (spotifyid,accesstoken) INSERT INTO public.users (spotifyid,accesstoken,refreshtoken)
VALUES ($1,$2) VALUES ($1,$2,$3)
ON CONFLICT (spotifyid) DO UPDATE SET ON CONFLICT (spotifyid) DO UPDATE SET
accesstoken = EXCLUDED.accesstoken accesstoken = EXCLUDED.accesstoken,
refreshtoken = EXCLUDED.refreshtoken
`; `;
client.query(sqlQuery, [data.SpotifyId, data.AccessToken], (err, res) => { client.query(sqlQuery, [data.SpotifyId, data.AccessToken, data.RefreshToken], (err, res) => {
if (err) { if (err) {
console.error('Error executing query', err); console.error('Error executing query', err);
return; return;

Loading…
Cancel
Save