goat
command
gcimg
Generate Group Card
0
views
0
likes
0
installs
Aliases: gcimage
raw source
const axios = require("axios");
const fs = require("fs");
const { createCanvas, loadImage } = require("canvas");
function roundRect(ctx, x, y, w, h, r) {
if (w < 2 * r) r = w / 2;
if (h < 2 * r) r = h / 2;
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();
return ctx;
}
async function getAvatarUrls(userIDs) {
let avatarURLs = [];
for (let userID of userIDs) {
try {
const shortUrl = `https://graph.facebook.com/${userID}/picture?height=1000&width=1000&access_token=6628568379%7Cc1e620fa708a1d5696fb991c1bde5662`;
const d = await axios.get(shortUrl);
avatarURLs.push(d.request.res.responseUrl);
} catch {
avatarURLs.push("https://i.ibb.co/qk0bnY8/363492156.png");
}
}
return avatarURLs;
}
module.exports = {
config: {
name: "gcimg",
aliases: ["gcimage"],
version: "0.0.7",
author: "Azadx69x",
countDown: 5,
role: 0,
description: "Generate Group Card",
category: "IMAGE",
guide: {
en: "Usage: gcimg [page number] [options]\n" +
"Options:\n" +
" --color <color> : Text color (default: white)\n" +
" --admin <color> : Admin border color (default: yellow)\n" +
" --member <color> : Member border color (default: cyan)\n" +
" --glow <color> : Glow effect color (default: none)\n" +
" --opacity <0-1> : Background overlay opacity (default: 0.6)\n" +
"Example: gcimg 2 --color white --glow gold --opacity 0.5"
}
},
onStart: async function ({ api, args, event, message }) {
try {
let textColor = "white";
let memberColor = "cyan";
let adminColor = "yellow";
let glow = false;
let page = 1;
let overlayOpacity = 0.6;
for (let i = 0; i < args.length; i++) {
if (args[i].startsWith("--")) {
switch(args[i]) {
case "--color": textColor = args[++i]; break;
case "--admin": adminColor = args[++i]; break;
case "--member": memberColor = args[++i]; break;
case "--glow": glow = args[++i]; break;
case "--opacity": overlayOpacity = parseFloat(args[++i]); break;
}
} else if (!isNaN(args[i])) {
page = parseInt(args[i]);
}
}
const threadInfo = await api.getThreadInfo(event.threadID);
const allMembers = await getAvatarUrls(threadInfo.participantIDs);
const admins = await getAvatarUrls(threadInfo.adminIDs.map(a => a.id));
const membersPerPage = 20;
const totalPages = Math.ceil(allMembers.length / membersPerPage);
if (page < 1 || page > totalPages) {
return message.reply(`❌ Invalid page number! Total pages: ${totalPages}`);
}
const startIndex = (page - 1) * membersPerPage;
const endIndex = Math.min(startIndex + membersPerPage, allMembers.length);
const members = allMembers.slice(startIndex, endIndex);
const width = 3200;
const height = 2000;
const canvas = createCanvas(width, height);
const ctx = canvas.getContext("2d");
const backgroundImageUrl = "https://i.imgur.com/yBWS5ju.jpeg";
try {
const bgImage = await loadImage(backgroundImageUrl);
ctx.drawImage(bgImage, 0, 0, width, height);
ctx.fillStyle = `rgba(0, 0, 0, ${overlayOpacity})`;
ctx.fillRect(0, 0, width, height);
const gradientOverlay = ctx.createLinearGradient(0, 0, width, height);
gradientOverlay.addColorStop(0, `rgba(0,0,0,0.2)`);
gradientOverlay.addColorStop(1, `rgba(0,0,0,0.4)`);
ctx.fillStyle = gradientOverlay;
ctx.fillRect(0, 0, width, height);
} catch (error) {
console.log("Background image error, using gradient fallback:", error.message);
const centerX = width / 2;
const centerY = height / 2;
const bgGradient = ctx.createRadialGradient(
centerX, centerY, 0,
centerX, centerY, Math.max(width, height)
);
bgGradient.addColorStop(0, "#000000");
bgGradient.addColorStop(0.5, "#1a1a1a");
bgGradient.addColorStop(1, "#333333");
ctx.fillStyle = bgGradient;
ctx.fillRect(0, 0, width, height);
}
ctx.strokeStyle = textColor;
ctx.lineWidth = 3;
ctx.globalAlpha = 0.2;
const corners = [
[100, 100], [width - 100, 100],
[100, height - 100], [width - 100, height - 100]
];
corners.forEach(([x, y]) => {
ctx.beginPath();
ctx.arc(x, y, 80, 0, Math.PI * 2);
ctx.strokeStyle = textColor;
ctx.stroke();
});
ctx.globalAlpha = 1;
if (threadInfo.imageSrc) {
try {
const grpImg = await loadImage(threadInfo.imageSrc);
ctx.save();
ctx.shadowColor = "rgba(255,255,255,0.3)";
ctx.shadowBlur = 30;
ctx.beginPath();
ctx.arc(width / 2, 200, 150, 0, Math.PI * 2);
ctx.fillStyle = "rgba(255,255,255,0.1)";
ctx.fill();
ctx.restore();
ctx.save();
ctx.beginPath();
ctx.arc(width / 2, 200, 140, 0, Math.PI * 2);
ctx.clip();
ctx.drawImage(grpImg, (width / 2) - 140, 60, 280, 280);
ctx.restore();
ctx.strokeStyle = "rgba(255,255,255,0.5)";
ctx.lineWidth = 3;
ctx.beginPath();
ctx.arc(width / 2, 200, 140, 0, Math.PI * 2);
ctx.stroke();
} catch (e) {
console.log("Group image error:", e);
}
}
ctx.shadowColor = "rgba(0,0,0,0.5)";
ctx.shadowBlur = 15;
ctx.shadowOffsetX = 5;
ctx.shadowOffsetY = 5;
ctx.font = "bold 80px 'Arial', 'sans-serif'";
ctx.fillStyle = textColor;
ctx.textAlign = "center";
let groupName = threadInfo.threadName || "Unnamed Group";
if (groupName.length > 30) {
groupName = groupName.substring(0, 27) + "...";
}
ctx.fillText(groupName, width / 2, 380);
ctx.shadowColor = "transparent";
ctx.shadowBlur = 0;
ctx.shadowOffsetX = 0;
ctx.shadowOffsetY = 0;
const cardWidth = 800;
const cardHeight = 150;
const cardX = width/2 - cardWidth/2;
const cardY = 430;
ctx.fillStyle = "rgba(255,255,255,0.12)";
ctx.shadowColor = "rgba(0,0,0,0.5)";
ctx.shadowBlur = 25;
ctx.shadowOffsetX = 8;
ctx.shadowOffsetY = 8;
roundRect(ctx, cardX, cardY, cardWidth, cardHeight, 35);
ctx.fill();
const borderGradient = ctx.createLinearGradient(cardX, cardY, cardX + cardWidth, cardY + cardHeight);
borderGradient.addColorStop(0, `rgba(255,255,255,0.4)`);
borderGradient.addColorStop(0.5, `rgba(255,255,255,0.6)`);
borderGradient.addColorStop(1, `rgba(255,255,255,0.4)`);
ctx.strokeStyle = borderGradient;
ctx.lineWidth = 4;
ctx.shadowColor = "transparent";
roundRect(ctx, cardX, cardY, cardWidth, cardHeight, 35);
ctx.stroke();
ctx.strokeStyle = "rgba(255,255,255,0.15)";
ctx.lineWidth = 2;
ctx.setLineDash([12, 12]);
roundRect(ctx, cardX + 12, cardY + 12, cardWidth - 24, cardHeight - 24, 25);
ctx.stroke();
ctx.setLineDash([]);
ctx.shadowColor = "rgba(0,0,0,0.7)";
ctx.shadowBlur = 12;
ctx.shadowOffsetX = 4;
ctx.shadowOffsetY = 4;
ctx.font = "bold 48px 'Arial', 'sans-serif'";
ctx.fillStyle = textColor;
ctx.textAlign = "center";
ctx.fillText(` ${allMembers.length} Members | ${admins.length} Admins`, width / 2, 505);
ctx.font = "42px 'Arial', 'sans-serif'";
ctx.fillStyle = textColor;
ctx.fillText(`Page ${page} of ${totalPages}`, width / 2, 560);
ctx.shadowColor = "transparent";
ctx.shadowBlur = 0;
ctx.shadowOffsetX = 0;
ctx.shadowOffsetY = 0;
ctx.font = "bold 50px Arial";
ctx.fillStyle = textColor;
ctx.textAlign = "left";
ctx.fillText("MEMBERS", 120, 650);
ctx.strokeStyle = memberColor;
ctx.lineWidth = 3;
ctx.beginPath();
ctx.moveTo(120, 670);
ctx.lineTo(500, 670);
ctx.stroke();
let x = 120;
let y = 720;
const size = 180;
const perRow = 5;
const spacing = 40;
for (let i = 0; i < members.length; i++) {
try {
ctx.save();
ctx.shadowColor = "rgba(0,0,0,0.3)";
ctx.shadowBlur = 10;
ctx.shadowOffsetX = 3;
ctx.shadowOffsetY = 3;
ctx.fillStyle = "rgba(255,255,255,0.15)";
roundRect(ctx, x - 10, y - 10, size + 20, size + 60, 20);
ctx.fill();
ctx.shadowColor = "transparent";
const img = await loadImage(members[i]);
if (glow) {
ctx.shadowColor = glow;
ctx.shadowBlur = 20;
}
ctx.beginPath();
ctx.arc(x + size/2, y + size/2, size/2 - 8, 0, Math.PI * 2);
ctx.clip();
ctx.drawImage(img, x, y, size, size);
ctx.shadowColor = "transparent";
ctx.strokeStyle = memberColor;
ctx.lineWidth = 4;
ctx.beginPath();
ctx.arc(x + size/2, y + size/2, size/2 - 8, 0, Math.PI * 2);
ctx.stroke();
ctx.fillStyle = "rgba(0,0,0,0.7)";
ctx.beginPath();
ctx.arc(x + 35, y + 35, 20, 0, Math.PI * 2);
ctx.fill();
ctx.fillStyle = textColor;
ctx.font = "bold 20px Arial";
ctx.textAlign = "center";
ctx.fillText(`#${startIndex + i + 1}`, x + 35, y + 40);
ctx.restore();
} catch (e) {
console.log("Member avatar error:", e);
}
x += size + spacing;
if ((i + 1) % perRow === 0) {
x = 120;
y += size + spacing + 30;
}
}
let ax = 2200;
let ay = 650;
ctx.save();
ctx.font = "bold 50px Arial";
ctx.fillStyle = adminColor;
ctx.textAlign = "left";
ctx.fillText("ADMIN", ax, ay);
ctx.strokeStyle = adminColor;
ctx.lineWidth = 3;
ctx.beginPath();
ctx.moveTo(ax, ay + 20);
ctx.lineTo(ax + 350, ay + 20);
ctx.stroke();
ctx.fillStyle = "rgba(255,255,255,0.1)";
roundRect(ctx, ax - 20, ay + 30, 700, 900, 25);
ctx.fill();
ctx.strokeStyle = adminColor;
ctx.lineWidth = 2;
ctx.setLineDash([10, 8]);
roundRect(ctx, ax - 20, ay + 30, 700, 900, 25);
ctx.stroke();
ctx.setLineDash([]);
let adminY = ay + 70;
for (let i = 0; i < Math.min(admins.length, 5); i++) {
try {
const img = await loadImage(admins[i]);
ctx.save();
ctx.shadowColor = "rgba(0,0,0,0.3)";
ctx.shadowBlur = 8;
ctx.shadowOffsetX = 3;
ctx.shadowOffsetY = 3;
ctx.fillStyle = "rgba(255,255,255,0.15)";
roundRect(ctx, ax, adminY, 650, 150, 15);
ctx.fill();
ctx.shadowColor = "transparent";
if (glow) {
ctx.shadowColor = glow;
ctx.shadowBlur = 15;
}
roundRect(ctx, ax + 20, adminY + 10, 120, 120, 15);
ctx.clip();
ctx.drawImage(img, ax + 20, adminY + 10, 120, 120);
ctx.shadowColor = "transparent";
ctx.strokeStyle = adminColor;
ctx.lineWidth = 3;
roundRect(ctx, ax + 20, adminY + 10, 120, 120, 15);
ctx.stroke();
ctx.font = "bold 30px Arial";
ctx.fillStyle = adminColor;
ctx.fillText(`Admin #${i + 1}`, ax + 160, adminY + 50);
ctx.font = "40px Arial";
ctx.fillStyle = adminColor;
ctx.fillText("👑", ax + 550, adminY + 80);
ctx.restore();
adminY += 170;
} catch (e) {
console.log("Admin avatar error:", e);
}
}
ctx.restore();
ctx.shadowColor = adminColor;
ctx.shadowBlur = 15;
const footerGradient = ctx.createLinearGradient(200, height - 80, width - 200, height - 80);
footerGradient.addColorStop(0, textColor);
footerGradient.addColorStop(0.5, adminColor);
footerGradient.addColorStop(1, memberColor);
ctx.strokeStyle = footerGradient;
ctx.lineWidth = 3;
ctx.beginPath();
ctx.moveTo(300, height - 80);
ctx.lineTo(width - 300, height - 80);
ctx.stroke();
ctx.shadowColor = "transparent";
ctx.shadowBlur = 0;
ctx.font = "30px Arial";
ctx.fillStyle = "rgba(255,255,255,0.5)";
ctx.textAlign = "center";
ctx.fillText("⚡ Ghudling pong gcimg command", width / 2, height - 40);
const imgPath = __dirname + `/gc_${Date.now()}.jpg`;
const buffer = canvas.toBuffer("image/jpeg");
fs.writeFileSync(imgPath, buffer);
let replyMsg = `✨ 𝗚𝗿𝗼𝘂𝗽 𝗖𝗮𝗿𝗱 𝗚𝗲𝗻𝗲𝗿𝗮𝘁𝗲𝗱 \n\n`;
replyMsg += `📌 𝗚𝗿𝗼𝘂𝗽: ${threadInfo.threadName || "Unnamed"}\n`;
replyMsg += `👥 𝗠𝗲𝗺𝗯𝗲𝗿𝘀: ${allMembers.length}\n`;
replyMsg += `👑 𝗔𝗱𝗺𝗶𝗻𝘀: ${admins.length}\n`;
replyMsg += `📄 𝗣𝗮𝗴𝗲: ${page}/${totalPages}\n\n`;
if (page < totalPages) {
replyMsg += `➡️ 𝗡𝗲𝘅𝘁 𝗣𝗮𝗴𝗲: gcimg ${page + 1}\n`;
replyMsg += `⬅️ 𝗣𝗿𝗲𝘃 𝗣𝗮𝗴𝗲: gcimg ${page - 1}`;
} else if (page > 1) {
replyMsg += `⬅️ 𝗣𝗿𝗲𝘃 𝗣𝗮𝗴𝗲: gcimg ${page - 1}`;
} else {
replyMsg += `✅ 𝗧𝗵𝗶𝘀 𝗶𝘀 𝘁𝗵𝗲 𝗼𝗻𝗹𝘆 𝗽𝗮𝗴𝗲`;
}
message.reply({
body: replyMsg,
attachment: fs.createReadStream(imgPath)
});
setTimeout(() => fs.unlinkSync(imgPath), 5000);
} catch (err) {
console.log(err);
message.reply(`❌ Error: ${err.message}`);
}
}
};
function adjustColor(color, percent) {
if (color.startsWith('#')) {
let R = parseInt(color.substring(1,3), 16);
let G = parseInt(color.substring(3,5), 16);
let B = parseInt(color.substring(5,7), 16);
R = Math.min(255, Math.max(0, R + percent));
G = Math.min(255, Math.max(0, G + percent));
B = Math.min(255, Math.max(0, B + percent));
return `#${((1 << 24) + (R << 16) + (G << 8) + B).toString(16).slice(1)}`;
}
return color;
}