// code from goatstore // api: https://store.agi.bd const axios = require("axios"); const Canvas = require("canvas"); const fs = require("fs"); const path = require("path"); module.exports = { config: { name: "pair5", version: "1.0.0", author: "𝐌𝐚𝐑𝐮𝐅", role: 0, countDown: 5, shortDescription: "Romantic pair system", category: "FUN & SOCIAL", guide: { en: "{pn}" } }, onStart: async function ({ api, event, usersData }) { const { threadID, messageID, senderID, messageReply } = event; try { let targetID = senderID; let targetName = null; if (messageReply) { targetID = messageReply.senderID; try { const userData = await usersData.get(targetID); targetName = userData.name || "User"; } catch { targetName = "User"; } } const loading = await api.sendMessage( "💗 | Finding a special match...", threadID ); const [senderData, threadInfo] = await Promise.all([ usersData.get(targetID), api.getThreadInfo(threadID) ]); const senderName = targetName || senderData.name || "User"; const senderGender = senderData.gender; const members = threadInfo.participantIDs.filter( uid => uid != targetID ); if (!members.length) { if (loading?.messageID) { try { await api.unsendMessage( loading.messageID, threadID ); } catch {} } return api.sendMessage( "❌ No other members found in this group.", threadID, messageID ); } let targetGender; if (senderGender === 1) { targetGender = 2; } else if (senderGender === 2) { targetGender = 1; } else { targetGender = Math.random() > 0.5 ? 1 : 2; } let partnerList = []; const randomMembers = members.sort( () => 0.5 - Math.random() ); for (const uid of randomMembers) { try { const data = await usersData.get(uid); if ( data && data.gender === targetGender ) { partnerList.push({ id: uid, name: data.name || "Someone", gender: data.gender }); } } catch {} } let partner; if (partnerList.length > 0) { partner = partnerList[ Math.floor( Math.random() * partnerList.length ) ]; } else { let fallbackPartner = null; for (const uid of randomMembers) { try { const data = await usersData.get(uid); if ( data && data.gender !== senderGender && data.gender !== undefined ) { fallbackPartner = { id: uid, name: data.name || "Someone", gender: data.gender }; break; } } catch {} } if (fallbackPartner) { partner = fallbackPartner; } else { const fallbackID = randomMembers[ Math.floor( Math.random() * randomMembers.length ) ]; partner = { id: fallbackID, name: "Someone Special", gender: targetGender }; } } if ( partner.gender === senderGender && senderGender !== undefined ) { for (const uid of randomMembers) { try { const data = await usersData.get(uid); if ( data && data.gender !== senderGender && data.gender !== undefined ) { partner = { id: uid, name: data.name || "Someone", gender: data.gender }; break; } } catch {} } } const match = Math.floor(Math.random() * 31) + 70; const canvas = Canvas.createCanvas(1600, 900); const ctx = canvas.getContext("2d"); const width = 1600; const height = 900; const bg = ctx.createLinearGradient( 0, 0, width, height ); bg.addColorStop( 0, "#15131c" ); bg.addColorStop( 0.48, "#27202c" ); bg.addColorStop( 1, "#100e15" ); ctx.fillStyle = bg; ctx.fillRect( 0, 0, width, height ); const glow1 = ctx.createRadialGradient( 280, 170, 10, 280, 170, 420 ); glow1.addColorStop( 0, "rgba(222,155,187,0.24)" ); glow1.addColorStop( 1, "rgba(222,155,187,0)" ); ctx.fillStyle = glow1; ctx.fillRect( 0, 0, width, height ); const glow2 = ctx.createRadialGradient( 1350, 720, 10, 1350, 720, 450 ); glow2.addColorStop( 0, "rgba(139,119,180,0.20)" ); glow2.addColorStop( 1, "rgba(139,119,180,0)" ); ctx.fillStyle = glow2; ctx.fillRect( 0, 0, width, height ); for (let i = 0; i < 120; i++) { const x = Math.random() * width; const y = Math.random() * height; const r = Math.random() * 1.8 + 0.4; ctx.beginPath(); ctx.arc( x, y, r, 0, Math.PI * 2 ); ctx.fillStyle = `rgba(255,255,255,${0.15 + Math.random() * 0.5})`; ctx.fill(); } ctx.textAlign = "left"; ctx.fillStyle = "#f5eaf0"; ctx.font = "bold 42px Arial"; ctx.fillText( "PAIR", 85, 90 ); ctx.fillStyle = "#9f8995"; ctx.font = "18px Arial"; ctx.fillText( "CONNECTION", 88, 120 ); ctx.strokeStyle = "rgba(255,255,255,0.13)"; ctx.lineWidth = 1; ctx.beginPath(); ctx.moveTo( 85, 150 ); ctx.lineTo( 1515, 150 ); ctx.stroke(); function roundedRect( x, y, w, h, r ) { ctx.beginPath(); ctx.moveTo( x + r, y ); ctx.lineTo( x + w - r, y ); ctx.quadraticCurveTo( x + w, y, x + w, y + r ); ctx.lineTo( x + w, y + h - r ); ctx.quadraticCurveTo( x + w, y + h, x + w - r, y + h ); ctx.lineTo( x + r, y + h ); ctx.quadraticCurveTo( x, y + h, x, y + h - r ); ctx.lineTo( x, y + r ); ctx.quadraticCurveTo( x, y, x + r, y ); ctx.closePath(); } function loadImage(url) { return axios .get( url, { responseType: "arraybuffer", headers: { "User-Agent": "Mozilla/5.0" }, timeout: 15000 } ) .then(res => Canvas.loadImage( res.data ) ); } const token = "6628568379|c1e620fa708a1d5696fb991c1bde5662"; const avt1 = `https://graph.facebook.com/${targetID}/picture?width=1024&height=1024&access_token=${token}`; const avt2 = `https://graph.facebook.com/${partner.id}/picture?width=1024&height=1024&access_token=${token}`; const [ img1, img2 ] = await Promise.all([ loadImage(avt1), loadImage(avt2) ]); function drawPortrait( image, x, y, size ) { ctx.save(); ctx.shadowColor = "rgba(0,0,0,0.45)"; ctx.shadowBlur = 30; ctx.shadowOffsetY = 15; ctx.fillStyle = "#f8f1f4"; roundedRect( x - 18, y - 18, size + 36, size + 36, 18 ); ctx.fill(); ctx.shadowBlur = 0; ctx.shadowOffsetY = 0; ctx.save(); roundedRect( x, y, size, size, 12 ); ctx.clip(); ctx.drawImage( image, x, y, size, size ); ctx.restore(); ctx.strokeStyle = "rgba(255,255,255,0.75)"; ctx.lineWidth = 2; roundedRect( x, y, size, size, 12 ); ctx.stroke(); ctx.restore(); } drawPortrait( img1, 120, 220, 380 ); drawPortrait( img2, 1100, 220, 380 ); ctx.textAlign = "center"; let name1 = String(senderName); let name2 = String(partner.name); if (name1.length > 18) { name1 = name1.substring( 0, 18 ) + "..."; } if (name2.length > 18) { name2 = name2.substring( 0, 18 ) + "..."; } ctx.fillStyle = "#f6eaf0"; ctx.font = "bold 30px Arial"; ctx.fillText( name1, 310, 665 ); ctx.fillText( name2, 1290, 665 ); ctx.fillStyle = "#a9939e"; ctx.font = "17px Arial"; ctx.fillText( "PERSON 01", 310, 695 ); ctx.fillText( "PERSON 02", 1290, 695 ); ctx.strokeStyle = "rgba(255,255,255,0.12)"; ctx.lineWidth = 2; ctx.beginPath(); ctx.moveTo( 535, 415 ); ctx.bezierCurveTo( 650, 350, 950, 350, 1065, 415 ); ctx.stroke(); ctx.beginPath(); ctx.moveTo( 535, 470 ); ctx.bezierCurveTo( 650, 540, 950, 540, 1065, 470 ); ctx.stroke(); ctx.shadowColor = "rgba(214,126,164,0.45)"; ctx.shadowBlur = 35; ctx.fillStyle = "#d88eab"; ctx.font = "100px Arial"; ctx.fillText( "♥", 800, 455 ); ctx.shadowBlur = 0; ctx.fillStyle = "#ead6df"; ctx.font = "15px Arial"; ctx.fillText( "TOGETHER", 800, 485 ); ctx.fillStyle = "#211a22"; roundedRect( 650, 535, 300, 105, 52 ); ctx.fill(); ctx.strokeStyle = "#6e5966"; ctx.lineWidth = 1; roundedRect( 650, 535, 300, 105, 52 ); ctx.stroke(); ctx.fillStyle = "#f8edf2"; ctx.font = "bold 46px Arial"; ctx.fillText( `${match}%`, 800, 602 ); ctx.fillStyle = "#a9929f"; ctx.font = "15px Arial"; ctx.fillText( "COMPATIBILITY", 800, 625 ); ctx.fillStyle = "#f0dce5"; ctx.font = "bold 24px Arial"; const resultText = match >= 90 ? "A RARE CONNECTION" : match >= 80 ? "A BEAUTIFUL CONNECTION" : "A SWEET CONNECTION"; ctx.fillText( resultText, 800, 735 ); ctx.fillStyle = "#9c8792"; ctx.font = "17px Arial"; ctx.fillText( "Two people • One unexpected connection", 800, 770 ); ctx.strokeStyle = "rgba(255,255,255,0.12)"; ctx.beginPath(); ctx.moveTo( 610, 810 ); ctx.lineTo( 990, 810 ); ctx.stroke(); ctx.fillStyle = "#8f7a86"; ctx.font = "14px Arial"; ctx.fillText( "✦", 590, 815 ); ctx.fillText( "✦", 1010, 815 ); ctx.fillText( "𝐌𝐚𝐑𝐮𝐅", 800, 840 ); ctx.strokeStyle = "rgba(255,255,255,0.08)"; ctx.lineWidth = 2; roundedRect( 55, 45, width - 110, height - 90, 24 ); ctx.stroke(); const cacheDir = path.join( __dirname, "cache" ); if ( !fs.existsSync(cacheDir) ) { fs.mkdirSync( cacheDir, { recursive: true } ); } const filePath = path.join( cacheDir, `pair5_${Date.now()}.png` ); fs.writeFileSync( filePath, canvas.toBuffer() ); if ( loading && loading.messageID ) { try { await api.unsendMessage( loading.messageID, threadID ); } catch {} } const emoji = match > 85 ? "💞" : match > 75 ? "💗" : "💕"; const compatibilityText = match > 85 ? "Perfect" : match > 75 ? "Great" : "Good"; const genderEmoji1 = senderGender === 1 ? "👦" : senderGender === 2 ? "👧" : "👤"; const genderEmoji2 = partner.gender === 1 ? "👦" : partner.gender === 2 ? "👧" : "👤"; const msg = `${emoji} 𝐏𝐀𝐈𝐑 𝐌𝐀𝐓𝐂𝐇 ${genderEmoji1} ${senderName} × ${genderEmoji2} ${partner.name} 📊 ${match}% ${compatibilityText} Match 💗 A beautiful connection`; return api.sendMessage( { body: msg, attachment: fs.createReadStream( filePath ) }, threadID, () => { if ( fs.existsSync( filePath ) ) { try { fs.unlinkSync( filePath ); } catch {} } }, messageID ); } catch (err) { console.log( "Pair5 Error:", err ); return api.sendMessage( "❌ | Pair system failed! Please try again.", threadID, messageID ); } } };