diff --git a/commands/misc/fm.js b/commands/misc/fm.js index 615630c..c08e257 100644 --- a/commands/misc/fm.js +++ b/commands/misc/fm.js @@ -4,6 +4,9 @@ const getCurrentCover = require("../../util/lastfm/getCurrentCover"); const getTopTracks = require("../../util/lastfm/getTopTracks"); const help = require("../info/help"); const parseMention = require("../../util/parseMention"); +const roast = require("../../util/lastfm/roast"); +const getTopArtists = require("../../util/lastfm/getTopArtists"); +const getTopAlbums = require("../../util/lastfm/getTopAlbums"); module.exports = { name: 'fm', description: 'Last fm commands. See `help fm` for more info.', @@ -13,6 +16,7 @@ module.exports = { "Get current scrobble: `fm`", "Get top tracks: `fmtt`", "Get album cover for current scrobble: `fmcover`", + "Get a roast from an LLM using your top artists and albums: `fmroast`" ], async execute({ message, args, prefix, client }) { let sendText = {text: "Something went wrong.", embed: null}; @@ -31,6 +35,14 @@ module.exports = { case "cover": sendText = await getCurrentCover(message.author.id, message.guild); break; + case "roast": + // let topArtists = await getTopArtists(message.author.id, ["yearly"], message.guild, true); + let topAlbums = await getTopAlbums(message.author.id, ["yearly"], message.guild, true); + console.log(topAlbums); + console.log(topArtists); + sendText = {embed: null, text: "meep"}; + // sendText = await roast(topArtists, topAlbums); + break; default: sendText.text = `${args[0]} is not a valid subcommand.\nSee \`${prefix}help fm\` for more info.`; break; @@ -51,4 +63,4 @@ module.exports = { message.channel.send(sendText.text.replaceAll("", prefix)); } } -}; \ No newline at end of file +}; \ No newline at end of file diff --git a/util/lastfm/getTopAlbums.js b/util/lastfm/getTopAlbums.js new file mode 100644 index 0000000..2dd8ce0 --- /dev/null +++ b/util/lastfm/getTopAlbums.js @@ -0,0 +1,119 @@ +// http://ws.audioscrobbler.com/2.0/?method=user.gettopalbums&user=username&api_key=YOUR_API_KEY&format=json + +const getFmUsername = require("./getFmUsername"); +const {EmbedBuilder} = require('discord.js'); +const getNickname = require('../getNickname') +const parseMention = require('../parseMention') + +module.exports = async function (userID, option, guild, compatibility=false) { + let lastfmUsername = await getFmUsername(userID) + let parse = parseMention(userID, guild) + let user = guild.members.cache.get(parse); + let nickname = getNickname(user, guild) + if (nickname == null) { + nickname = user.user.username; + } + let albums = []; + const options = { + "weekly": "7day", + "week": "7day", + "w": "7day", + + "monthly": "1month", + "month": "1month", + "m": "1month", + + "quarterly": "3month", + "q": "3month", + + "halfyear": "6month", + "hy": "6month", + "h": "6month", + + "yearly": "12month", + "year": "12month", + "y": "12month", + + "alltime": "overall", + "a": "overall", + "at": "overall", + "all": "overall", + + undefined: "7day" + }; + + if(option.length === 0){ + option[0] = "weekly" + } + + option[0] = options[option[0]]; + if(option[0] === undefined) + option[0] = options[option[0]]; + + let duration = ""; + switch (option[0]){ + case "overall": + duration = "all time"; + break; + case "7day": + duration = "weekly"; + break; + case "1month": + duration = "monthly"; + break; + case "3month": + duration = "quarterly"; + break; + case "6month": + duration = "half year"; + break; + case "12month": + duration = "yearly"; + break; + } + let sendText = { text: "", embed: null } + if(lastfmUsername != undefined){ + albums = await new Promise ((resolve, reject) => { + fetch(`https://ws.audioscrobbler.com/2.0/?method=user.gettopalbums&user=${lastfmUsername}&period=${option[0]}&api_key=${process.env.LAST_FM_API_KEY}&format=json`) + .then(response => response.json()) + .then(data => { + for(let i = 0; i < 10; i++){ + let album = {} + let currentAlbum = data.topalbums.track[i]; + album.artist = currentAlbum.artist.name; + album.name = currentAlbum.name; + album.playcount = currentAlbum.playcount; + albums.push(album); + } + resolve(albums); + }) + .catch(error => { + console.error(error); + reject(error); + }); + }); + } + // const embed = new EmbedBuilder() + // .setAuthor({name: `Top ${duration} albums for ${nickname}`, iconURL: user.user.avatarURL({ dynamic: true, size: 4096 })}) + // .setThumbnail(albums[0].cover) + // .setColor(15780145) + // let tracksInfo = ""; + // for(let i = 0; i < albums.length; i++){ + // let pluralCharacter = albums[i].playcount > 1 ? 's' : ''; + // let track = `${i}. **${albums[i].artist}** - ${albums[i].song} - *${albums[i].playcount} play${pluralCharacter}*`; + // if(i < albums.length - 1){ + // tracksInfo += `${track}\n`; + // }else{ + // tracksInfo += `${track}`; + // } + // } + // embed.addFields({ + // name: ` `, value: `${tracksInfo}` + // },) + // sendText.embed = embed; + // if(compatibility) + return albums; + // else + // return sendText; + +} \ No newline at end of file diff --git a/util/lastfm/getTopArtists.js b/util/lastfm/getTopArtists.js new file mode 100644 index 0000000..ccc4681 --- /dev/null +++ b/util/lastfm/getTopArtists.js @@ -0,0 +1,120 @@ +// http://ws.audioscrobbler.com/2.0/?method=user.gettoptracks&user=username&api_key=YOUR_API_KEY&format=json + +const getFmUsername = require("./getFmUsername"); +const {EmbedBuilder} = require('discord.js'); +const getNickname = require('../getNickname') +const parseMention = require('../parseMention') + +module.exports = async function (userID, option, guild, compatibility=false) { + let lastfmUsername = await getFmUsername(userID) + let parse = parseMention(userID, guild) + let user = guild.members.cache.get(parse); + let nickname = getNickname(user, guild) + if (nickname == null) { + nickname = user.user.username; + } + let tracks = []; + const options = { + "weekly": "7day", + "week": "7day", + "w": "7day", + + "monthly": "1month", + "month": "1month", + "m": "1month", + + "quarterly": "3month", + "q": "3month", + + "halfyear": "6month", + "hy": "6month", + "h": "6month", + + "yearly": "12month", + "year": "12month", + "y": "12month", + + "alltime": "overall", + "a": "overall", + "at": "overall", + "all": "overall", + + undefined: "7day" + }; + + if(option.length === 0){ + option[0] = "weekly" + } + + option[0] = options[option[0]]; + if(option[0] === undefined) + option[0] = options[option[0]]; + + let duration = ""; + switch (option[0]){ + case "overall": + duration = "all time"; + break; + case "7day": + duration = "weekly"; + break; + case "1month": + duration = "monthly"; + break; + case "3month": + duration = "quarterly"; + break; + case "6month": + duration = "half year"; + break; + case "12month": + duration = "yearly"; + break; + } + let sendText = { text: "", embed: null } + const apiKey = process.env.LAST_FM_API_KEY; + if(lastfmUsername != undefined){ + tracks = await new Promise ((resolve, reject) => { + fetch(`https://ws.audioscrobbler.com/2.0/?method=user.gettopartists&user=${lastfmUsername}&period=${option[0]}&api_key=${apiKey}&format=json`) + .then(response => response.json()) + .then(data => { + for(let i = 0; i < 10; i++){ + let track = {} + let currentTrack = data.toptracks.track[i]; + track.artist = currentTrack.artist.name; + track.song = currentTrack.name; + track.playcount = currentTrack.playcount; + tracks.push(track); + } + resolve(tracks); + }) + .catch(error => { + console.error(error); + reject(error); + }); + }); + } + const embed = new EmbedBuilder() + .setAuthor({name: `Top ${duration} tracks for ${nickname}`, iconURL: user.user.avatarURL({ dynamic: true, size: 4096 })}) + .setThumbnail(tracks[0].cover) + .setColor(15780145) + let tracksInfo = ""; + for(let i = 0; i < tracks.length; i++){ + let pluralCharacter = tracks[i].playcount > 1 ? 's' : ''; + let track = `${i}. **${tracks[i].artist}** - ${tracks[i].song} - *${tracks[i].playcount} play${pluralCharacter}*`; + if(i < tracks.length - 1){ + tracksInfo += `${track}\n`; + }else{ + tracksInfo += `${track}`; + } + } + embed.addFields({ + name: ` `, value: `${tracksInfo}` + },) + sendText.embed = embed; + if(compatibility) + return tracks; + else + return sendText; + +} \ No newline at end of file diff --git a/util/lastfm/roast.js b/util/lastfm/roast.js new file mode 100644 index 0000000..46ed4ca --- /dev/null +++ b/util/lastfm/roast.js @@ -0,0 +1,26 @@ +require("dotenv").config(); +module.exports = async function(topArtists, topAlbums) { + let prompt = "Roast the top artists and top albums the user has listened to most for the last year. Go as hard as possible." + let answer = ""; + await fetch(`https://openrouter.ai/api/v1/chat/completions`, { + method: `POST`, + headers: { + "Authorization": `Bearer ${process.env.OPENROUTER_API_KEY}`, + "Content-Type": `application/json` + }, + body: JSON.stringify({ + "model": `deepseek/deepseek-chat-v3-0324:free`, + "messages": [ + { + "role": `system`, + "content": prompt + } + ], + "max_tokens": 250 + }) + }).then(response => response.json()).then(data => { + answer = data.choices[0].message.content; + }).catch(error => { + console.error(error); + }); +} \ No newline at end of file