goat
command
gdrive
Advanced Gmail Google Drive Control Panel
0
views
0
likes
0
installs
Aliases: gd, drive
raw source
const axios = require("axios");
const { google } = require("googleapis");
const fs = require("fs-extra");
const path = require("path");
const CREDENTIALS_PATH = path.join(process.cwd(), "credentials.json");
const DRIVE_SCOPES = ["https://www.googleapis.com/auth/drive"];
let drive = null;
// প্রথমে চেষ্টা করা হচ্ছে GOOGLE_CREDENTIALS environment variable থেকে পড়তে
// (Railway/Render-এর মতো হোস্টিং-এ যেখানে credentials.json ফাইল হিসেবে রাখা যায় না)
let credentialsJSON = null;
if (process.env.GOOGLE_CREDENTIALS) {
try {
credentialsJSON = JSON.parse(process.env.GOOGLE_CREDENTIALS);
} catch (e) {
console.log("❌ GOOGLE_CREDENTIALS environment variable ভ্যালিড JSON না:", e.message);
}
} else if (fs.existsSync(CREDENTIALS_PATH)) {
// environment variable না থাকলে লোকাল credentials.json ফাইল থেকে পড়া হচ্ছে
credentialsJSON = fs.readJsonSync(CREDENTIALS_PATH);
}
if (credentialsJSON) {
const auth = new google.auth.GoogleAuth({
credentials: credentialsJSON,
scopes: DRIVE_SCOPES
});
drive = google.drive({ version: "v3", auth });
}
const DB_PATH = path.join(__dirname, "cache", "gdrive_counter.json");
const LINKS_PATH = path.join(__dirname, "cache", "gdrive_links.json");
const USERS_PATH = path.join(__dirname, "cache", "gdrive_users.json");
fs.ensureDirSync(path.dirname(DB_PATH));
if (!fs.existsSync(DB_PATH)) fs.writeJsonSync(DB_PATH, { video: 0, audio: 0, image: 0, gif: 0, file: 0 });
if (!fs.existsSync(LINKS_PATH)) fs.writeJsonSync(LINKS_PATH, {});
if (!fs.existsSync(USERS_PATH)) fs.writeJsonSync(USERS_PATH, { allowedUsers: [] });
function getNextNumber(type) {
const data = fs.readJsonSync(DB_PATH);
data[type] = (data[type] || 0) + 1;
fs.writeJsonSync(DB_PATH, data);
return data[type];
}
function saveFileMapping(name, fileId, type, webLink) {
const data = fs.readJsonSync(LINKS_PATH);
data[name.toLowerCase()] = { id: fileId, type: type, link: webLink };
fs.writeJsonSync(LINKS_PATH, data);
}
function getFileData(name) {
const data = fs.readJsonSync(LINKS_PATH);
return data[name.toLowerCase()] || null;
}
function extractAllUrls(text) {
if (!text) return [];
return text.match(/(https?:\/\/[^\s]+)/g) || [];
}
module.exports = {
config: {
name: "gdrive",
aliases: ["gd", "drive"],
version: "12.1",
author: "Arafat & Sahu",
countDown: 2,
role: 0,
shortDescription: { en: "Advanced Gmail Google Drive Control Panel" },
longDescription: { en: "Manage your Gmail Google drive easily with auto-numbering, permissions and list selection." },
category: "UTILITY",
guide: { en: "{pn} help" }
},
onStart: async function ({ api, event, args, message, role }) {
if (!drive) return message.reply("❌ 'credentials.json' ফাইলটি মেইন ডিরেক্টরিতে সেটআপ করা নেই!");
const { senderID, messageReply } = event;
const usersData = fs.readJsonSync(USERS_PATH);
const isMainAdmin = (role >= 3);
const isAllowedUser = usersData.allowedUsers.includes(senderID) || isMainAdmin;
if (!isAllowedUser) {
return message.reply("❌ আপনার এই ড্রাইভ কমান্ড প্যানেল ব্যবহার করার কোনো পারমিশন নেই!");
}
const subCommand = args[0] ? args[0].toLowerCase() : "";
if (subCommand === "help") {
let helpMsg = "━━━━━ 𝐆𝐃𝐑𝐈𝐕𝐄 𝐇𝐄𝐋𝐏 ━━━━━\n\n" +
"🔹 [শুধু লিংক] ➔ ড্রাইভ সেভ ছাড়া ডিরেক্ট প্লে\n" +
"🔹 .gdrive save ➔ অটো নাম্বারিংয়ে ফাইল সেভ\n" +
"🔹 .gdrive save [নাম] ➔ কাস্টম নামে ফাইল সেভ\n" +
"🔹 .gdrive [নাম/নাম্বার] ➔ ফাইল চ্যাটে প্রদর্শন/প্লে\n" +
"🔹 .gdrive file [নাম/নাম্বার] ➔ ড্রাইভ ফাইল লিংক\n" +
"🔹 .gdrive del [নাম/নাম্বার] ➔ ড্রাইভ থেকে স্থায়ী ডিলিট\n" +
"🔹 .gdrive [ক্যাটাগরি] list ➔ ফাইলের তালিকা\n" +
"🔹 .gdrive edit [পুরাতন_নাম] [নতুন_নাম] ➔ নাম পরিবর্তন\n\n" +
"👑 𝐀𝐃𝐌𝐈𝐍 𝐂𝐎𝐌𝐌𝐀𝐍𝐃𝐒:\n" +
"🔸 .gdrive user add [Reply/UID] ➔ ইউজার যুক্ত করা\n" +
"🔸 .gdrive user ➔ ইউজার রিমুভ ও লিস্ট\n" +
"━━━━━━━━━━━━━━━━━━";
return message.reply(helpMsg);
}
if (subCommand === "user") {
if (!isMainAdmin) return message.reply("❌ এই ক্ষমতা শুধুমাত্র মেইন অ্যাডমিনের আছে!");
if (args[1] === "add") {
let targetUID = args[2] || (messageReply ? messageReply.senderID : null);
if (!targetUID) return message.reply("❌ অনুগ্রহ করে ইউজারের UID দিন অথবা তার মেসেজে রিপ্লাই দিন।");
if (!usersData.allowedUsers.includes(targetUID)) {
usersData.allowedUsers.push(targetUID);
fs.writeJsonSync(USERS_PATH, usersData);
}
return message.reply(`✅ ইউজার (UID: ${targetUID}) সফলভাবে ড্রাইভ এক্সেস তালিকায় যুক্ত হয়েছে।`);
}
if (usersData.allowedUsers.length === 0) return message.reply("⭕ পারমিশন পাওয়া কোনো ইউজারের তালিকা নেই।");
let uList = "👥 𝐆𝐃𝐑𝐈𝐕𝐄 𝐔𝐒𝐄𝐑 𝐋𝐈𝐒𝐓:\n\n";
for (let i = 0; i < usersData.allowedUsers.length; i++) {
uList += `${i + 1}. UID: ${usersData.allowedUsers[i]}\n`;
}
uList += "\n👉 যে ইউজারকে রিমুভ করতে চান, এই মেসেজে তার নম্বর টাইপ করে রিপ্লাই দিন।";
return message.reply(uList).then(info => {
global.GoatBot.onReply.set(info.messageID, {
commandName: this.config.name,
type: "user_remove",
author: senderID,
list: usersData.allowedUsers,
messageID: info.messageID
});
});
}
if (subCommand === "edit") {
const oldName = args[1];
const newName = args[2];
if (!oldName || !newName) return message.reply("❌ সঠিক নিয়ম: .gdrive edit [পুরাতন_নাম] [নতুন_নাম]");
const fileData = getFileData(oldName);
if (!fileData) return message.reply("❌ এই নামের কোনো ফাইল ডাটাবেসে পাওয়া যায়নি!");
try {
await drive.files.update({ fileId: fileData.id, requestBody: { name: newName } });
const allLinks = fs.readJsonSync(LINKS_PATH);
allLinks[newName.toLowerCase()] = { id: fileData.id, type: fileData.type, link: fileData.link };
delete allLinks[oldName.toLowerCase()];
fs.writeJsonSync(LINKS_PATH, allLinks);
return message.reply(`✅ ফাইলের নাম '${oldName}' থেকে বদলে সফলভাবে '${newName}' করা হয়েছে!`);
} catch (err) {
return message.reply(`❌ নাম পরিবর্তন ব্যর্থ হয়েছে: ${err.message}`);
}
}
if (subCommand === "del" || subCommand === "delete") {
const targetName = args[1];
if (!targetName) return message.reply("❌ অনুগ্রহ করে ফাইলের নাম বা নাম্বার দিন। যেমন: .gdrive del video_1");
const fileData = getFileData(targetName);
if (!fileData) return message.reply("❌ এই নামের কোনো ফাইল ড্রাইভ ডাটাবেসে নেই।");
try {
await drive.files.delete({ fileId: fileData.id });
const allLinks = fs.readJsonSync(LINKS_PATH);
delete allLinks[targetName.toLowerCase()];
fs.writeJsonSync(LINKS_PATH, allLinks);
return message.reply(`🗑️ '${targetName}' ফাইলটি ড্রাইভ থেকে সফলভাবে ডিলিট করা হয়েছে!`);
} catch (err) {
return message.reply(`❌ ডিলিট ব্যর্থ হয়েছে: ${err.message}`);
}
}
if (subCommand === "file") {
const targetName = args[1];
if (!targetName) return message.reply("❌ ফাইলের নাম দিন। যেমন: .gdrive file video_1");
const fileData = getFileData(targetName);
if (!fileData) return message.reply("❌ ফাইলটি পাওয়া যায়নি।");
// লিংক টেক্সট আগে পাঠানো হচ্ছে
await message.reply(`📁 𝐅𝐢𝐥𝐞: ${targetName}\n🔗 𝐃𝐨𝐰𝐧𝐥𝐨𝐚𝐝 𝐋𝐢𝐧𝐤:\n${fileData.link}`);
// এরপর video/audio/image/gif হলে অটোমেটিক প্রিভিউ দেখানো হচ্ছে (শুধু প্লেব্যাক, নতুন করে সেভ হচ্ছে না)
if (["video", "audio", "image", "gif"].includes(fileData.type)) {
try {
const wait = await message.reply(`⏳ '${targetName}' প্রিভিউ লোড হচ্ছে...`);
const res = await drive.files.get({ fileId: fileData.id, alt: "media" }, { responseType: "stream" });
await message.unsend(wait.messageID);
return message.reply({ body: `✅ Preview: ${targetName}`, attachment: res.data });
} catch (e) {
return message.reply(`⚠️ লিংক পাওয়া গেছে কিন্তু প্রিভিউ লোড করতে সমস্যা হয়েছে: ${e.message}`);
}
}
return;
}
if (subCommand === "save") {
if (!messageReply || !messageReply.attachments || messageReply.attachments.length === 0) {
return message.reply("❌ দয়া করে কোনো ছবি/ভিডিওতে রিপ্লাই দিয়ে .gdrive save লিখুন।");
}
const attach = messageReply.attachments[0];
let fileType = "file";
let ext = "bin";
if (attach.type === "video") { fileType = "video"; ext = "mp4"; }
else if (attach.type === "photo") { fileType = "image"; ext = "jpg"; }
else if (attach.type === "audio") { fileType = "audio"; ext = "mp3"; }
else if (attach.type === "animated_image") { fileType = "gif"; ext = "gif"; }
let fileName = args.slice(1).join(" ").trim();
if (!fileName) {
const currentCount = getNextNumber(fileType);
fileName = `${fileType}_${currentCount}`;
}
const fullFileName = `${fileName}.${ext}`;
const wait = await message.reply(`⏳ '${fullFileName}' নামে জিমেইল ড্রাইভে সেভ হচ্ছে...`);
try {
const responseStream = await axios({ method: "get", url: attach.url, responseType: "stream" });
const driveResponse = await drive.files.create({
requestBody: { name: fullFileName, mimeType: responseStream.headers["content-type"] },
media: { mimeType: responseStream.headers["content-type"], body: responseStream.data },
fields: "id, webViewLink"
});
await drive.permissions.create({ fileId: driveResponse.data.id, requestBody: { role: "reader", type: "anyone" } });
saveFileMapping(fileName, driveResponse.data.id, fileType, driveResponse.data.webViewLink);
await message.unsend(wait.messageID);
return message.reply(`✅ 𝐒𝐚𝐯𝐞 𝐒𝐮𝐜𝐜𝐞𝐬𝐬𝐟𝐮𝐥!\n\n📁 Name: ${fileName}\n🆔 ID: ${driveResponse.data.id}\n🔗 Link: ${driveResponse.data.webViewLink}`);
} catch (e) {
return message.reply(`❌ সেভ করতে সমস্যা হয়েছে: ${e.message}`);
}
}
if (args[1] === "list") {
const catType = args[0].toLowerCase();
const allLinks = fs.readJsonSync(LINKS_PATH);
const filtered = Object.keys(allLinks).filter(k => allLinks[k].type === catType);
if (filtered.length === 0) return message.reply(`⭕ ${catType} ক্যাটাগরিতে কোনো ফাইল সেভ করা নেই।`);
let listMsg = `📂 𝐆𝐃𝐑𝐈𝐕𝐄 ${catType.toUpperCase()} 𝐋𝐈𝐒𝐓:\n\n`;
for (let i = 0; i < filtered.length; i++) {
listMsg += `${i + 1}. ${filtered[i]}\n`;
}
listMsg += "\n👉 যে ফাইলটি প্লে করতে চান, তার নম্বর টাইপ করে রিপ্লাই দিন।";
return message.reply(listMsg).then(info => {
global.GoatBot.onReply.set(info.messageID, {
commandName: this.config.name,
type: "list_choose",
author: senderID,
list: filtered,
messageID: info.messageID
});
});
}
const urls = extractAllUrls(event.body);
if (urls.length > 0) {
try {
const wait = await message.reply("⏳ লিংক থেকে ফাইলটি প্রসেস করা হচ্ছে (No Save)...");
const resStream = await axios({ method: "get", url: urls[0], responseType: "stream" });
await message.unsend(wait.messageID);
return message.reply({ body: "✅ Temporary Playback:", attachment: resStream.data });
} catch (err) {
return message.reply(`❌ লিংক প্লে করতে সমস্যা হয়েছে: ${err.message}`);
}
}
const checkName = args.join(" ").trim();
if (checkName) {
const fileData = getFileData(checkName);
if (fileData) {
try {
const wait = await message.reply(`⏳ '${checkName}' ড্রাইভ থেকে লোড হচ্ছে...`);
const res = await drive.files.get({ fileId: fileData.id, alt: "media" }, { responseType: "stream" });
await message.unsend(wait.messageID);
return message.reply({ body: `✅ Playing: ${checkName}`, attachment: res.data });
} catch (e) {
return message.reply(`❌ ফাইলটি প্লে করতে সমস্যা হয়েছে: ${e.message}`);
}
} else {
return message.reply("❌ এই নামে বা নাম্বারে কোনো ফাইল বা কমান্ড পাওয়া যায়নি। সাহায্য পেতে লিখুন: .gdrive help");
}
}
},
onReply: async function ({ event, message, Reply }) {
const { author, type, list, messageID } = Reply;
if (event.senderID !== author) return;
const choice = parseInt(event.body.trim());
if (isNaN(choice) || choice < 1 || choice > list.length) {
global.GoatBot.onReply.delete(messageID);
return message.reply("❌ বাতিল করা হয়েছে।");
}
global.GoatBot.onReply.delete(messageID);
const selectedItem = list[choice - 1];
if (type === "user_remove") {
const usersData = fs.readJsonSync(USERS_PATH);
usersData.allowedUsers = usersData.allowedUsers.filter(u => u !== selectedItem);
fs.writeJsonSync(USERS_PATH, usersData);
return message.reply(`🗑️ ইউজার (UID: ${selectedItem}) সফলভাবে অনুমতি তালিকা থেকে রিমুভ হয়েছে।`);
}
if (type === "list_choose") {
const allLinks = fs.readJsonSync(LINKS_PATH);
const fileData = allLinks[selectedItem.toLowerCase()];
try {
const wait = await message.reply(`⏳ '${selectedItem}' ড্রাইভ থেকে লোড হচ্ছে...`);
const localDrive = drive;
const res = await localDrive.files.get({ fileId: fileData.id, alt: "media" }, { responseType: "stream" });
await message.unsend(wait.messageID);
return message.reply({ body: `✅ Playing selected: ${selectedItem}`, attachment: res.data });
} catch (e) {
return message.reply(`❌ ফাইলটি আনতে সমস্যা হয়েছে: ${e.message}`);
}
}
}
};