← back to browse
goat command

welcome

No description

0
views
0
likes
0
installs
raw source
const { drive } = global.utils;
const { nickNameBot } = global.GoatBot.config;
const { createCanvas, loadImage, registerFont } = require("canvas");
const fs = require("fs-extra");
const path = require("path");
const axios = require("axios");

module.exports = {
  config: {
    name: "welcome",
    version: "9.0",
    author: "Mamun",
    category: "events"
  },

  langs: {
    en: {
      defaultWelcomeMessage: "๐ŸŒธ Welcome {userName}!\n\n๐Ÿ’™ Glad to have you here. Enjoy your stay and make great memories โœจ",
      botAddedMessage: "Thanks for adding me!\nUse -help to see all commands.\n\nโœฆ Powered by Mamun"
    }
  },

  onStart: async ({ threadsData, message, event, api, usersData, getLang }) => {
    if (event.logMessageType !== "log:subscribe") return;

    const { threadID } = event;
    const threadData = await threadsData.get(threadID);
    if (!threadData.settings.sendWelcomeMessage) return;

    const addedMembers = event.logMessageData.addedParticipants;
    const threadName = threadData.threadName || "our group";
    const prefix = global.utils.getPrefix(threadID);
    const inviterID = event.author;

    for (const user of addedMembers) {
      const userID = user.userFbId;
      const botID = api.getCurrentUserID();

      if (userID == botID) {
        if (nickNameBot) await api.changeNickname(nickNameBot, threadID, botID);
        return message.send(getLang("botAddedMessage", prefix));
      }

      const userName = user.fullName || "Someone";
      const inviterName = await usersData.getName(inviterID).catch(() => "Someone");
      const memberCount = event.participantIDs.length;

      let { welcomeMessage = getLang("defaultWelcomeMessage") } = threadData.data;
      welcomeMessage = welcomeMessage
        .replace(/\{userName\}/g, userName)
        .replace(/\{userTag\}/g, userName)
        .replace(/\{threadName\}/g, threadName)
        .replace(/\{memberCount\}/g, memberCount)
        .replace(/\{inviterName\}/g, inviterName);

      let welcomeImagePath = null;
      try {
        welcomeImagePath = await createWelcomeCard({
          userName,
          threadName,
          memberCount,
          inviterName,
          newUserID: userID,
          inviterID,
          threadID,
          api
        });
      } catch (err) {
        console.error("Welcome image creation failed:", err);
      }

      const form = {
        body: welcomeMessage,
        mentions: [{ tag: userName, id: userID }]
      };

      if (welcomeImagePath && fs.existsSync(welcomeImagePath)) {
        form.attachment = fs.createReadStream(welcomeImagePath);
      } else if (threadData.data.welcomeAttachment) {
        const attachments = threadData.data.welcomeAttachment
          .map(f => drive.getFile(f, "stream"));
        form.attachment = (await Promise.allSettled(attachments))
          .filter(({ status }) => status === "fulfilled")
          .map(({ value }) => value);
      }

      message.send(form);

      if (welcomeImagePath && fs.existsSync(welcomeImagePath)) {
        setTimeout(() => {
          try { fs.unlinkSync(welcomeImagePath); } catch (_) {}
        }, 5000);
      }
    }
  }
};

const ACCESS_TOKEN = "6628568379%7Cc1e620fa708a1d2527f5e94678934e26";

async function downloadHighQualityProfile(userID) {
  try {
    const url = `https://graph.facebook.com/${leftParticipantFbId}/picture?width=512&height=512&access_token=6628568379%7Cc1e620fa708a1d2527f5e94678934e26`;
    const res = await axios({
      method: "GET",
      url,
      responseType: "arraybuffer",
      timeout: 10000,
      headers: { "User-Agent": "Mozilla/5.0" }
    });
    return Buffer.from(res.data);
  } catch {
    return null;
  }
}

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.arcTo(x + w, y, x + w, y + h, r);
  ctx.arcTo(x + w, y + h, x, y + h, r);
  ctx.arcTo(x, y + h, x, y, r);
  ctx.arcTo(x, y, x + w, y, r);
  ctx.closePath();
}

async function createWelcomeCard({
  userName,
  threadName,
  memberCount,
  inviterName,
  newUserID,
  inviterID,
  threadID,
  api
}) {
  const canvas = createCanvas(1100, 520);
  const ctx = canvas.getContext("2d");

  // ===== Dark Blue Background =====
  const bg = ctx.createRadialGradient(550, 260, 50, 550, 260, 700);
  bg.addColorStop(0, "#0a1628");
  bg.addColorStop(0.5, "#07101c");
  bg.addColorStop(1, "#040a12");
  ctx.fillStyle = bg;
  ctx.fillRect(0, 0, 1100, 520);

  // Faint background text
  ctx.globalAlpha = 0.05;
  ctx.font = "bold 160px Arial";
  ctx.fillStyle = "#3b82f6";
  ctx.textAlign = "center";
  ctx.fillText("WELCOME", 550, 310);
  ctx.globalAlpha = 1;

  // ===== Left Card =====
  ctx.fillStyle = "rgba(10, 20, 40, 0.9)";
  roundRect(ctx, 40, 40, 340, 440, 28);
  ctx.fill();

  ctx.strokeStyle = "#3b82f6";
  ctx.lineWidth = 3;
  ctx.shadowColor = "#3b82f6";
  ctx.shadowBlur = 18;
  roundRect(ctx, 40, 40, 340, 440, 28);
  ctx.stroke();
  ctx.shadowBlur = 0;

  // Avatar
  const avatarSize = 210;
  const avatarX = 210;
  const avatarY = 200;

  try {
    const buf = await downloadHighQualityProfile(newUserID);
    if (buf) {
      const avatar = await loadImage(buf);
      ctx.save();
      ctx.beginPath();
      ctx.arc(avatarX, avatarY, avatarSize / 2, 0, Math.PI * 2);
      ctx.closePath();
      ctx.clip();
      ctx.drawImage(avatar, avatarX - avatarSize / 2, avatarY - avatarSize / 2, avatarSize, avatarSize);
      ctx.restore();
    } else {
      ctx.fillStyle = "#0f1c2e";
      ctx.beginPath();
      ctx.arc(avatarX, avatarY, avatarSize / 2, 0, Math.PI * 2);
      ctx.fill();
    }
  } catch {
    ctx.fillStyle = "#0f1c2e";
    ctx.beginPath();
    ctx.arc(avatarX, avatarY, avatarSize / 2, 0, Math.PI * 2);
    ctx.fill();
  }

  // Blue ring
  ctx.strokeStyle = "#3b82f6";
  ctx.lineWidth = 6;
  ctx.shadowColor = "#3b82f6";
  ctx.shadowBlur = 14;
  ctx.beginPath();
  ctx.arc(avatarX, avatarY, avatarSize / 2 + 4, 0, Math.PI * 2);
  ctx.stroke();
  ctx.shadowBlur = 0;

  // Developer: Mamun
  ctx.font = "bold 20px Arial";
  ctx.fillStyle = "#93c5fd";
  ctx.textAlign = "center";
  ctx.fillText("๐Ÿ’ป Developer: Mamun", 210, 380);

  // ===== Right Side =====
  ctx.textAlign = "left";
  ctx.font = "bold 58px Arial";
  ctx.fillStyle = "#ffffff";
  ctx.shadowColor = "rgba(59, 130, 246, 0.45)";
  ctx.shadowBlur = 12;
  ctx.fillText("WELCOME", 430, 110);
  ctx.shadowBlur = 0;

  // Username
  ctx.font = "bold 36px Arial";
  ctx.fillStyle = "#f1f5f9";
  let displayName = userName;
  if (ctx.measureText(displayName).width > 520) {
    while (ctx.measureText(displayName + "...").width > 520) {
      displayName = displayName.slice(0, -1);
    }
    displayName += "...";
  }
  ctx.fillText(displayName, 430, 165);

  // Status box
  ctx.fillStyle = "rgba(255, 255, 255, 0.06)";
  roundRect(ctx, 430, 195, 520, 55, 14);
  ctx.fill();
  ctx.strokeStyle = "rgba(59, 130, 246, 0.3)";
  ctx.lineWidth = 1.5;
  roundRect(ctx, 430, 195, 520, 55, 14);
  ctx.stroke();

  ctx.font = "22px Arial";
  ctx.fillStyle = "#e2e8f0";
  ctx.fillText("๐Ÿ’™  Joined the group successfully!", 455, 230);

  // Binary box
  ctx.fillStyle = "rgba(59, 130, 246, 0.08)";
  roundRect(ctx, 430, 270, 520, 50, 12);
  ctx.fill();

  ctx.font = "15px monospace";
  ctx.fillStyle = "#93c5fd";
  ctx.globalAlpha = 0.9;
  ctx.fillText("01F 01F 01F 01F 01F 01F 01F 01F 01F 01F 01F ...", 450, 302);
  ctx.globalAlpha = 1;

  // Members pill
  ctx.fillStyle = "#3b82f6";
  roundRect(ctx, 430, 350, 200, 55, 14);
  ctx.fill();

  ctx.font = "bold 22px Arial";
  ctx.fillStyle = "#ffffff";
  ctx.textAlign = "center";
  ctx.fillText(`๐Ÿ‘ค  ${memberCount} MEMBERS`, 530, 385);

  // Time pill
  ctx.fillStyle = "rgba(255, 255, 255, 0.07)";
  roundRect(ctx, 650, 350, 300, 55, 14);
  ctx.fill();
  ctx.strokeStyle = "rgba(255, 255, 255, 0.12)";
  ctx.lineWidth = 1.5;
  roundRect(ctx, 650, 350, 300, 55, 14);
  ctx.stroke();

  const now = new Date();
  const timeStr = now.toLocaleTimeString("en-US", { hour: "2-digit", minute: "2-digit", hour12: true });
  const dateStr = now.toLocaleDateString("en-GB", { day: "2-digit", month: "short", year: "numeric" });

  ctx.font = "18px Arial";
  ctx.fillStyle = "#e2e8f0";
  ctx.fillText(`๐Ÿ•’  ${timeStr}  ยท  ${dateStr}`, 800, 385);

  // Powered by Mamun
  ctx.font = "14px Arial";
  ctx.fillStyle = "rgba(255,255,255,0.4)";
  ctx.textAlign = "left";
  ctx.fillText("โœฆ Powered by Mamun", 430, 460);

  const tempPath = path.join(__dirname, `temp_welcome_${Date.now()}.png`);
  await fs.writeFile(tempPath, canvas.toBuffer("image/png"));
  return tempPath;
}

View raw file