← back to browse
goat command

videocall

No description

0
views
0
likes
0
installs

Aliases: vcall

raw source
const fs = require("fs-extra");
const axios = require("axios");
const { loadImage, createCanvas } = require("canvas");

module.exports = {
 config: {
 name: "videocall",
 aliases: ["vcall"],
 version: "1.0.0",
 author: "EryXenX",
 countDown: 5,
 role: 0,
 description: {
 en: "Fake video call screen with you and target",
 bn: "তুমি আর target এর ফেক ভিডিও কল স্ক্রিন"
 },
 category: "fun",
 guide: { en: "{pn} @mention or reply to a message" }
 },

 langs: {
 en: { noMention: "❌ | Mention someone or reply to a message!", error: "❌ | Failed to generate. Try again." },
 bn: { noMention: "❌ | কাউকে mention করুন বা reply করুন!", error: "❌ | তৈরি করতে সমস্যা হয়েছে।" },
 hi: { noMention: "❌ | Kisi ko mention karein ya reply karein!", error: "❌ | Banana fail hua." },
 tl: { noMention: "❌ | Mag-mention ng isa o mag-reply!", error: "❌ | Hindi nagawa." },
 ar: { noMention: "❌ | أشر إلى شخص أو رد على رسالة!", error: "❌ | فشل الإنشاء." }
 },

 onStart: async function ({ event, message, getLang, usersData, args }) {
 try {
 const senderID = event.senderID;
 const targetID = Object.keys(event.mentions)[0]
 || (event.messageReply ? event.messageReply.senderID : null)
 || (args[0] && /^\d+$/.test(args[0]) ? args[0] : null);

 if (!targetID) return message.reply(getLang("noMention"));

 const targetName = await usersData.getName(targetID).catch(() => "Unknown");

 const ts = Date.now();
 const senderAvtPath = __dirname + "/cache/vc_sender_" + ts + ".jpg";
 const targetAvtPath = __dirname + "/cache/vc_target_" + ts + ".jpg";
 const outputPath = __dirname + "/cache/vc_out_" + ts + ".jpg";

 const [senderRes, targetRes] = await Promise.all([
 axios.get("https://graph.facebook.com/" + senderID + "/picture?height=720&width=720&access_token=6628568379%7Cc1e620fa708a1d5696fb991c1bde5662", { responseType: "arraybuffer" }),
 axios.get("https://graph.facebook.com/" + targetID + "/picture?height=720&width=720&access_token=6628568379%7Cc1e620fa708a1d5696fb991c1bde5662", { responseType: "arraybuffer" })
 ]);

 fs.writeFileSync(senderAvtPath, Buffer.from(senderRes.data));
 fs.writeFileSync(targetAvtPath, Buffer.from(targetRes.data));

 const senderImg = await loadImage(senderAvtPath);
 const targetImg = await loadImage(targetAvtPath);

 const W = 720;
 const H = 1280;
 const canvas = createCanvas(W, H);
 const ctx = canvas.getContext("2d");

 drawCoverBlurred(ctx, targetImg, 0, 0, W, H);

 const overlay = ctx.createLinearGradient(0, 0, 0, H);
 overlay.addColorStop(0, "rgba(0,0,0,0.55)");
 overlay.addColorStop(0.2, "rgba(0,0,0,0.05)");
 overlay.addColorStop(0.8, "rgba(0,0,0,0.05)");
 overlay.addColorStop(1, "rgba(0,0,0,0.6)");
 ctx.fillStyle = overlay;
 ctx.fillRect(0, 0, W, H);

 ctx.fillStyle = "#ffffff";
 ctx.font = "bold 36px Sans";
 ctx.textAlign = "center";
 ctx.fillText(targetName, W / 2, 90);

 ctx.fillStyle = "#d9dee3";
 ctx.font = "24px Sans";
 ctx.fillText("00:14", W / 2, 130);

 const pipW = 200;
 const pipH = 270;
 const pipX = W - pipW - 30;
 const pipY = 60;
 const radius = 18;

 ctx.save();
 roundRectPath(ctx, pipX, pipY, pipW, pipH, radius);
 ctx.clip();
 drawCoverImage(ctx, senderImg, pipX, pipY, pipW, pipH);
 ctx.restore();

 ctx.strokeStyle = "rgba(255,255,255,0.6)";
 ctx.lineWidth = 3;
 roundRectPath(ctx, pipX, pipY, pipW, pipH, radius);
 ctx.stroke();

 const btnY = H - 150;
 const spacing = 130;
 const centerX = W / 2;
 const positions = [centerX - spacing, centerX, centerX + spacing];

 ctx.fillStyle = "rgba(255,255,255,0.18)";
 ctx.beginPath();
 ctx.arc(positions[0], btnY, 55, 0, Math.PI * 2);
 ctx.fill();
 drawMicIcon(ctx, positions[0], btnY, "#ffffff");

 ctx.fillStyle = "#e53950";
 ctx.beginPath();
 ctx.arc(positions[1], btnY, 60, 0, Math.PI * 2);
 ctx.fill();
 ctx.save();
 ctx.translate(positions[1], btnY);
 ctx.rotate((135 * Math.PI) / 180);
 drawPhoneIcon(ctx, "#ffffff");
 ctx.restore();

 ctx.fillStyle = "rgba(255,255,255,0.18)";
 ctx.beginPath();
 ctx.arc(positions[2], btnY, 55, 0, Math.PI * 2);
 ctx.fill();
 drawCameraIcon(ctx, positions[2], btnY, "#ffffff");

 fs.writeFileSync(outputPath, canvas.toBuffer("image/jpeg", { quality: 0.92 }));

 await message.reply({ body: "📹 Video call with " + targetName, attachment: fs.createReadStream(outputPath) });

 [senderAvtPath, targetAvtPath, outputPath].forEach(p => { try { fs.unlinkSync(p); } catch (_) {} });

 } catch (err) {
 console.error("Videocall Error:", err);
 message.reply(getLang("error"));
 }
 }
};

function drawCoverImage(ctx, img, x, y, w, h) {
 const scale = Math.max(w / img.width, h / img.height);
 const dw = img.width * scale;
 const dh = img.height * scale;
 const dx = x + (w - dw) / 2;
 const dy = y + (h - dh) / 2;
 ctx.drawImage(img, dx, dy, dw, dh);
}

function drawCoverBlurred(ctx, img, x, y, w, h) {
 ctx.save();
 ctx.filter = "blur(18px)";
 drawCoverImage(ctx, img, x - 20, y - 20, w + 40, h + 40);
 ctx.restore();
}

function roundRectPath(ctx, x, y, w, h, r) {
 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();
}

function drawPhoneIcon(ctx, color) {
 ctx.fillStyle = color;
 ctx.beginPath();
 ctx.moveTo(-18, -22);
 ctx.lineTo(-6, -22);
 ctx.lineTo(-2, -10);
 ctx.lineTo(-9, -3);
 ctx.bezierCurveTo(-4, 8, 4, 16, 15, 21);
 ctx.lineTo(22, 14);
 ctx.lineTo(34, 18);
 ctx.lineTo(34, 30);
 ctx.bezierCurveTo(34, 33, 31, 35, 28, 35);
 ctx.bezierCurveTo(0, 35, -35, 0, -35, -28);
 ctx.bezierCurveTo(-35, -31, -33, -34, -30, -34);
 ctx.lineTo(-18, -22);
 ctx.closePath();
 ctx.fill();
}

function drawMicIcon(ctx, cx, cy, color) {
 ctx.save();
 ctx.translate(cx, cy);
 ctx.fillStyle = color;
 ctx.beginPath();
 ctx.moveTo(-10, -22);
 ctx.lineTo(10, -22);
 ctx.arcTo(20, -12, 10, 0, 10);
 ctx.lineTo(-10, 0);
 ctx.arcTo(-20, -12, -10, -22, 10);
 ctx.closePath();
 ctx.fill();
 ctx.strokeStyle = color;
 ctx.lineWidth = 4;
 ctx.beginPath();
 ctx.arc(0, 0, 22, 0.2 * Math.PI, 0.8 * Math.PI);
 ctx.stroke();
 ctx.beginPath();
 ctx.moveTo(0, 22);
 ctx.lineTo(0, 32);
 ctx.moveTo(-12, 32);
 ctx.lineTo(12, 32);
 ctx.stroke();
 ctx.restore();
}

function drawCameraIcon(ctx, cx, cy, color) {
 ctx.save();
 ctx.translate(cx, cy);
 ctx.fillStyle = color;
 ctx.beginPath();
 ctx.roundRect ? ctx.roundRect(-22, -16, 32, 32, 6) : ctx.rect(-22, -16, 32, 32);
 ctx.fill();
 ctx.beginPath();
 ctx.moveTo(10, -8);
 ctx.lineTo(24, -16);
 ctx.lineTo(24, 16);
 ctx.lineTo(10, 8);
 ctx.closePath();
 ctx.fill();
 ctx.restore();
}

View raw file