← back to browse
goat command

welcome

Group Cover BG & Dynamic Dual Avatar Welcome Card

0
views
0
likes
0
installs
raw source
const { createCanvas, loadImage } = require("canvas");
const fs = require("fs-extra");
const path = require("path");
const moment = require("moment-timezone");

module.exports = {
  config: {
    name: "welcome",
    version: "7.0.0",
    author: "Protik Shah",
    category: "events",
    description: "Group Cover BG & Dynamic Dual Avatar Welcome Card"
  },

  onStart: async function ({ api, event }) {
    if (event.logMessageType !== "log:subscribe") return;

    const { threadID, logMessageData, author } = event;
    const addedParticipants = logMessageData.addedParticipants;

    try {
      const threadInfo = await api.getThreadInfo(threadID);
      const threadName = threadInfo.threadName || "Diablo Realm";
      const memberCount = threadInfo.participantIDs.length;
      const groupIconUrl = threadInfo.imageSrc || "https://i.ibb.co/L5k6NvZ/bg2.jpg";

      for (const user of addedParticipants) {
        const userID = user.userFbId;
        const userName = user.fullName;
        const adderID = author;
        const isSelfJoin = !adderID || adderID === userID;
        const timeNow = moment().tz("Asia/Dhaka").format("hh:mm A | DD MMM YYYY");

        const canvas = createCanvas(1000, 500);
        const ctx = canvas.getContext("2d");

        // 1. Group Cover Background with Blur
        try {
          const bgImg = await loadImage(groupIconUrl);
          ctx.filter = "blur(12px)";
          ctx.drawImage(bgImg, -20, -20, canvas.width + 40, canvas.height + 40);
          ctx.filter = "none";
        } catch (e) {
          ctx.fillStyle = "#050b14";
          ctx.fillRect(0, 0, canvas.width, canvas.height);
        }

        // Dark Overlay for readability
        ctx.fillStyle = "rgba(5, 11, 20, 0.85)";
        ctx.fillRect(0, 0, canvas.width, canvas.height);

        // Vertical Line
        ctx.strokeStyle = "rgba(0, 242, 254, 0.25)";
        ctx.lineWidth = 2;
        ctx.beginPath();
        ctx.moveTo(420, 0);
        ctx.lineTo(420, 500);
        ctx.stroke();

        // 2. Avatar Rendering
        const targetAvatarUrl = `https://graph.facebook.com/${userID}/picture?height=500&width=500&access_token=6628568379%7Cc1e620fa708a1d5696fb991c1bde5662`;

        if (isSelfJoin) {
          // Single Avatar Centered on Left Panel
          try {
            const targetImg = await loadImage(targetAvatarUrl);
            ctx.save();
            ctx.shadowColor = "#00f2fe";
            ctx.shadowBlur = 25;
            ctx.beginPath();
            ctx.arc(210, 200, 85, 0, Math.PI * 2);
            ctx.clip();
            ctx.drawImage(targetImg, 125, 115, 170, 170);
            ctx.restore();

            ctx.strokeStyle = "#00f2fe";
            ctx.lineWidth = 4;
            ctx.beginPath();
            ctx.arc(210, 200, 85, 0, Math.PI * 2);
            ctx.stroke();
          } catch (e) {}
        } else {
          // Dual Avatar (Adder + Added Member)
          const adderAvatarUrl = `https://graph.facebook.com/${adderID}/picture?height=500&width=500&access_token=6628568379%7Cc1e620fa708a1d5696fb991c1bde5662`;

          try {
            const adderImg = await loadImage(adderAvatarUrl);
            ctx.save();
            ctx.beginPath();
            ctx.arc(150, 200, 60, 0, Math.PI * 2);
            ctx.clip();
            ctx.drawImage(adderImg, 90, 140, 120, 120);
            ctx.restore();

            ctx.strokeStyle = "#ffffff";
            ctx.lineWidth = 3;
            ctx.beginPath();
            ctx.arc(150, 200, 60, 0, Math.PI * 2);
            ctx.stroke();
          } catch (e) {}

          try {
            const targetImg = await loadImage(targetAvatarUrl);
            ctx.save();
            ctx.shadowColor = "#00f2fe";
            ctx.shadowBlur = 20;
            ctx.beginPath();
            ctx.arc(260, 200, 70, 0, Math.PI * 2);
            ctx.clip();
            ctx.drawImage(targetImg, 190, 130, 140, 140);
            ctx.restore();

            ctx.strokeStyle = "#00f2fe";
            ctx.lineWidth = 4;
            ctx.beginPath();
            ctx.arc(260, 200, 70, 0, Math.PI * 2);
            ctx.stroke();
          } catch (e) {}
        }

        // Sub Text
        ctx.fillStyle = "#00f2fe";
        ctx.font = "bold 18px 'Segoe UI', Sans-serif";
        ctx.textAlign = "center";
        ctx.fillText("⚡ NEW MEMBER ADDED ⚡", 210, 350);

        // 3. Right Panel Content
        ctx.textAlign = "left";

        ctx.fillStyle = "#ffffff";
        ctx.font = "900 38px 'Segoe UI', Sans-serif";
        ctx.fillText("WELCOME ABOARD!", 460, 110);

        ctx.fillStyle = "#00f2fe";
        ctx.font = "bold 28px 'Segoe UI', Sans-serif";
        ctx.fillText(userName, 460, 160);

        // Strip 1: Message
        ctx.fillStyle = "rgba(0, 242, 254, 0.15)";
        ctx.beginPath();
        ctx.roundRect(460, 195, 480, 50, 12);
        ctx.fill();

        ctx.fillStyle = "#ffffff";
        ctx.font = "18px 'Segoe UI', Sans-serif";
        ctx.fillText("Welcome to our server, hope you enjoy!", 480, 227);

        // Strip 2: Group Name
        ctx.fillStyle = "rgba(0, 242, 254, 0.15)";
        ctx.beginPath();
        ctx.roundRect(460, 265, 480, 50, 12);
        ctx.fill();

        ctx.fillStyle = "#00f2fe";
        ctx.font = "bold 18px 'Segoe UI', Sans-serif";
        ctx.fillText(`GROUP: ${threadName}`, 480, 297);

        // Badges
        ctx.fillStyle = "#00f2fe";
        ctx.beginPath();
        ctx.roundRect(460, 355, 210, 48, 12);
        ctx.fill();

        ctx.fillStyle = "#000000";
        ctx.font = "bold 18px 'Segoe UI', Sans-serif";
        ctx.fillText(`MEMBER #${memberCount}`, 485, 385);

        ctx.fillStyle = "#121b2d";
        ctx.beginPath();
        ctx.roundRect(690, 355, 250, 48, 12);
        ctx.fill();

        ctx.fillStyle = "#a0aec0";
        ctx.font = "15px 'Segoe UI', Sans-serif";
        ctx.fillText(timeNow, 705, 384);

        const cardPath = path.join(__dirname, `cache_welcome_${userID}.png`);
        fs.writeFileSync(cardPath, canvas.toBuffer("image/png"));

        api.sendMessage(
          {
            body: `✨ Welcome ${userName} to ${threadName}!`,
            attachment: fs.createReadStream(cardPath)
          },
          threadID,
          () => {
            if (fs.existsSync(cardPath)) fs.unlinkSync(cardPath);
          }
        );
      }
    } catch (err) {
      console.error("Welcome Error:", err);
    }
  }
};

View raw file