Skip to content

Instantly share code, notes, and snippets.

@ONLym22
Created December 31, 2025 12:05
Show Gist options
  • Select an option

  • Save ONLym22/f7a256d18f9c14128fd26f2d14647ec1 to your computer and use it in GitHub Desktop.

Select an option

Save ONLym22/f7a256d18f9c14128fd26f2d14647ec1 to your computer and use it in GitHub Desktop.
Uploaded via ONLym Bot
//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