// code from goatstore // api: https://store.agi.bd const fs = require("fs-extra"); const path = require("path"); const axios = require("axios"); // ═══════════════════════════════════════ // 🔒 ANTI DOUBLE TRIGGER // ═══════════════════════════════════════ const running = new Set(); // ═══════════════════════════════════════ // 📁 FILE / CACHE // ═══════════════════════════════════════ const prefixFile = path.join( __dirname, "prefixData.json" ); const cacheFolder = path.join( __dirname, "cache", "prefix_gif" ); fs.ensureDirSync(cacheFolder); // ═══════════════════════════════════════ // ⏳ DELAY // ═══════════════════════════════════════ const sleep = ms => new Promise(resolve => setTimeout(resolve, ms)); // ═══════════════════════════════════════ // 💾 PREFIX FILE // ═══════════════════════════════════════ function ensurePrefixFile() { try { if (!fs.existsSync(prefixFile)) { fs.writeFileSync( prefixFile, JSON.stringify({}, null, 2) ); } } catch (e) { console.error( "prefix.js | prefixData:", e.message ); } } function getCurrentPrefix(threadID) { ensurePrefixFile(); try { const data = JSON.parse( fs.readFileSync(prefixFile, "utf8") ); return ( data[threadID] || global.GoatBot?.config?.prefix || "." ); } catch { return global.GoatBot?.config?.prefix || "."; } } function setPrefix(threadID, newPrefix) { ensurePrefixFile(); try { const data = JSON.parse( fs.readFileSync(prefixFile, "utf8") ); data[threadID] = newPrefix; fs.writeFileSync( prefixFile, JSON.stringify(data, null, 2) ); return true; } catch (e) { console.error( "prefix.js | Save prefix:", e.message ); return false; } } // ═══════════════════════════════════════ // ✨ LOADING ANIMATION // ═══════════════════════════════════════ const loadingFrames = [ "𝐋𝐨𝐚𝐝𝐢𝐧𝐠 𝐏𝐫𝐞𝐟𝐢𝐱...\n▰▱▱▱▱▱▱▱▱▱ 10%", "𝐋𝐨𝐚𝐝𝐢𝐧𝐠 𝐏𝐫𝐞𝐟𝐢𝐱...\n▰▰▰▱▱▱▱▱▱▱ 30%", "𝐋𝐨𝐚𝐝𝐢𝐧𝐠 𝐏𝐫𝐞𝐟𝐢𝐱...\n▰▰▰▰▰▱▱▱▱▱ 50%", "𝐋𝐨𝐚𝐝𝐢𝐧𝐠 𝐏𝐫𝐞𝐟𝐢𝐱...\n▰▰▰▰▰▰▰▱▱▱ 70%", "𝐋𝐨𝐚𝐝𝐢𝐧𝐠 𝐏𝐫𝐞𝐟𝐢𝐱...\n▰▰▰▰▰▰▰▰▰▱ 90%", "𝐋𝐨𝐚𝐝𝐢𝐧𝐠 𝐏𝐫𝐞𝐟𝐢𝐱...\n▰▰▰▰▰▰▰▰▰▰ 100%" ]; // ═══════════════════════════════════════ // 🎬 VIDEO LIST // ═══════════════════════════════════════ const gifs = [ "https://files.catbox.moe/tjhylq.mp4", "https://files.catbox.moe/qo2asu.mp4", "https://files.catbox.moe/jqjp2r.mp4", "https://files.catbox.moe/nm10q6.mp4", "https://files.catbox.moe/okfub6.mp4", "https://files.catbox.moe/pwe8d2.mp4", "https://files.catbox.moe/7hdws4.mp4", "https://files.catbox.moe/yzpag9.mp4" ]; // ═══════════════════════════════════════ // 📥 DOWNLOAD VIDEO // ═══════════════════════════════════════ async function downloadVideo( url, filePath, retries = 2 ) { for ( let attempt = 0; attempt <= retries; attempt++ ) { try { const response = await axios({ url, method: "GET", responseType: "arraybuffer", timeout: 30000, maxRedirects: 5, maxContentLength: 100 * 1024 * 1024, maxBodyLength: 100 * 1024 * 1024, headers: { "User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 Chrome/120 Safari/537.36", "Accept": "video/mp4,video/*,*/*" } }); const buffer = Buffer.from(response.data); if (buffer.length > 10000) { await fs.writeFile(filePath, buffer); console.log( `prefix.js → ✅ Video cached: ${path.basename(filePath)}` ); return true; } } catch (err) { console.error( `prefix.js → Download ${attempt + 1}:`, err.message ); } if (attempt < retries) { await sleep(1000); } } return false; } // ═══════════════════════════════════════ // 📦 VALID CACHE // ═══════════════════════════════════════ function getValidCachedFiles() { try { return fs .readdirSync(cacheFolder) .filter(file => { try { const fullPath = path.join( cacheFolder, file ); return ( file.endsWith(".mp4") && fs.statSync(fullPath).size > 10000 ); } catch { return false; } }); } catch { return []; } } // ═══════════════════════════════════════ // 🚀 BACKGROUND CACHE // ═══════════════════════════════════════ async function ensureCached() { console.log( "prefix.js → Background cache started..." ); for (let i = 0; i < gifs.length; i++) { const filePath = path.join( cacheFolder, `gif${i}.mp4` ); try { if ( fs.existsSync(filePath) && fs.statSync(filePath).size > 10000 ) { continue; } if (fs.existsSync(filePath)) { await fs.remove(filePath); } await downloadVideo( gifs[i], filePath, 2 ); } catch (e) { console.error( "prefix.js | Cache error:", e.message ); } } console.log( "prefix.js → Background cache finished." ); } // Background cache ensureCached().catch(() => {}); // ═══════════════════════════════════════ // 💠 PREFIX INFO // ═══════════════════════════════════════ async function showPrefixInfo({ message, event, api }) { const key = event.threadID; if (running.has(key)) { return; } running.add(key); let loadingMessage = null; try { // ═══════════════════════════════════ // 🤖 BOT INFO // ═══════════════════════════════════ const botPrefix = global.GoatBot?.config?.prefix || "."; const groupPrefix = getCurrentPrefix(event.threadID); const ping = event.timestamp ? Math.max( 0, Date.now() - event.timestamp ) : 0; const day = new Date().toLocaleString( "en-US", { weekday: "long", timeZone: "Asia/Dhaka" } ); const BOTNAME = global.GoatBot?.config?.nickNameBot || "KakashiBot"; // ═══════════════════════════════════ // 📋 FINAL TEXT // ═══════════════════════════════════ const prefixText = `╭─❍ ⟣ 𝗣𝗥𝗘𝗙𝗜𝗫 𝗜𝗡𝗙𝗢 ⟢ ❍─╮ ⏱️ 𝗣𝗶𝗻𝗴 : ${ping}ms 📅 𝗗𝗮𝘆 : ${day} 💠 𝗕𝗼𝘁 𝗣𝗿𝗲𝗳𝗶𝘅 : ${botPrefix} 💬 𝗚𝗿𝗼𝘂𝗽 𝗣𝗿𝗲𝗳𝗶𝘅 : ${groupPrefix} 🤖 𝗕𝗼𝘁 𝗡𝗮𝗺𝗲 : ${BOTNAME} ╰─❍ 𝗧𝗛𝗔𝗡𝗞 𝗬𝗢𝗨 ❍─╯ 𓊈𓊉 ══ ♡𝐌𝙴ʜ𝐄ᴅ𝐈♡ ══ 𓊈𓊉`; // ═══════════════════════════════════ // 📩 LOADING MESSAGE // ═══════════════════════════════════ try { loadingMessage = await message.reply( loadingFrames[0] ); } catch (e) { console.error( "prefix.js | Loading send:", e.message ); } // ═══════════════════════════════════ // 🔄 LOADING EDIT // ═══════════════════════════════════ if (loadingMessage?.messageID) { for ( let i = 1; i < loadingFrames.length; i++ ) { await sleep(700); try { await api.editMessage( loadingFrames[i], loadingMessage.messageID ); } catch (e) { console.log( "prefix.js | Edit:", e.message ); } } // 100% একটু দেখাবে await sleep(500); // শুধু loading message delete try { await api.unsendMessage( loadingMessage.messageID ); } catch {} loadingMessage = null; } // ═══════════════════════════════════ // 🎬 GET VIDEO // ═══════════════════════════════════ let cachedFiles = getValidCachedFiles(); if (cachedFiles.length === 0) { const shuffled = [...gifs].sort( () => Math.random() - 0.5 ); for ( let i = 0; i < shuffled.length; i++ ) { const livePath = path.join( cacheFolder, `live_${Date.now()}_${i}.mp4` ); const ok = await downloadVideo( shuffled[i], livePath, 1 ); if (ok) { cachedFiles = [ path.basename(livePath) ]; break; } } } // ═══════════════════════════════════ // 📤 TEXT + VIDEO // SAME MESSAGE // ═══════════════════════════════════ let finalMsg; if (cachedFiles.length > 0) { const chosen = cachedFiles[ Math.floor( Math.random() * cachedFiles.length ) ]; const fullPath = path.join( cacheFolder, chosen ); try { finalMsg = await message.reply({ body: prefixText, attachment: fs.createReadStream( fullPath ) }); console.log( "prefix.js → ✅ Prefix text + video sent" ); } catch (e) { console.error( "prefix.js | Video send:", e.message ); finalMsg = await message.reply( prefixText ); } } else { finalMsg = await message.reply( prefixText + "\n\n⚠️ ভিডিও লোড করা যায়নি।" ); ensureCached().catch( () => {} ); } // ═══════════════════════════════════ // 🗑️ REMOVE FINAL BOT MESSAGE // AFTER 30 SECONDS // ═══════════════════════════════════ if (finalMsg?.messageID) { setTimeout(() => { api .unsendMessage( finalMsg.messageID ) .catch(() => {}); }, 30000); } return finalMsg; } catch (e) { console.error( "prefix.js → Main error:", e.stack || e.message || e ); // Error হলেও শুধু loading delete if (loadingMessage?.messageID) { try { await api.unsendMessage( loadingMessage.messageID ); } catch {} } try { return await message.reply( "❌ Prefix command চালাতে সমস্যা হয়েছে।" ); } catch {} } finally { running.delete(key); } } // ═══════════════════════════════════════ // 🔧 SET PREFIX // ═══════════════════════════════════════ async function handleSetPrefix({ message, event, api, args, threadsData }) { const key = event.threadID; if (running.has(key)) { return; } running.add(key); try { const newPrefix = args?.[1]; if (!newPrefix) { return message.reply( "❌ | Example: prefix set !" ); } // ═══════════════════════════════════ // 👑 ADMIN CHECK // ═══════════════════════════════════ let isAdmin = false; try { const threadInfo = await api.getThreadInfo( event.threadID ); const admins = threadInfo?.adminIDs || []; const isGroupAdmin = admins.some( a => String(a.id) === String(event.senderID) ); const botAdmins = global.GoatBot?.config ?.adminBot || []; const isBotAdmin = botAdmins .map(String) .includes( String(event.senderID) ); isAdmin = isGroupAdmin || isBotAdmin; } catch { const botAdmins = global.GoatBot?.config ?.adminBot || []; isAdmin = botAdmins .map(String) .includes( String(event.senderID) ); } if (!isAdmin) { return message.reply( "❌ | শুধুমাত্র গ্রুপ এডমিন বা বট এডমিন প্রেফিক্স পরিবর্তন করতে পারবে।" ); } // ═══════════════════════════════════ // 💾 SAVE // ═══════════════════════════════════ const saved = setPrefix( event.threadID, newPrefix ); if (!saved) { return message.reply( "❌ Prefix save করা যায়নি।" ); } if (threadsData) { try { await threadsData.set( event.threadID, newPrefix, "data.prefix" ); } catch {} } const reply = await message.reply( `╭━━━━━━━━━━━━━━━━━━━━━━╮ │ ✅ 𝗣𝗥𝗘𝗙𝗜𝗫 𝗨𝗣𝗗𝗔𝗧𝗘𝗗 ╰━━━━━━━━━━━━━━━━━━━━━━╯ ✨ New Prefix : ${newPrefix} ✔ Successfully changed!` ); // ৩০ সেকেন্ড পরে শুধু bot reply delete if (reply?.messageID) { setTimeout(() => { api .unsendMessage( reply.messageID ) .catch(() => {}); }, 30000); } return reply; } finally { running.delete(key); } } // ═══════════════════════════════════════ // 🚀 GOATBOT V2 // ═══════════════════════════════════════ module.exports = { config: { name: "prefix", version: "25.0.0", author: "Hridoy", countDown: 2, role: 2, description: "Prefix info with loading animation and video", category: "utility", usePrefix: false, guide: { en: "prefix → show prefix info\n" + "prefix set → change prefix" } }, // ═══════════════════════════════════════ // COMMAND // ═══════════════════════════════════════ onStart: async function ({ message, event, api, args, threadsData }) { if ( args?.[0]?.toLowerCase() === "set" ) { return handleSetPrefix({ message, event, api, args, threadsData }); } return showPrefixInfo({ message, event, api }); }, // ═══════════════════════════════════════ // NO PREFIX: prefix // ═══════════════════════════════════════ onChat: async function ({ event, message, api, threadsData }) { if (!event.body) { return; } const body = event.body.trim(); const lower = body.toLowerCase(); // prefix set ! const setMatch = lower.match( /^prefix\s+set\s+(\S+)$/ ); if (setMatch) { return handleSetPrefix({ message, event, api, threadsData, args: [ "set", body.split(/\s+/)[2] ] }); } // শুধু prefix if (lower === "prefix") { return showPrefixInfo({ message, event, api }); } } };