Lynx Snip

downloader-spotify

#3r4cfi3

javascript ยท 181 baris ยท 23481 dilihat

Lihat raw
/**
 * ๐Ÿ€ Plugin : Spotify & Lyrics Search (NIXCODE UI v4.6 & Smart LRCLib)
 */

import axios from 'axios';
import { Button } from '../lib/nixcode.js';

const SPOTIFY_SEARCH_1 = "https://api.nexray.eu.cc/search/spotify";
const SPOTIFY_SEARCH_V1 = "https://api.nexray.eu.cc/search/v1/spotify";
const SPOTIFY_DL = "https://api.nexray.eu.cc/downloader/spotify";

function formatDuration(ms) {
    if (!ms) return "-";
    let minutes = Math.floor(ms / 60000);
    let seconds = ((ms % 60000) / 1000).toFixed(0);
    return minutes + ":" + (seconds < 10 ? '0' : '') + seconds;
}

// Fungsi Lirik Pintar & Akurat (Menyaring versi instrumental/lagu kosong)
async function getLyrics(artist, title) {
    try {
        let searchQuery = artist && title ? `${artist} ${title}` : title;
        if (!searchQuery) return null;

        const { data } = await axios.get(`https://lrclib.net/api/search?q=${encodeURIComponent(searchQuery)}`, {
            headers: {
                referer: `https://lrclib.net/search/${encodeURIComponent(searchQuery)}`,
                'user-agent': 'Mozilla/5.0 (Linux; Android 10; K) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/137.0.0.0 Mobile Safari/537.36'
            },
            timeout: 15000
        });
        
        if (!data || !data.length) return null;

        // Saring data: Ambil yang memiliki plainLyrics, panjang teks > 50 karakter, dan bukan instrumental
        let validSongs = data.filter(v => v.plainLyrics && v.plainLyrics.length > 50 && !v.instrumental);
        
        // Prioritaskan yang cocok dengan nama artisnya jika ada
        let matchedSong = validSongs.find(v => artist && v.artistName.toLowerCase().includes(artist.toLowerCase())) || validSongs[0] || data[0];

        return matchedSong?.plainLyrics || null;
    } catch (e) {
        return null;
    }
}

let handler = async (m, { conn, text, usedPrefix, command, args }) => {
    let cmd = command.toLowerCase();
    let query = text || args.join(" ");

    // ==========================================
    // 1. LYRICS (.lyrics / .lirik)
    // ==========================================
    if (cmd === "lyrics" || cmd === "lirik") {
        if (!query) return m.reply(`โš ๏ธ *Contoh penggunaan:*\n${usedPrefix + command} seafret atlantis`);
        
        await m.react('๐Ÿ”');
        try {
            let res = await axios.get(`https://lrclib.net/api/search?q=${encodeURIComponent(query)}`, {
                headers: {
                    referer: `https://lrclib.net/search/${encodeURIComponent(query)}`,
                    'user-agent': 'Mozilla/5.0 (Linux; Android 10; K) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/137.0.0.0 Mobile Safari/537.36'
                },
                timeout: 15000
            });
            
            if (!res.data || !res.data.length) throw new Error("Lirik tidak ditemukan!");

            let song = res.data.find(v => v.plainLyrics && v.plainLyrics.length > 50) || res.data[0];
            let hasil = `๐ŸŽต *LYRICS FINDER*\n\n` +
                        `*Judul:* ${song.trackName || '-'}\n` +
                        `*Artis:* ${song.artistName || '-'}\n` +
                        `*Album:* ${song.albumName || '-'}\n\n` +
                        `๐Ÿ“‘ *Lirik:*\n${song.plainLyrics || 'Tidak ada lirik tersedia.'}\n\n` +
                        `> ยฉ Erine-AI`;

            await conn.sendMessage(m.chat, { text: hasil }, { quoted: m });
            await m.react('โœ…');
        } catch (e) {
            await m.react('โŒ');
            m.reply(`โŒ Error: ${e.message}`);
        }
        return;
    }

    // ==========================================
    // 2. SPOTIFY SEARCH (.spotify / .spsearch)
    // ==========================================
    if (cmd === "spotify" || cmd === "spsearch") {
        if (!query) return m.reply(`โš ๏ธ *Contoh penggunaan:*\n${usedPrefix + command} seafret atlantis`);
        
        await m.react('โณ');
        try {
            let res;
            try {
                res = await axios.get(`${SPOTIFY_SEARCH_1}?q=${encodeURIComponent(query)}`, { timeout: 30000 });
            } catch (err) {
                res = await axios.get(`${SPOTIFY_SEARCH_V1}?q=${encodeURIComponent(query)}`, { timeout: 30000 });
            }

            let tracks = res.data?.result || res.data?.tracks || res.data?.data || res.data;
            if (!Array.isArray(tracks) || !tracks.length) throw new Error("Lagu tidak ditemukan.");

            let track = tracks[0];
            let trackUrl = track.url || track.external_urls?.spotify || track.link;
            let title = track.title || track.name || 'Tanpa Judul';
            let artist = track.artist || track.artists?.map(v => v.name).join(', ') || 'Unknown';
            let album = track.album || track.album?.name || '-';
            let duration = track.duration_ms ? formatDuration(track.duration_ms) : (track.duration || '-');
            let thumbnail = track.image || track.thumbnail || track.album?.images?.[0]?.url;

            // Ambil lirik dengan menyertakan nama artis + judul agar anti nyasar ke lagu instrumen
            let lirikText = await getLyrics(artist, title);
            if (!lirikText) lirikText = await getLyrics(null, query);
            if (!lirikText) lirikText = "Lirik tidak tersedia.";

            let captionText = 
                `๐ŸŽต *Judul:* ${title}\n` +
                `๐ŸŽค *Penyanyi:* ${artist}\n` +
                `๐Ÿ’ฟ *Album:* ${album}\n` +
                `โฑ๏ธ *Durasi:* ${duration}\n\n` +
                `๐Ÿ“œ *Lirik:*\n${lirikText}\n\n` +
                `> ยฉ Erine-AI`;

            let button = new Button(conn)
                .setTitle('๐ŸŽง NOW PLAYING')
                .setSubtitle(artist)
                .setBody(captionText)
                .setFooter('');

            if (thumbnail) button.setImage(thumbnail);
            if (trackUrl) {
                button.addReply('๐Ÿ“ฅ Download MP3', `${usedPrefix}spdl ${trackUrl}`, { icon: 'DEFAULT' });
                button.addUrl('๐Ÿ”— Open Spotify', trackUrl, true, { icon: 'PROMOTION' });
            }

            await button.send(m.chat, { quoted: m });
            await m.react('โœ…');
        } catch (e) {
            await m.react('โŒ');
            m.reply(`โŒ Gagal: ${e.message}`);
        }
        return;
    }

    // ==========================================
    // 3. SPOTIFY DOWNLOADER (.spdl)
    // ==========================================
    if (cmd === "spdl" || cmd === "spotifydl") {
        if (!query) return m.reply(`โš ๏ธ *Masukkan URL Spotify!*\n\n*Contoh:*\n${usedPrefix + command} https://open.spotify.com/track/...`);
        
        await m.react('๐ŸŽง');
        try {
            let { data } = await axios.get(`${SPOTIFY_DL}?url=${encodeURIComponent(query)}`, { timeout: 50000 });
            let audioUrl = data?.result?.url || data?.result?.download || data?.url || data?.data;
            
            if (!audioUrl) throw new Error("Link unduhan audio tidak valid dari API.");

            await conn.sendMessage(m.chat, {
                audio: { url: audioUrl },
                mimetype: 'audio/mpeg',
                fileName: `SpotifyMusic.mp3`,
                ptt: false
            }, { quoted: m });
            
            await m.react('โœ…');
        } catch (e) {
            await m.react('โŒ');
            m.reply(`โŒ Gagal download: ${e.message}`);
        }
        return;
    }
};

handler.help = ["lyrics <query>", "spotify <query>", "spdl <url>"];
handler.tags = ["downloader", "tools", "internet"];
handler.command = /^(lyrics|lirik|spotify|spsearch|spdl|spotifydl)$/i;
handler.limit = true;
handler.register = true;

export default handler;