// code from goatstore // api: https://store.agi.bd const axios = require("axios"); const fs = require("fs-extra"); const path = require("path"); module.exports = { config: { name: "ytv", aliases: ["ytdl", "video", "singv"], version: "2.1.0", author: "Taha Khan", countDown: 5, role: 0, description: { en: "Search YouTube videos, reply with number to download MP4", ur: "YouTube video search karein aur number reply karke MP4 download karein" }, category: "media", guide: { en: "{pn} [song name]", ur: "{pn} [gaane ka naam]" } }, async onStart({ api, event, args }) { const { threadID, messageID, senderID } = event; const query = args.join(" "); if (!query) { return api.sendMessage( "āŒ **Aapne gaane ka naam nahi likha!**\n\nšŸ’” *Example:* `.ytv Waja tum`", threadID, messageID ); } if (api.setMessageReaction) api.setMessageReaction("āŒ›", messageID, () => {}, true); try { // STEP 1: Search YouTube Videos via Nexray Search API const searchRes = await axios.get(`https://api.nexray.eu.cc/search/youtube?q=${encodeURIComponent(query)}`, { headers: { "User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36" }, timeout: 15000 }); const results = searchRes.data?.result; if (!results || !Array.isArray(results) || results.length === 0) { if (api.setMessageReaction) api.setMessageReaction("āŒ", messageID, () => {}, true); return api.sendMessage("āŒ Is naam se koi video nahi mili!", threadID, messageID); } const topResults = results.slice(0, 5); const numBadges = ["ā¶", "ā·", "āø", "ā¹", "āŗ"]; // Bold & Mota Stylized Search Box let msg = `╭━━━〔 š—¬š—¢š—Øš—§š—Øš—•š—˜ š—¦š—˜š—”š—„š—–š—› 〕━━━╮\n\n`; topResults.forEach((item, index) => { msg += `${numBadges[index]} š—§š—¶š˜š—¹š—²: ${item.title}\n` + `ā±ļø š——š˜‚š—æš—®š˜š—¶š—¼š—»: ${item.duration} | šŸ“ŗ š—–š—µš—®š—»š—»š—²š—¹: ${item.channel}\n` + `───────────────────────\n`; }); msg += `\nšŸ‘‰ š—š—¶š˜€ š˜ƒš—¶š—±š—²š—¼ š—øš—¼ š—±š—¼š˜„š—»š—¹š—¼š—®š—± š—øš—®š—æš—»š—® š—µš—®š—¶, š˜‚š˜€ š—øš—® š—»š˜‚š—ŗš—Æš—²š—æ š—æš—²š—½š—¹š˜† š—øš—®š—æš—²š—¶š—» (šŸ­-šŸ±)\n\n` + `šŸ‘‘ š—¢š—Ŗš—”š—˜š—„: š—§š—”š—›š—” š—žš—›š—”š—”\n` + `╰━━━━━━━━━━━━━━━━━━━━━╯`; if (api.setMessageReaction) api.setMessageReaction("āœ…", messageID, () => {}, true); const sendMsg = await api.sendMessage(msg, threadID, messageID); global.GoatBot.onReply.set(sendMsg.messageID, { commandName: this.config.name, messageID: sendMsg.messageID, author: senderID, results: topResults }); } catch (err) { console.error("[YTV SEARCH ERROR]:", err.message); if (api.setMessageReaction) api.setMessageReaction("āŒ", messageID, () => {}, true); return api.sendMessage("āŒ YouTube search karne me masla aaya!", threadID, messageID); } }, async onReply({ api, event, Reply }) { const { threadID, messageID, senderID, body } = event; const { author, results } = Reply; if (senderID !== author) { return api.sendMessage("āš ļø Yeh search list aap ke liye nahi hai!", threadID, messageID); } const choice = parseInt(body.trim()); if (isNaN(choice) || choice < 1 || choice > results.length) { return api.sendMessage(`āŒ Baraye meherbani 1 se ${results.length} ke darmiyan number reply karein!`, threadID, messageID); } const selectedVideo = results[choice - 1]; const videoUrl = selectedVideo.url; global.GoatBot.onReply.delete(Reply.messageID); if (api.setMessageReaction) api.setMessageReaction("āŒ›", messageID, () => {}, true); const downloadingMsg = await api.sendMessage( `šŸ“„ **"${selectedVideo.title}"** download ho rahi hai...\nā³ Baraye meherbani thoda intezar karein!`, threadID, messageID ); const cacheDir = path.join(__dirname, "cache"); await fs.ensureDir(cacheDir); const filePath = path.join(cacheDir, `ytv_${Date.now()}.mp4`); try { // STEP 2: Get MP4 Download Link via Nexray Downloader API const dlRes = await axios.get(`https://api.nexray.eu.cc/downloader/v1/ytmp4?url=${encodeURIComponent(videoUrl)}&resolusi=1080`, { headers: { "User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36" }, timeout: 30000 }); const mp4Url = dlRes.data?.result?.url; const title = dlRes.data?.result?.title || selectedVideo.title; const authorName = dlRes.data?.result?.author || selectedVideo.channel; const quality = dlRes.data?.result?.quality || "1080p"; if (!mp4Url) { if (api.setMessageReaction) api.setMessageReaction("āŒ", messageID, () => {}, true); return api.sendMessage("āŒ Video download link extract nahi ho saka!", threadID, messageID); } // STEP 3: Download Video Stream to Cache const streamRes = await axios({ method: "get", url: mp4Url, responseType: "stream", headers: { "User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36" } }); const writer = fs.createWriteStream(filePath); streamRes.data.pipe(writer); await new Promise((resolve, reject) => { writer.on("finish", resolve); writer.on("error", reject); }); if (api.setMessageReaction) api.setMessageReaction("āœ…", messageID, () => {}, true); if (downloadingMsg && downloadingMsg.messageID) { api.unsendMessage(downloadingMsg.messageID); } // STEP 4: Send MP4 Video Attachment with Bold Layout const finalMsg = `╭━━━〔 š—¬š—¢š—Øš—§š—Øš—•š—˜ š—©š—œš——š—˜š—¢ 〕━━━╮\n` + `šŸ“ š—§š—¶š˜š—¹š—²: ${title}\n` + `šŸ‘¤ š—–š—µš—®š—»š—»š—²š—¹: ${authorName}\n` + `āš™ļø š—¤š˜‚š—®š—¹š—¶š˜š˜†: ${quality}\n` + `šŸ‘‘ š—¢š—Ŗš—”š—˜š—„: š—§š—”š—›š—” š—žš—›š—”š—”\n` + `╰━━━━━━━━━━━━━━━━━━━━━╯`; await api.sendMessage( { body: finalMsg, attachment: fs.createReadStream(filePath) }, threadID, messageID ); if (fs.existsSync(filePath)) await fs.unlink(filePath); } catch (err) { console.error("[YTV DOWNLOAD ERROR]:", err.message); if (fs.existsSync(filePath)) await fs.unlink(filePath); if (api.setMessageReaction) api.setMessageReaction("āŒ", messageID, () => {}, true); return api.sendMessage("āŒ Video download ya send karne me masla aaya! File size zayada hone ki wajah se error aa sakta hai.", threadID, messageID); } } };