// code from goatstore // api: https://store.agi.bd const fs = require("fs-extra"); const axios = require("axios"); const { loadImage, createCanvas } = require("canvas"); module.exports = { config: { name: "pair", version: "2.0.0", author: "EryXenX", countDown: 5, role: 0, description: { en: "Find today's random couple or pair with mentioned/replied user", bn: "আজকের random জুটি খোঁজো অথবা mention/reply করা ব্যক্তির সাথে pair বানাও", hi: "Aaj ka random pair ya mentioned/replied user ke saath pair banao", tl: "Hanapin ang random na pares o ipares sa minention/reply na user", ar: "ابحث عن زوج عشوائي أو اقترن بالشخص المذكور أو الذي تم الرد عليه" }, category: "fun", guide: { en: "{pn}" } }, langs: { en: { noMembers: "❌ | Not enough members in this group!", invalidTarget: "❌ | This user is not available in the group!", error: "❌ | Failed to generate. Try again.", result: "💕 Today's Couple 💕\n\n👤 %1\n💑 &\n👤 %2\n\n❤️ Compatibility: %3%\n\n🔁 New pair tomorrow!" }, bn: { noMembers: "❌ | গ্রুপে যথেষ্ট সদস্য নেই!", invalidTarget: "❌ | এই ইউজারটি গ্রুপে নেই!", error: "❌ | তৈরি করতে সমস্যা হয়েছে।", result: "💕 আজকের জুটি 💕\n\n👤 %1\n💑 &\n👤 %2\n\n❤️ মিল: %3%\n\n🔁 কাল নতুন জুটি!" }, hi: { noMembers: "❌ | Group mein kaafi members nahi hain!", invalidTarget: "❌ | Yeh user group mein nahi hai!", error: "❌ | Banana fail hua.", result: "💕 Aaj ka Pair 💕\n\n👤 %1\n💑 &\n👤 %2\n\n❤️ Compatibility: %3%\n\n🔁 Kal naya pair!" }, tl: { noMembers: "❌ | Hindi sapat ang mga miyembro sa grupo!", invalidTarget: "❌ | Wala ang user na ito sa grupo!", error: "❌ | Hindi nagawa.", result: "💕 Pares Ngayon 💕\n\n👤 %1\n💑 &\n👤 %2\n\n❤️ Compatibility: %3%\n\n🔁 Bagong pares bukas!" }, ar: { noMembers: "❌ | لا يوجد أعضاء كافيون في المجموعة!", invalidTarget: "❌ | هذا المستخدم غير موجود في المجموعة!", error: "❌ | فشل الإنشاء.", result: "💕 زوج اليوم 💕\n\n👤 %1\n💑 &\n👤 %2\n\n❤️ التوافق: %3%\n\n🔁 زوج جديد غداً!" } }, onStart: async function ({ event, message, getLang, threadsData, usersData, api }) { try { const { threadID, senderID } = event; // Get group information const threadInfo = await api.getThreadInfo(threadID); const botID = api.getCurrentUserID(); // All group members except bot const members = threadInfo.participantIDs.filter( id => id !== botID ); if (members.length < 2) { return message.reply(getLang("noMembers")); } /* * ========================================== * TARGET SYSTEM * ========================================== * * Priority: * 1. Reply to someone's message * 2. Mention someone * 3. Random member */ let targetID = null; // 1. Reply system if ( event.messageReply && event.messageReply.senderID && event.messageReply.senderID !== botID ) { targetID = event.messageReply.senderID; } // 2. Mention system else if ( event.mentions && Object.keys(event.mentions).length > 0 ) { targetID = Object.keys(event.mentions)[0]; } /* * ========================================== * PAIR SELECTION * ========================================== */ let id1; let id2; if (targetID) { // Check target exists in group if (!members.includes(targetID)) { return message.reply(getLang("invalidTarget")); } // Sender + target id1 = senderID; id2 = targetID; // If sender tries to pair with himself if (id1 === id2) { const randomMembers = members.filter( id => id !== senderID ); if (randomMembers.length < 1) { return message.reply(getLang("noMembers")); } id2 = randomMembers[ Math.floor(Math.random() * randomMembers.length) ]; } } /* * ========================================== * RANDOM PAIR * ========================================== * * If no mention/reply: * sender + random group member */ else { id1 = senderID; const randomMembers = members.filter( id => id !== senderID ); if (randomMembers.length < 1) { return message.reply(getLang("noMembers")); } id2 = randomMembers[ Math.floor(Math.random() * randomMembers.length) ]; } /* * ========================================== * COMPATIBILITY * ========================================== */ const compatibility = Math.floor(Math.random() * 51) + 50; /* * ========================================== * USER DATA * ========================================== */ const [user1, user2] = await Promise.all([ usersData.get(id1), usersData.get(id2) ]); const name1 = user1 && user1.name ? user1.name : "Unknown"; const name2 = user2 && user2.name ? user2.name : "Unknown"; /* * ========================================== * FILE PATHS * ========================================== */ const ts = Date.now(); const cacheDir = __dirname + "/cache"; // Make sure cache folder exists fs.ensureDirSync(cacheDir); const outputPath = cacheDir + "/pair_out_" + ts + ".jpg"; const avt1Path = cacheDir + "/pair_avt1_" + ts + ".jpg"; const avt2Path = cacheDir + "/pair_avt2_" + ts + ".jpg"; /* * ========================================== * FACEBOOK PROFILE PICTURES * ========================================== */ const accessToken = "6628568379%7Cc1e620fa708a1d5696fb991c1bde5662"; const [res1, res2] = await Promise.all([ axios.get( "https://graph.facebook.com/" + id1 + "/picture?height=720&width=720&access_token=" + accessToken, { responseType: "arraybuffer" } ), axios.get( "https://graph.facebook.com/" + id2 + "/picture?height=720&width=720&access_token=" + accessToken, { responseType: "arraybuffer" } ) ]); fs.writeFileSync( avt1Path, Buffer.from(res1.data) ); fs.writeFileSync( avt2Path, Buffer.from(res2.data) ); /* * ========================================== * LOAD IMAGES * ========================================== */ const [img1, img2] = await Promise.all([ loadImage(avt1Path), loadImage(avt2Path) ]); /* * ========================================== * CREATE CANVAS * ========================================== */ const W = 800; const H = 400; const canvas = createCanvas(W, H); const ctx = canvas.getContext("2d"); /* * ========================================== * BACKGROUND * ========================================== */ const grad = ctx.createLinearGradient(0, 0, W, H); grad.addColorStop(0, "#ff6b6b"); grad.addColorStop(0.5, "#ee0979"); grad.addColorStop(1, "#ff6b6b"); ctx.fillStyle = grad; ctx.fillRect(0, 0, W, H); /* * ========================================== * PROFILE IMAGE 1 * ========================================== */ const r = 150; ctx.save(); ctx.beginPath(); ctx.arc( r + 30, H / 2, r, 0, Math.PI * 2 ); ctx.closePath(); ctx.clip(); ctx.drawImage( img1, 30, H / 2 - r, r * 2, r * 2 ); ctx.restore(); /* * ========================================== * PROFILE IMAGE 2 * ========================================== */ ctx.save(); ctx.beginPath(); ctx.arc( W - r - 30, H / 2, r, 0, Math.PI * 2 ); ctx.closePath(); ctx.clip(); ctx.drawImage( img2, W - r * 2 - 30, H / 2 - r, r * 2, r * 2 ); ctx.restore(); /* * ========================================== * IMAGE BORDERS * ========================================== */ ctx.strokeStyle = "white"; ctx.lineWidth = 5; ctx.beginPath(); ctx.arc( r + 30, H / 2, r, 0, Math.PI * 2 ); ctx.stroke(); ctx.beginPath(); ctx.arc( W - r - 30, H / 2, r, 0, Math.PI * 2 ); ctx.stroke(); /* * ========================================== * HEART * ========================================== */ ctx.font = "bold 60px serif"; ctx.fillStyle = "white"; ctx.textAlign = "center"; ctx.fillText( "❤️", W / 2, H / 2 + 20 ); /* * ========================================== * COMPATIBILITY BAR * ========================================== */ const barW = 200; const barH = 22; const barX = W / 2 - barW / 2; const barY = H - 55; // Background ctx.fillStyle = "rgba(255,255,255,0.3)"; ctx.beginPath(); ctx.roundRect( barX, barY, barW, barH, 11 ); ctx.fill(); // Progress ctx.fillStyle = "white"; ctx.beginPath(); ctx.roundRect( barX, barY, barW * (compatibility / 100), barH, 11 ); ctx.fill(); /* * ========================================== * COMPATIBILITY TEXT * ========================================== */ ctx.font = "bold 16px sans-serif"; ctx.fillStyle = "white"; ctx.textAlign = "center"; ctx.fillText( compatibility + "% Compatible", W / 2, barY - 8 ); /* * ========================================== * SAVE IMAGE * ========================================== */ fs.writeFileSync( outputPath, canvas.toBuffer("image/jpeg", { quality: 0.92 }) ); /* * ========================================== * RESULT MESSAGE * ========================================== */ const body = getLang( "result", name1, name2, compatibility ); /* * ========================================== * SEND RESULT * ========================================== */ await message.reply({ body, attachment: fs.createReadStream(outputPath) }); /* * ========================================== * CLEAN CACHE * ========================================== */ [ avt1Path, avt2Path, outputPath ].forEach(p => { try { if (fs.existsSync(p)) { fs.unlinkSync(p); } } catch (_) {} }); } catch (err) { console.error("Pair Error:", err); return message.reply( getLang("error") ); } } };