goat
command
song
YouTube theke gaan download
0
views
0
likes
0
installs
Aliases: song
raw source
const axios = require("axios");
const yts = require("yt-search");
const fs = require("fs");
const path = require("path");
const { alldown } = require("shaon-video-downloader");
const CACHE_DIR = path.join(__dirname, "cache");
function tempFilePath(ext) {
if (!fs.existsSync(CACHE_DIR)) {
fs.mkdirSync(CACHE_DIR, { recursive: true });
}
return path.join(
CACHE_DIR,
`sing_${Date.now()}_${Math.floor(Math.random() * 10000)}.${ext}`
);
}
function react(api, messageID, emoji) {
try {
api.setMessageReaction(
emoji,
messageID,
() => {},
true
);
} catch (_) {}
}
function cleanFileName(name) {
return String(name || "song")
.replace(/[\/:*?"<>|]/g, "")
.replace(/\s+/g, " ")
.trim()
.slice(0, 100) || "song";
}
async function getDownloadLink(videoUrl) {
const data = await alldown(videoUrl);
if (!data || data.status !== true) {
throw new Error(
data?.message ||
data?.error ||
"Download link paoa jayni"
);
}
/*
shaon-video-downloader response e
audio object thakle audio.url use korbo.
*/
let downloadUrl = null;
if (data.audio?.url) {
downloadUrl = data.audio.url;
}
// fallback
if (!downloadUrl && data.url) {
downloadUrl = data.url;
}
if (!downloadUrl) {
throw new Error("MP3 download link paoa jayni");
}
return {
downloadUrl,
title: data.title || "Unknown Song",
author: data.author || "",
source: data.source || "YouTube"
};
}
async function downloadMP3(downloadUrl, filePath) {
const response = await axios.get(downloadUrl, {
responseType: "stream",
timeout: 300000,
maxContentLength: Infinity,
maxBodyLength: Infinity,
headers: {
"User-Agent":
"Mozilla/5.0 (Linux; Android 11) AppleWebKit/537.36 Chrome/120.0 Mobile Safari/537.36"
}
});
const writer = fs.createWriteStream(filePath);
await new Promise((resolve, reject) => {
let finished = false;
const fail = (err) => {
if (finished) return;
finished = true;
try {
writer.destroy();
} catch (_) {}
try {
fs.unlinkSync(filePath);
} catch (_) {}
reject(err);
};
response.data.on("error", fail);
writer.on("error", fail);
writer.on("finish", () => {
if (finished) return;
finished = true;
resolve();
});
response.data.pipe(writer);
});
if (!fs.existsSync(filePath)) {
throw new Error("MP3 file create hoyni");
}
const stats = fs.statSync(filePath);
if (stats.size < 1024) {
try {
fs.unlinkSync(filePath);
} catch (_) {}
throw new Error(
`Downloaded file too small (${stats.size} bytes)`
);
}
}
async function sendWithRetry(message, msg, retries = 2) {
for (let i = 0; i <= retries; i++) {
try {
return await message.reply(msg);
} catch (err) {
const errorText = String(
err?.message || err || ""
);
const is408 =
err?.error === 408 ||
errorText.includes("408") ||
errorText.toLowerCase().includes("timeout");
if (is408 && i < retries) {
console.warn(
`[sing] Upload timeout, retrying (${i + 1}/${retries})...`
);
await new Promise(resolve =>
setTimeout(resolve, 2000)
);
continue;
}
throw err;
}
}
}
function extractError(err) {
if (!err) return "Unknown error";
if (typeof err === "string") {
return err;
}
if (err.message) {
return err.message;
}
try {
return JSON.stringify(err);
} catch (_) {
return "Unknown error";
}
}
module.exports.config = {
name: "song",
aliases: ["song"],
version: "2.0.0",
author: "SUJON - BOSS",
countDown: 5,
role: 0,
shortDescription: "YouTube theke gaan download",
longDescription:
"Song name diye YouTube theke MP3 download kore Messenger e pathay",
category: "media",
guide: {
en:
"{pn} <song name>\n" +
"Example: {pn} mann mera"
}
};
module.exports.onStart = async function ({
api,
event,
args,
message
}) {
const { messageID } = event;
const query = args
.join(" ")
.trim();
if (!query) {
return message.reply(
"❌ Song name den.\n\n" +
"Example:\n" +
"sing mann mera"
);
}
react(api, messageID, "⏳");
let file = null;
try {
console.log(
`[sing] Searching YouTube: ${query}`
);
// YouTube search
const search = await yts(query);
const video = search.videos?.[0];
if (!video) {
react(api, messageID, "❌");
return message.reply(
`❌ "${query}" er kono YouTube result paoa jayni.`
);
}
console.log(
`[sing] Found: ${video.title}`
);
react(api, messageID, "🔎");
// shaon-video-downloader API/package
const info = await getDownloadLink(
video.url
);
if (!info.downloadUrl) {
throw new Error(
"MP3 download URL paoa jayni"
);
}
file = tempFilePath("mp3");
react(api, messageID, "⬇️");
console.log(
"[sing] Downloading MP3..."
);
await downloadMP3(
info.downloadUrl,
file
);
console.log(
"[sing] MP3 download complete"
);
const fileName = cleanFileName(
info.title || video.title
);
react(api, messageID, "📤");
await sendWithRetry(message, {
body:
`🎵 ${fileName}\n\n` +
`👤 ${info.author || video.author?.name || "Unknown"}\n` +
`🕒 ${video.timestamp || "Unknown"}\n` +
`📺 YouTube`,
attachment: fs.createReadStream(file)
});
react(api, messageID, "✅");
console.log(
`[sing] Sent successfully: ${fileName}`
);
} catch (err) {
console.error(
"[sing ERROR]",
err
);
react(api, messageID, "❌");
const errorMessage =
extractError(err);
return message.reply(
"❌ Song download failed!\n\n" +
`📌 ${errorMessage}`
);
} finally {
// Cache cleanup
if (file) {
try {
if (fs.existsSync(file)) {
fs.unlinkSync(file);
console.log(
"[sing] Cache deleted"
);
}
} catch (e) {
console.error(
"[sing] Cleanup error:",
e.message
);
}
}
}
};