/** * 🍀 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 ", "spotify ", "spdl "]; handler.tags = ["downloader", "tools", "internet"]; handler.command = /^(lyrics|lirik|spotify|spsearch|spdl|spotifydl)$/i; handler.limit = true; handler.register = true; export default handler;