// code from goatstore // api: https://store.agi.bd module.exports = { config: { name: "besti", version: "1.0.0", author: "MR Mehedi| Goat Bot V2 Fixed", countDown: 40, role: 0, shortDescription: { en: "Besti & Bestu banner" }, longDescription: { en: "Create a Bestu and Besti banner with both users' profile pictures and a random Bengali caption." }, category: "image", guide: { en: "{pn} @mention or reply to a message" } }, onStart: async function ({ api, event }) { const axios = require("axios"); const fs = require("fs-extra"); const path = require("path"); const { createCanvas, loadImage } = require("canvas"); const { threadID, messageID, senderID, mentions, messageReply } = event; // ===== Template settings ===== const TEMPLATE_URL = "https://i.imgur.com/iWnk0rs.jpeg"; const REF_W = 1774; const REF_H = 887; const LEFT = { x: 407, y: 391, rx: 211, ry: 199, cut: 548 }; const RIGHT = { x: 1387, y: 399, rx: 224, ry: 199, cut: 545 }; const FOCUS_Y = 0.35; const CREDIT = "♡𝐌𝙴ʜ𝐄ᴅ𝐈♡"; // ===== Random captions ===== const CAPTIONS = [ `💖 ১. বেস্টি মানে শুধু বন্ধু নয়, একটা ছোট্ট পৃথিবী 🌍❤️ যার সাথে সব সুখ-দুঃখ ভাগ করা যায়, সে-ই আমার প্রিয় মানুষ 🫶✨`, `🌸 ২. জীবনে অনেক মানুষ আসবে যাবে, কিন্তু কিছু মানুষ স্মৃতিতে থেকে যায় 💫 আমার বেস্টি তেমনই একজন, যাকে কখনো ভুলতে পারবো না 🤍🌿`, `🦋 ৩. পাগলামি, ঝগড়া আর হাসাহাসি, সবকিছুর সঙ্গী তুমি 😍 বন্ধুত্বটা এমনই থাকুক, সারাজীবন পাশাপাশি ❤️✨`, `🌹 ৪. সম্পর্কের নাম হয়তো বেস্টি, কিন্তু অনুভূতিটা পরিবারের মতো 🏡💖 তুমি পাশে থাকলেই, সবকিছু সুন্দর লাগে 🌸`, `✨ ৫. হাজার বন্ধুর ভিড়ে, একজনই থাকে মনের মতো 🫶 সে হলো আমার বেস্টি, আমার সুখের কারণ ❤️🌺`, `💫 ৬. কখনো ঝগড়া, কখনো অভিমান, তবুও বন্ধুত্ব থাকবে অটুট 🤍 কারণ তুমি শুধু বন্ধু নও, আমার জীবনের গুরুত্বপূর্ণ অংশ 💖`, `🌙 ৭. যে আমার নীরবতাও বুঝে, যে আমার হাসির কারণ 😊 সে-ই আমার আসল বেস্টি, সে-ই আমার আপনজন ❤️`, `🌈 ৮. দূরত্ব যতই হোক, মন থেকে দূরে নয় কেউ 💕 সত্যিকারের বেস্টি সবসময়, হৃদয়ের কাছেই থাকে 🫶✨`, `🌺 ৯. বন্ধুত্বের গল্পে, সবচেয়ে সুন্দর অধ্যায় তুমি 📖💖 আমার বেস্টি হয়ে, জীবনটা আরো সুন্দর করে দিয়েছো 🌸`, `👑 ১০. একসাথে কাটানো মুহূর্তগুলো, জীবনের সেরা স্মৃতি ✨ বেস্টি তুমি থাকলে, সব দিনই হয়ে যায় বিশেষ ❤️🦋` ]; // ===== Find target user ===== let targetID = null; if (mentions && Object.keys(mentions).length > 0) { targetID = Object.keys(mentions)[0]; } else if (messageReply && messageReply.senderID) { targetID = messageReply.senderID; } if (!targetID) { return api.sendMessage( "⚠️ কাউকে মেনশন করো অথবা তার মেসেজে রিপ্লাই দাও!\n\n" + "উদাহরণ: besti @RIYA", threadID, messageID ); } if (String(senderID) === String(targetID)) { return api.sendMessage( "😅 নিজের সাথে Besti-Bestu ব্যানার বানানো যাবে না! অন্য কাউকে মেনশন করো।", threadID, messageID ); } const cacheDir = path.join(__dirname, "cache"); fs.ensureDirSync(cacheDir); const uniqueID = `${Date.now()}_${senderID}_${targetID}`; const imgPath = path.join(cacheDir, `besti_${uniqueID}.png`); const templatePath = path.join(cacheDir, "besti_template_v2.jpg"); // ===== Download template ===== const getTemplate = async () => { if (!fs.existsSync(templatePath)) { try { const res = await axios.get(TEMPLATE_URL, { responseType: "arraybuffer", timeout: 30000, headers: { "User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 Chrome/124.0 Safari/537.36", Referer: "https://imgur.com/" } }); fs.writeFileSync(templatePath, Buffer.from(res.data)); } catch (err) { throw new Error( "Template download failed: " + (err.response?.status || err.message) ); } } return loadImage(templatePath); }; // ===== Download profile pictures ===== const getAvatar = async (uid) => { const url = `https://graph.facebook.com/${uid}/picture?width=720&height=720&access_token=6628568379|c1e620fa708a1d5696fb991c1bde5662`; try { const res = await axios.get(url, { responseType: "arraybuffer", timeout: 20000, maxRedirects: 5 }); return loadImage(Buffer.from(res.data)); } catch (err) { throw new Error( "Avatar download failed: " + (err.response?.status || err.message) ); } }; // ===== Trim white borders ===== const trimBorders = (img) => { try { const tempCanvas = createCanvas(img.width, img.height); const tempCtx = tempCanvas.getContext("2d"); tempCtx.drawImage(img, 0, 0); const { data } = tempCtx.getImageData( 0, 0, img.width, img.height ); const iw = img.width; const ih = img.height; const isBlank = (i) => { const a = data[i + 3]; if (a < 20) return true; return ( data[i] > 235 && data[i + 1] > 235 && data[i + 2] > 235 ); }; const colBlank = (x) => { let n = 0; for (let y = 0; y < ih; y++) { if (isBlank((y * iw + x) * 4)) n++; } return n / ih > 0.97; }; const rowBlank = (y) => { let n = 0; for (let x = 0; x < iw; x++) { if (isBlank((y * iw + x) * 4)) n++; } return n / iw > 0.97; }; let l = 0; let r = iw - 1; let t = 0; let b = ih - 1; while (l < r && colBlank(l)) l++; while (r > l && colBlank(r)) r--; while (t < b && rowBlank(t)) t++; while (b > t && rowBlank(b)) b--; const w = r - l + 1; const h = b - t + 1; if (w < iw * 0.3 || h < ih * 0.3) { return { sx: 0, sy: 0, sw: iw, sh: ih }; } return { sx: l, sy: t, sw: w, sh: h }; } catch (_) { return { sx: 0, sy: 0, sw: img.width, sh: img.height }; } }; // ===== Draw profile picture ===== const drawAvatar = (ctx, canvas, img, frame, sx, sy) => { const cx = frame.x * sx; const cy = frame.y * sy; const rx = frame.rx * sx; const ry = frame.ry * sy; const w = rx * 2; const h = ry * 2; const src = trimBorders(img); const scale = Math.max( w / src.sw, h / src.sh ); const dw = src.sw * scale; const dh = src.sh * scale; const dx = cx - dw / 2; let dy = cy - ry - (dh - h) * FOCUS_Y; dy = Math.min(dy, cy - ry); dy = Math.max(dy, cy + ry - dh); ctx.save(); ctx.beginPath(); ctx.ellipse(cx, cy, rx, ry, 0, 0, Math.PI * 2); ctx.closePath(); ctx.clip(); // Keep the picture above the bottom banner if (frame.cut) { ctx.beginPath(); ctx.rect(0, 0, canvas.width, frame.cut * sy); ctx.clip(); } ctx.drawImage( img, src.sx, src.sy, src.sw, src.sh, dx, dy, dw, dh ); ctx.restore(); }; try { // ===== Load all images ===== const [template, avatar1, avatar2] = await Promise.all([ getTemplate(), getAvatar(senderID), getAvatar(targetID) ]); const W = template.width; const H = template.height; const sx = W / REF_W; const sy = H / REF_H; const canvas = createCanvas(W, H); const ctx = canvas.getContext("2d"); ctx.drawImage(template, 0, 0, W, H); // Left: BESTU | Right: BESTI drawAvatar(ctx, canvas, avatar1, LEFT, sx, sy); drawAvatar(ctx, canvas, avatar2, RIGHT, sx, sy); fs.writeFileSync(imgPath, canvas.toBuffer("image/png")); // ===== Get both users' names ===== let senderName = "User"; let targetName = "Friend"; try { const info = await api.getUserInfo([ senderID, targetID ]); senderName = info[senderID]?.name || senderName; targetName = info[targetID]?.name || targetName; } catch (_) {} const tag1 = `@${senderName}`; const tag2 = `@${targetName}`; const caption = CAPTIONS[Math.floor(Math.random() * CAPTIONS.length)]; const body = `╔════════════════╗ 🫶 𝐁𝐄𝐒𝐓𝐔 🫂 𝐁𝐄𝐒𝐓𝐈 🎀 ╚═════════════════╝ 👤 ${tag1} 💞 ${tag2} ${caption} ━━━━━━━━━━━━━━━━━━━ ♡𝐌𝙴ʜ𝐄ᴅ𝐈♡ ━━━━━━━━━━━━━━━━━━━`; // ===== Send image and mentions ===== return api.sendMessage( { body, mentions: [ { tag: tag1, id: senderID }, { tag: tag2, id: targetID } ], attachment: fs.createReadStream(imgPath) }, threadID, () => { fs.unlink(imgPath, () => {}); }, messageID ); } catch (err) { console.error("BESTI CMD ERROR:", err); fs.unlink(imgPath, () => {}); return api.sendMessage( "❌ Besti Banner তৈরি করা যায়নি!\n\n" + "সমস্যা: " + (err.response?.status || err.message) + "\n\nTemplate URL এবং Canvas dependency চেক করো।", threadID, messageID ); } } };