deezer link support

This commit is contained in:
Soph :3 2025-12-20 14:38:28 +02:00
parent de10005da7
commit 959eedb964

View file

@ -36,7 +36,9 @@ const command = new SlashCommandBuilder()
function isValidSendGbUrl(url) { function isValidSendGbUrl(url) {
return /^https:\/\/sendgb\.com\/[A-Za-z0-9]+$/.test(url); return /^https:\/\/sendgb\.com\/[A-Za-z0-9]+$/.test(url);
} }
function isValidDeezerUrl(url) {
return /^https:\/\/(www\.)?deezer\.com\/(en\/)?album\/\d+/.test(url);
}
const rest = new REST({ version: "10" }).setToken(process.env.DISCORD_TOKEN); const rest = new REST({ version: "10" }).setToken(process.env.DISCORD_TOKEN);
@ -49,6 +51,26 @@ await rest.put(
); );
async function getDeezerAlbum(url) {
const match = url.match(/album\/(\d+)/);
if (!match) return null;
const albumId = match[1];
const apiUrl = `https://api.deezer.com/album/${albumId}`;
const res = await fetch(apiUrl);
if (!res.ok) return null;
const data = await res.json();
return {
title: data.title,
artist: data.artist.name,
link: data.link,
cover: data.cover_medium,
releaseDate: data.release_date,
tracks: data.tracks?.data?.map(t => t.title).join(", ") || "No tracks info",
};
}
async function getLastFmArtist(artist) { async function getLastFmArtist(artist) {
const url = const url =
"https://ws.audioscrobbler.com/2.0/?" + "https://ws.audioscrobbler.com/2.0/?" +
@ -123,9 +145,7 @@ client.on("interactionCreate", async interaction => {
if (interaction.guildId !== process.env.GUILD_ID) { if (interaction.guildId !== process.env.GUILD_ID) {
return interaction.reply({ return interaction.reply({
content: "❌ This command can only be used in the main server.", content: "❌ This command can only be used in the main server.",
flags: { ephemeral: true,
}
}); });
} }
@ -134,25 +154,70 @@ client.on("interactionCreate", async interaction => {
const description = interaction.options.getString("description"); const description = interaction.options.getString("description");
await interaction.deferReply({ ephemeral: true }); await interaction.deferReply({ ephemeral: true });
if (!artistName && !url) { if (!artistName && !url) {
return interaction.editReply({ return interaction.editReply({
content: "❌ You must provide either an artist name or a SendGB URL.", content: "❌ You must provide either an artist name or a URL.",
}); });
} }
const channel = await client.channels.fetch(process.env.REQUEST_CHANNEL_ID);
if (url) { if (url) {
if (!isValidSendGbUrl(url)) { if (isValidSendGbUrl(url)) {
if (!description) {
return interaction.editReply({ return interaction.editReply({
content: "❌ Invalid SendGB URL format.", content: "❌ A description is required when submitting a SendGB URL.",
}); });
} }
if (!description) { await channel.send({
embeds: [
{
title: "📦 External Upload",
description,
fields: [
{ name: "Download", value: url },
{ name: "Requested by", value: `<@${interaction.user.id}>` },
],
},
],
});
return interaction.editReply({ content: "✅ SendGB link submitted." });
}
if (isValidDeezerUrl(url)) {
const album = await getDeezerAlbum(url);
if (!album) {
return interaction.editReply({ return interaction.editReply({
content: "❌ A description is required when submitting a URL.", content: "❌ Could not fetch album info from Deezer.",
}); });
} }
await channel.send({
embeds: [
{
title: album.title,
url: album.link,
description: `Artist: **${album.artist}**\nRelease Date: ${album.releaseDate}`,
thumbnail: { url: album.cover },
fields: [
{ name: "Tracks", value: album.tracks },
{ name: "Requested by", value: `<@${interaction.user.id}>` },
],
},
],
});
return interaction.editReply({ content: "✅ Deezer album info submitted." });
} }
return interaction.editReply({
content: "❌ URL is not a valid SendGB or Deezer link.",
});
}
if (artistName) { if (artistName) {
if (await navidromeHasArtist(artistName)) { if (await navidromeHasArtist(artistName)) {
return interaction.editReply({ return interaction.editReply({
@ -162,72 +227,30 @@ client.on("interactionCreate", async interaction => {
const artist = await getLastFmArtist(artistName); const artist = await getLastFmArtist(artistName);
if (!artist) { if (!artist) {
return interaction.editReply({ return interaction.editReply({ content: "❌ Artist not found on Last.fm." });
content: "❌ Artist not found on Last.fm.",
});
} }
const channel = await client.channels.fetch(process.env.REQUEST_CHANNEL_ID);
await channel.send({ await channel.send({
embeds: [ embeds: [
{ {
title: artist.name, title: artist.name,
url: artist.url, url: artist.url,
description: description: artist.bio?.summary?.replace(/<[^>]*>/g, "") ?? "No description available.",
artist.bio?.summary?.replace(/<[^>]*>/g, "") ??
"No description available.",
thumbnail: { thumbnail: {
url: url: artist.image?.find(i => i.size === "extralarge")?.["#text"] ?? null,
artist.image?.find(i => i.size === "extralarge")?.["#text"] ??
null,
}, },
fields: [ fields: [
{ name: "Listeners", value: artist.stats.listeners, inline: true }, { name: "Listeners", value: artist.stats.listeners, inline: true },
{ name: "Playcount", value: artist.stats.playcount, inline: true }, { name: "Playcount", value: artist.stats.playcount, inline: true },
{ { name: "Tags", value: artist.tags?.tag?.map(t => t.name).join(", ") || "None" },
name: "Tags", { name: "Requested by", value: `<@${interaction.user.id}>` },
value:
artist.tags?.tag?.map(t => t.name).join(", ") || "None",
},
{
name: "Requested by",
value: `<@${interaction.user.id}>`,
},
], ],
}, },
], ],
}); });
return interaction.editReply({ return interaction.editReply({ content: "✅ Artist request submitted." });
content: "✅ Artist request submitted.",
});
} }
const channel = await client.channels.fetch(process.env.REQUEST_CHANNEL_ID);
await channel.send({
embeds: [
{
title: "📦 External Upload",
description,
fields: [
{
name: "Download",
value: url,
},
{
name: "Requested by",
value: `<@${interaction.user.id}>`,
},
],
},
],
});
await interaction.editReply({
content: "✅ Link submitted.",
});
}); });
/* --------------------------------- Ready -------------------------------- */ /* --------------------------------- Ready -------------------------------- */