← back to browse
goat command

sing

YouTube theke gaan download

2
views
0
likes
2
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: "sing",
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
			);
		}
	}
}

};

View raw file