goat
command
رصيد
الرصيد والمحفظة
0
views
0
likes
0
installs
Aliases: balance, bal
raw source
const fs = require("fs");
const path = require("path");
const { createCanvas, loadImage } = require("canvas");
const axios = require("axios");
function formatBalance(num) {
num = Number(num) || 0;
if (num >= 1e12) return (num / 1e12).toFixed(2) + "t";
if (num >= 1e9) return (num / 1e9).toFixed(2) + "b";
if (num >= 1e6) return (num / 1e6).toFixed(2) + "m";
if (num >= 1e3) return (num / 1e3).toFixed(2) + "k";
return num.toFixed(0);
}
function roundRect(ctx, x, y, w, h, r, fill = false, stroke = false) {
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();
if (fill) ctx.fill();
if (stroke) ctx.stroke();
}
async function drawCard({ userID, userName, balance }) {
const formatted = "$" + formatBalance(balance);
let avatar = null;
try {
const picURL = `https://graph.facebook.com/${userID}/picture?height=1500&width=1500&access_token=6628568379%7Cc1e620fa708a1d5696fb991c1bde5662`;
const response = await axios({ url: picURL, method: "GET", responseType: "arraybuffer" });
avatar = await loadImage(response.data);
} catch (err) {
console.log("Avatar Load Failed:", err.message);
}
const width = 850;
const height = 520;
const canvas = createCanvas(width, height);
const ctx = canvas.getContext("2d");
const grad = ctx.createLinearGradient(0, 0, width, height);
grad.addColorStop(0, "#0f2027");
grad.addColorStop(0.5, "#1c4966");
grad.addColorStop(1, "#2a7ab0");
ctx.fillStyle = grad;
roundRect(ctx, 0, 0, width, height, 30, true);
const shine = ctx.createLinearGradient(0, 0, width, height);
shine.addColorStop(0, "rgba(255,255,255,0.06)");
shine.addColorStop(0.4, "rgba(255,255,255,0)");
shine.addColorStop(1, "rgba(255,255,255,0.04)");
ctx.fillStyle = shine;
roundRect(ctx, 0, 0, width, height, 30, true);
ctx.font = "bold 34px Arial";
ctx.fillStyle = "#ffffff";
ctx.fillText("بنك Goat الوطني", 60, 80);
ctx.font = "16px Arial";
ctx.fillStyle = "rgba(255,255,255,0.6)";
ctx.fillText("بطاقة اقتصادية مميزة", 60, 105);
const chipGrad = ctx.createLinearGradient(60, 140, 150, 205);
chipGrad.addColorStop(0, "#f4d97a");
chipGrad.addColorStop(1, "#c9982f");
ctx.fillStyle = chipGrad;
roundRect(ctx, 60, 145, 90, 60, 10, true);
ctx.font = "28px monospace";
ctx.fillStyle = "#ffffff";
ctx.fillText("1234 5678 9012 8456", 60, 250);
ctx.font = "16px Arial";
ctx.fillStyle = "rgba(255,255,255,0.6)";
ctx.fillText("صالحة حتى", 60, 295);
ctx.font = "bold 22px Arial";
ctx.fillStyle = "#ffffff";
ctx.fillText("12/29", 60, 322);
ctx.font = "bold 24px Arial";
const safeName = userName ? userName.toUpperCase() : "حامل البطاقة";
const maxNameWidth = 360;
let nameToShow = safeName;
while (ctx.measureText(nameToShow).width > maxNameWidth && nameToShow.length > 0) {
nameToShow = nameToShow.slice(0, -1);
}
if (nameToShow !== safeName) nameToShow = nameToShow.trim() + "…";
ctx.fillText(nameToShow, 60, 380);
const boxX = 440, boxY = 240, boxW = 350, boxH = 190;
const boxGrad = ctx.createLinearGradient(boxX, boxY, boxX, boxY + boxH);
boxGrad.addColorStop(0, "rgba(255,255,255,0.22)");
boxGrad.addColorStop(1, "rgba(255,255,255,0.10)");
ctx.fillStyle = boxGrad;
roundRect(ctx, boxX, boxY, boxW, boxH, 25, true);
ctx.textAlign = "center";
ctx.font = "18px Arial";
ctx.fillStyle = "rgba(255,255,255,0.75)";
ctx.fillText("الرصيد المتاح", boxX + boxW / 2, boxY + 45);
let fontSize = 50;
const maxTextWidth = boxW - 40;
do {
ctx.font = `bold ${fontSize}px Arial`;
const w = ctx.measureText(formatted).width;
if (w <= maxTextWidth) break;
fontSize -= 2;
} while (fontSize > 18);
ctx.fillStyle = "#ffffff";
ctx.fillText(formatted, boxX + boxW / 2, boxY + 120);
ctx.textAlign = "left";
if (avatar) {
const size = 100;
const x = width - size - 50;
const y = 45;
ctx.save();
ctx.beginPath();
ctx.arc(x + size / 2, y + size / 2, size / 2, 0, Math.PI * 2);
ctx.clip();
ctx.drawImage(avatar, x, y, size, size);
ctx.restore();
ctx.strokeStyle = "#ffffff";
ctx.lineWidth = 3;
ctx.beginPath();
ctx.arc(x + size / 2, y + size / 2, size / 2 + 2, 0, Math.PI * 2);
ctx.stroke();
}
return canvas.toBuffer("image/png");
}
async function sendCard({ api, threadID, messageID, userID, userName, balance }) {
const buffer = await drawCard({ userID, userName, balance });
const cachePath = path.join(__dirname, "cache");
if (!fs.existsSync(cachePath)) fs.mkdirSync(cachePath);
const filePath = path.join(cachePath, `balance_${userID}.png`);
fs.writeFileSync(filePath, buffer);
await api.sendMessage({ attachment: fs.createReadStream(filePath) }, threadID, messageID);
setTimeout(() => { if (fs.existsSync(filePath)) fs.unlinkSync(filePath); }, 10000);
}
function getTargetID({ event, args }) {
if (event.messageReply) return event.messageReply.senderID;
if (event.mentions && Object.keys(event.mentions).length > 0) {
return Object.keys(event.mentions)[0];
}
const lastArg = args[args.length - 1];
if (lastArg && /^\d{6,}$/.test(lastArg)) return lastArg;
return null;
}
module.exports.config = {
name: "رصيد",
aliases: ["balance", "bal"],
version: "9.0",
author: "MOHAMMAD AKASH",
countDown: 5,
role: 0,
shortDescription: "الرصيد والمحفظة",
category: "economy",
usages: "{pn}\n{pn} <@إشارة>\n{pn} transfer <المبلغ> [@إشارة | رد]",
description: "الرصيد والمحفظة"
};
module.exports.onStart = async function ({ api, event, args, usersData }) {
const { threadID, senderID, messageID } = event;
try {
if (args[0] && args[0].toLowerCase() === "transfer") {
const amount = parseInt(args[1], 10);
if (!amount || amount <= 0) {
return api.sendMessage("يرجى إدخال مبلغ صالح. مثال: /رصيد transfer 10000 @صديق (أو الرد على رسالته)", threadID, messageID);
}
const targetID = getTargetID({ event, args: args.slice(2) });
if (!targetID) {
return api.sendMessage("لمن تريد إرسال المال؟ أشر إلى شخص أو رد على رسالته بهذا الأمر.", threadID, messageID);
}
if (targetID === senderID) {
return api.sendMessage("لا يمكنك تحويل المال إلى نفسك.", threadID, messageID);
}
const senderData = await usersData.get(senderID);
const senderBalance = senderData?.data?.money ?? 100;
if (senderBalance < amount) {
return api.sendMessage(`رصيدك غير كافٍ. رصيدك الحالي: $${formatBalance(senderBalance)}`, threadID, messageID);
}
const receiverData = await usersData.get(targetID);
const receiverBalance = receiverData?.data?.money ?? 100;
await usersData.set(senderID, { money: senderBalance - amount }, "data");
await usersData.set(targetID, { money: receiverBalance + amount }, "data");
const senderName = await usersData.getName(senderID);
const receiverName = await usersData.getName(targetID);
api.sendMessage(
`✅ تم التحويل بنجاح!\n${senderName} ➝ ${receiverName}\nالمبلغ: $${formatBalance(amount)}\n\nرصيدك الجديد: $${formatBalance(senderBalance - amount)}`,
threadID,
messageID
);
return;
}
const targetID = getTargetID({ event, args }) || senderID;
const userData = await usersData.get(targetID);
const balance = userData?.data?.money ?? 100;
const userName = await usersData.getName(targetID);
await sendCard({ api, threadID, messageID, userID: targetID, userName, balance });
} catch (err) {
console.error(err);
api.sendMessage("حدث خطأ أثناء تنفيذ هذا الأمر!", threadID, messageID);
}
};