Add spotify playlist tracking
This commit is contained in:
parent
a7e35351d3
commit
9130494b00
@ -4,4 +4,9 @@ discordToken=
|
|||||||
igdbClientId=
|
igdbClientId=
|
||||||
igdbClientSecret=
|
igdbClientSecret=
|
||||||
igdbAccessToken=
|
igdbAccessToken=
|
||||||
googleplacesapikey=
|
googleplacesapikey=
|
||||||
|
spotifyClientId=
|
||||||
|
spotifyClientSecret=
|
||||||
|
spotifyAccessToken=
|
||||||
|
spotifyPlaylistTracking=
|
||||||
|
spotifyPlaylistChannel=
|
4
.gitignore
vendored
4
.gitignore
vendored
@ -4,4 +4,6 @@ config.json
|
|||||||
*.sqlite
|
*.sqlite
|
||||||
backups
|
backups
|
||||||
*.idea
|
*.idea
|
||||||
tempbeattimeline.png
|
tempbeattimeline.png
|
||||||
|
playlistinfo.json
|
||||||
|
playlistContent.json
|
127
commands/fun/postnewplaylistupdates.js
Normal file
127
commands/fun/postnewplaylistupdates.js
Normal file
@ -0,0 +1,127 @@
|
|||||||
|
const { EmbedBuilder } = require('@discordjs/builders');
|
||||||
|
const fs = require('fs');
|
||||||
|
|
||||||
|
async function getAllPlaylistTracks() {
|
||||||
|
let allTracks = [];
|
||||||
|
let offset = 0;
|
||||||
|
const limit = 100;
|
||||||
|
let total = 0;
|
||||||
|
|
||||||
|
do {
|
||||||
|
await fetch(
|
||||||
|
`https://api.spotify.com/v1/playlists/${process.env.spotifyPlaylistTracking}/tracks?limit=${limit}&offset=${offset}`,
|
||||||
|
{
|
||||||
|
method: 'GET',
|
||||||
|
headers: {
|
||||||
|
'Authorization': `Bearer ${process.env.spotifyAccessToken}`,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
)
|
||||||
|
.then(response => response.json())
|
||||||
|
.then(response => {
|
||||||
|
allTracks = allTracks.concat(response.items);
|
||||||
|
total = response.total;
|
||||||
|
offset += limit;
|
||||||
|
})
|
||||||
|
.catch(err => {
|
||||||
|
console.log(err);
|
||||||
|
});
|
||||||
|
} while (allTracks.length < total);
|
||||||
|
|
||||||
|
return allTracks;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
let seenTrackIds = new Set();
|
||||||
|
|
||||||
|
async function PostNewPlaylistUpdates(client) {
|
||||||
|
if (!process.env.spotifyPlaylistTracking || !process.env.spotifyPlaylistChannel || !process.env.spotifyAccessToken) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (fs.existsSync('./playlistContent.json')) {
|
||||||
|
seenTrackIds = new Set(JSON.parse(fs.readFileSync('./playlistContent.json', 'utf-8')));
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
seenTrackIds = new Set();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
const tracks = await getAllPlaylistTracks();
|
||||||
|
if (tracks.length <= 1) return;
|
||||||
|
|
||||||
|
const currentIds = tracks.map(item => item.track.id);
|
||||||
|
|
||||||
|
let newTracks;
|
||||||
|
|
||||||
|
if (seenTrackIds.size > 0)
|
||||||
|
{
|
||||||
|
newTracks = currentIds.filter(id => !seenTrackIds.has(id));
|
||||||
|
} else {
|
||||||
|
newTracks = currentIds;
|
||||||
|
}
|
||||||
|
|
||||||
|
const channel = await client.channels.cache.get(process.env.spotifyPlaylistChannel);
|
||||||
|
|
||||||
|
for (const trackID of newTracks) {
|
||||||
|
// Send discord embeds;
|
||||||
|
const track = tracks.find(item => item.track.id === trackID);
|
||||||
|
|
||||||
|
console.log(track);
|
||||||
|
|
||||||
|
const embed = new EmbedBuilder()
|
||||||
|
|
||||||
|
.setColor(0x1db954)
|
||||||
|
.setTitle(`${track.track.name} added!`)
|
||||||
|
.setURL(track.track.external_urls.spotify)
|
||||||
|
.setFooter({ text: 'The Ochulus • 100 Games Challenge', iconURL: client.user.avatarURL() })
|
||||||
|
.setTimestamp();
|
||||||
|
|
||||||
|
if (track.added_by) {
|
||||||
|
await fetch(
|
||||||
|
`https://api.spotify.com/v1/users/${track.added_by.id}`,
|
||||||
|
{
|
||||||
|
method: 'GET',
|
||||||
|
headers: {
|
||||||
|
'Authorization': `Bearer ${process.env.spotifyAccessToken}`,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
)
|
||||||
|
.then(response => response.json())
|
||||||
|
.then(response => {
|
||||||
|
if (response.images.length > 0) {
|
||||||
|
embed.setAuthor({ name: `${response.display_name} added a new song!`, iconURL: response.images[0].url });
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
embed.setAuthor({ name: `${response.display_name} added a new song!` });
|
||||||
|
}
|
||||||
|
})
|
||||||
|
.catch(err => {
|
||||||
|
console.log(err);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
embed.addFields({ name: 'Title', value: `[${track.track.name}](${track.track.external_urls.spotify})`, inline: true });
|
||||||
|
|
||||||
|
const artists = track.track.artists.map(artist => `[${artist.name}](${artist.external_urls.spotify})`).join(', ');
|
||||||
|
embed.addFields({ name: 'Artists', value: artists, inline: true });
|
||||||
|
|
||||||
|
embed.addFields({ name: 'Album', value: `[${track.track.album.name}](${track.track.album.external_urls.spotify})`, inline: true });
|
||||||
|
|
||||||
|
if (track.track.album.images.length > 0)
|
||||||
|
{
|
||||||
|
embed.setThumbnail(track.track.album.images[0].url);
|
||||||
|
}
|
||||||
|
|
||||||
|
await channel.send({ embeds: [embed] });
|
||||||
|
}
|
||||||
|
|
||||||
|
seenTrackIds = new Set(currentIds);
|
||||||
|
|
||||||
|
fs.writeFileSync('./playlistContent.json', JSON.stringify([...seenTrackIds]));
|
||||||
|
}
|
||||||
|
|
||||||
|
module.exports = {
|
||||||
|
getAllPlaylistTracks,
|
||||||
|
PostNewPlaylistUpdates,
|
||||||
|
};
|
69
commands/fun/trackspotifyplaylist.js
Normal file
69
commands/fun/trackspotifyplaylist.js
Normal file
@ -0,0 +1,69 @@
|
|||||||
|
const { SlashCommandBuilder, EmbedBuilder } = require('discord.js');
|
||||||
|
const axios = require('axios');
|
||||||
|
const fs = require('fs');
|
||||||
|
const { getAllPlaylistTracks } = require('./postnewplaylistupdates.js');
|
||||||
|
|
||||||
|
module.exports = {
|
||||||
|
data: new SlashCommandBuilder()
|
||||||
|
.setName('trackspotifyplaylist')
|
||||||
|
.setDescription('Tracks for changes in a spotify playlist and posts updates in the channel this message is sent')
|
||||||
|
.addStringOption(option => option.setName('playlisturl').setDescription('A link to the playlist to track.').setRequired(true)),
|
||||||
|
async execute(interaction) {
|
||||||
|
|
||||||
|
await interaction.deferReply();
|
||||||
|
|
||||||
|
const playlistURL = interaction.options.getString('playlisturl');
|
||||||
|
const lastIndexOf = playlistURL.lastIndexOf('/');
|
||||||
|
const playlistID = playlistURL.substr(lastIndexOf + 1);
|
||||||
|
|
||||||
|
const embed = new EmbedBuilder()
|
||||||
|
.setColor(0xFFD700)
|
||||||
|
.setFooter({ text: 'The Ochulus • 100 Games Challenge', iconURL: interaction.client.user.avatarURL() })
|
||||||
|
.setTimestamp();
|
||||||
|
|
||||||
|
await fetch(
|
||||||
|
`https://api.spotify.com/v1/playlists/${playlistID}`,
|
||||||
|
{
|
||||||
|
method: 'GET',
|
||||||
|
headers: {
|
||||||
|
'Authorization': `Bearer ${process.env.spotifyAccessToken}`,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
)
|
||||||
|
.then(response => response.json())
|
||||||
|
.then(response => {
|
||||||
|
embed.setColor(0x1db954);
|
||||||
|
embed.setTitle(`Now tracking ${response.name}`);
|
||||||
|
embed.setURL(response.external_urls.spotify);
|
||||||
|
|
||||||
|
if (response.images) {
|
||||||
|
embed.setThumbnail(`${response.images[0].url}`);
|
||||||
|
}
|
||||||
|
|
||||||
|
embed.setDescription(`There are currently ${response.tracks.total} tracks in the playlist.`);
|
||||||
|
|
||||||
|
console.log(response);
|
||||||
|
process.env.spotifyPlaylistTracking = response.id;
|
||||||
|
process.env.spotifyPlaylistChannel = interaction.channelId;
|
||||||
|
// Save to file
|
||||||
|
|
||||||
|
const list = [];
|
||||||
|
list.push(process.env.spotifyPlaylistTracking);
|
||||||
|
list.push(process.env.spotifyPlaylistChannel);
|
||||||
|
fs.writeFileSync('./playlistinfo.json', JSON.stringify(list));
|
||||||
|
})
|
||||||
|
.catch(err => {
|
||||||
|
embed.setColor(0xFF0000);
|
||||||
|
embed.setTitle('Unable to track playlist');
|
||||||
|
console.error(err);
|
||||||
|
});
|
||||||
|
|
||||||
|
if (process.env.spotifyPlaylistTracking) {
|
||||||
|
const allTracks = await getAllPlaylistTracks();
|
||||||
|
const ids = allTracks.map(item => item.track.id);
|
||||||
|
fs.writeFileSync('./playlistContent.json', JSON.stringify([...ids]));
|
||||||
|
}
|
||||||
|
|
||||||
|
await interaction.editReply({ embeds: [embed] });
|
||||||
|
},
|
||||||
|
};
|
19
index.js
19
index.js
@ -10,6 +10,10 @@ const { igdb } = require('./igdb.js');
|
|||||||
const { backupDatabase } = require('./databaseHelperFunctions.js');
|
const { backupDatabase } = require('./databaseHelperFunctions.js');
|
||||||
new igdb();
|
new igdb();
|
||||||
|
|
||||||
|
const { Spotify } = require('./spotify.js');
|
||||||
|
new Spotify();
|
||||||
|
const { PostNewPlaylistUpdates } = require('./commands/fun/postnewplaylistupdates.js');
|
||||||
|
|
||||||
// Create a new client instance
|
// Create a new client instance
|
||||||
const client = new Client({ intents: [GatewayIntentBits.Guilds] });
|
const client = new Client({ intents: [GatewayIntentBits.Guilds] });
|
||||||
|
|
||||||
@ -68,4 +72,17 @@ setInterval(() => {
|
|||||||
backupDatabase();
|
backupDatabase();
|
||||||
}, 86000000);
|
}, 86000000);
|
||||||
|
|
||||||
backupDatabase();
|
backupDatabase();
|
||||||
|
|
||||||
|
|
||||||
|
if (fs.existsSync('./playlistinfo.json')) {
|
||||||
|
const info = JSON.parse(fs.readFileSync('./playlistinfo.json'));
|
||||||
|
process.env.spotifyPlaylistTracking = info[0];
|
||||||
|
process.env.spotifyPlaylistChannel = info[1];
|
||||||
|
}
|
||||||
|
|
||||||
|
setInterval(() => {
|
||||||
|
PostNewPlaylistUpdates(client);
|
||||||
|
}, 60000);
|
||||||
|
|
||||||
|
PostNewPlaylistUpdates(client);
|
39
spotify.js
Normal file
39
spotify.js
Normal file
@ -0,0 +1,39 @@
|
|||||||
|
class Spotify {
|
||||||
|
constructor() {
|
||||||
|
// make a new token every hour
|
||||||
|
setInterval(() => {
|
||||||
|
this.makeClientCred();
|
||||||
|
}, 3600000);
|
||||||
|
this.makeClientCred();
|
||||||
|
}
|
||||||
|
|
||||||
|
async makeClientCred() {
|
||||||
|
console.log('Making a spotify token');
|
||||||
|
|
||||||
|
const response = await fetch('https://accounts.spotify.com/api/token',
|
||||||
|
{
|
||||||
|
method: 'POST',
|
||||||
|
headers: {
|
||||||
|
'Authorization': 'Basic ' + (new Buffer.from(process.env.spotifyClientId + ':' + process.env.spotifyClientSecret).toString('base64')),
|
||||||
|
'Content-Type': 'application/x-www-form-urlencoded',
|
||||||
|
},
|
||||||
|
body: new URLSearchParams({
|
||||||
|
grant_type: 'client_credentials',
|
||||||
|
}),
|
||||||
|
},
|
||||||
|
);
|
||||||
|
|
||||||
|
const data = await response.json();
|
||||||
|
if (response.status != 200) {
|
||||||
|
console.log('Failed with ', data.status, data.body);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
process.env.spotifyAccessToken = data.access_token;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
module.exports = {
|
||||||
|
Spotify,
|
||||||
|
};
|
||||||
|
|
Loading…
x
Reference in New Issue
Block a user