Created
December 31, 2025 12:05
-
-
Save ONLym22/f7a256d18f9c14128fd26f2d14647ec1 to your computer and use it in GitHub Desktop.
Uploaded via ONLym Bot
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| //Spotify Downloader | |
| import axios from "axios" | |
| import { spawn } from "child_process" | |
| import fs from "fs" | |
| const CLIENT_ID = "Isi" | |
| const CLIENT_SECRET = "isi" | |
| process.env.YTDLP_COOKIES = "cookies.txt" | |
| process.env.YTDLP_JS = "node" | |
| const getToken = async () => { | |
| const body = new URLSearchParams({ grant_type: "client_credentials" }).toString() | |
| const auth = Buffer.from(`${CLIENT_ID}:${CLIENT_SECRET}`).toString("base64") | |
| const r = await axios.post("https://accounts.spotify.com/api/token", body, { | |
| headers: { | |
| "Content-Type": "application/x-www-form-urlencoded", | |
| Authorization: `Basic ${auth}` | |
| }, | |
| timeout: 10000 | |
| }) | |
| return r.data.access_token | |
| } | |
| const spotifyMeta = async url => { | |
| const id = url.match(/track\/([a-zA-Z0-9]+)/)?.[1] | |
| if (!id) throw new Error("URL Spotify tidak valid") | |
| const token = await getToken() | |
| const r = await axios.get(`https://api.spotify.com/v1/tracks/${id}`, { | |
| headers: { Authorization: `Bearer ${token}` }, | |
| timeout: 10000 | |
| }) | |
| const t = r.data | |
| return { | |
| title: t.name, | |
| artist: t.artists.map(a => a.name).join(" "), | |
| album: t.album.name, | |
| releaseDate: t.album.release_date, | |
| duration: Math.floor(t.duration_ms / 1000), | |
| cover: t.album.images?.[0]?.url, | |
| spotify: t.external_urls.spotify | |
| } | |
| } | |
| const ytMeta = query => new Promise((resolve, reject) => { | |
| const y = spawn("yt-dlp", [ | |
| "--dump-json", | |
| "--skip-download", | |
| "--cookies", process.env.YTDLP_COOKIES, | |
| "--js-runtime", process.env.YTDLP_JS, | |
| `ytsearch1:${query}` | |
| ]) | |
| let out = "" | |
| y.stdout.on("data", d => out += d.toString()) | |
| y.stderr.on("data", d => process.stderr.write(d)) | |
| y.on("close", () => { | |
| try { | |
| const i = JSON.parse(out) | |
| resolve({ | |
| title: i.title, | |
| author: i.uploader || i.channel, | |
| releaseDate: i.release_date, | |
| duration: i.duration, | |
| views: i.view_count, | |
| url: i.webpage_url, | |
| thumbnail: Array.isArray(i.thumbnails) ? i.thumbnails.at(-1)?.url : i.thumbnail | |
| }) | |
| } catch (e) { reject(e) } | |
| }) | |
| }) | |
| const ytAudio = query => new Promise((resolve, reject) => { | |
| const out = "output.m4a" | |
| const y = spawn("yt-dlp", [ | |
| "-f", "bestaudio/best", | |
| "--cookies", process.env.YTDLP_COOKIES, | |
| "--js-runtime", process.env.YTDLP_JS, | |
| "-o", "-", | |
| `ytsearch1:${query}` | |
| ]) | |
| const ff = spawn("ffmpeg", [ | |
| "-y", | |
| "-i", "pipe:0", | |
| "-vn", | |
| "-c:a", "aac", | |
| "-b:a", "192k", | |
| "-movflags", "+faststart", | |
| out | |
| ]) | |
| y.stdout.pipe(ff.stdin) | |
| y.stderr.on("data", d => process.stderr.write(d)) | |
| ff.stderr.on("data", d => process.stderr.write(d)) | |
| ff.on("close", c => { | |
| if (c === 0) { | |
| const buf = fs.readFileSync(out) | |
| resolve(buf) | |
| } else reject(new Error("Convert gagal")) | |
| }) | |
| }) | |
| let handler = async (m, { conn, args, command }) => { | |
| try { | |
| if (!args[0]) return m.reply(`*Example :* .${command} https://open.spotify.com/track/xxxxx`) | |
| m.reply("Wait") | |
| const sp = await spotifyMeta(args[0]) | |
| const query = `${sp.title} ${sp.artist}` | |
| const [d, buf] = await Promise.all([ | |
| ytMeta(query), | |
| ytAudio(query) | |
| ]) | |
| const cap = | |
| `*${sp.title}* | |
| *Artist :* ${sp.artist} | |
| *Album :* ${sp.album} | |
| *Release :* ${sp.releaseDate} | |
| *Duration :* ${sp.duration}s | |
| *Spotify :* ${sp.spotify} | |
| *Source :* ${d.url} | |
| > Send Audio` | |
| await conn.sendMessage( | |
| m.chat, | |
| { image: { url: sp.cover || d.thumbnail }, caption: cap }, | |
| { quoted: m } | |
| ) | |
| await conn.sendMessage( | |
| m.chat, | |
| { audio: buf, mimetype: "audio/mpeg" }, | |
| { quoted: m } | |
| ) | |
| } catch (e) { | |
| m.reply(e.message) | |
| } | |
| } | |
| handler.help = ["spdl"] | |
| handler.tags = ["downloader"] | |
| handler.command = /^spdl|spotify$/i | |
| export default handler |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment