goat
command
tagreply
No description
0
views
0
likes
0
installs
Aliases: tr, tagr, nametag
raw source
module.exports = {
config: {
name: "tagreply",
aliases: ["tr", "tagr", "nametag"],
version: "2.0.0",
author: "Banu_suna",
countDown: 2,
role: 0,
description: {
en: "Tag a member by name or by replying to their message",
bn: "নাম দিয়ে বা কারো মেসেজে রিপ্লাই দিয়ে ট্যাগ করুন"
},
category: "box chat",
guide: {
en: "• Reply to someone's message:\n {pn}\n {pn} your text here\n\n• By name:\n {pn} <name>\n {pn} <name> <message>",
bn: "• কারো মেসেজে রিপ্লাই দিয়ে:\n {pn}\n {pn} আপনার টেক্সট\n\n• নাম দিয়ে:\n {pn} <নাম>\n {pn} <নাম> <মেসেজ>"
}
},
langs: {
en: {
missing: "⚠ Reply to someone's message or enter a name.\nExample:\n.tagreply (while replying)\n.tagreply Rocky Hello!",
notFound: "✗ No member found matching \"%1\"",
cannotTagSelf: "✗ You cannot tag yourself this way."
},
bn: {
missing: "⚠ কারো মেসেজে রিপ্লাই দিন অথবা নাম লিখুন।\nউদাহরণ:\n.tagreply (রিপ্লাই দিয়ে)\n.tagreply Rocky কি করছো?",
notFound: "✗ \"%1\" নামে কোনো মেম্বার পাওয়া যায়নি",
cannotTagSelf: "✗ এইভাবে নিজেকে ট্যাগ করা যাবে না।"
}
},
onStart: async function ({ api, event, args, message, usersData, threadsData, getLang }) {
const { threadID, senderID, messageReply } = event;
try {
// ========== MODE 1: Reply to someone's message (Fast Path) ==========
if (messageReply && messageReply.senderID) {
const targetID = messageReply.senderID;
const replyToMsgID = messageReply.messageID;
const extraMessage = args.join(" ").trim();
let targetName = "User";
// দ্রুত নাম আনার চেষ্টা
try {
const dbName = await usersData.getName(targetID);
if (dbName) targetName = dbName;
} catch (e) {}
if (targetName === "User") {
try {
const info = await api.getUserInfo(targetID);
if (info[targetID]?.name) targetName = info[targetID].name;
} catch (e) {}
}
const tagText = `@${targetName}`;
let body = tagText;
if (extraMessage) body += "\n" + extraMessage;
return api.sendMessage(
{
body,
mentions: [{ tag: tagText, id: targetID }]
},
threadID,
null,
replyToMsgID
);
}
// ========== MODE 2: Tag by name ==========
if (!args[0]) {
return message.reply(getLang("missing"));
}
let searchQuery = args[0].toLowerCase().trim();
let textAfterName = args.slice(1).join(" ").trim();
// ---- Fast: threadsData থেকে নাম নেওয়ার চেষ্টা (ক্যাশ) ----
let members = [];
try {
const threadData = await threadsData.get(threadID);
if (threadData?.members && Array.isArray(threadData.members)) {
members = threadData.members
.filter(m => m.userID && m.userID != api.getCurrentUserID() && m.name)
.map(m => ({
id: m.userID,
name: m.name,
nameLower: m.name.toLowerCase(),
firstName: m.name.split(" ")[0].toLowerCase()
}));
}
} catch (e) {}
// ---- threadsData খালি হলে getThreadInfo + batched getUserInfo ----
if (members.length === 0) {
const threadInfo = await api.getThreadInfo(threadID);
const participantIDs = (threadInfo.participantIDs || []).filter(
id => id != api.getCurrentUserID()
);
if (!participantIDs.length) {
return message.reply(getLang("notFound", searchQuery));
}
// Facebook API তে একবারে অনেক ID দিলে ফেইল করে — ৪০ করে ব্যাচ
const userInfos = {};
const chunkSize = 40;
for (let i = 0; i < participantIDs.length; i += chunkSize) {
const chunk = participantIDs.slice(i, i + chunkSize);
try {
const info = await api.getUserInfo(chunk);
Object.assign(userInfos, info);
} catch (e) {
// একটি চান্ক ফেইল হলেও বাকি চালু থাকবে
}
}
// usersData.getName লুপে না চালিয়ে শুধু getUserInfo ব্যবহার
for (const uid of participantIDs) {
const name = userInfos[uid]?.name;
if (!name) continue;
members.push({
id: uid,
name,
nameLower: name.toLowerCase(),
firstName: name.split(" ")[0].toLowerCase()
});
}
}
if (members.length === 0) {
return message.reply(getLang("notFound", searchQuery));
}
// ---- Matching (priority order) ----
let matched = members.filter(m => m.firstName === searchQuery);
if (matched.length === 0) {
matched = members.filter(m => m.nameLower === searchQuery);
}
if (matched.length === 0) {
matched = members.filter(m => m.firstName.startsWith(searchQuery));
}
if (matched.length === 0) {
matched = members.filter(
m => m.nameLower.startsWith(searchQuery) || m.nameLower.includes(searchQuery)
);
}
// ২ শব্দের নাম চেষ্টা
if (matched.length === 0 && args.length > 1) {
const fullTry = args.slice(0, 2).join(" ").toLowerCase();
matched = members.filter(
m =>
m.nameLower === fullTry ||
m.nameLower.startsWith(fullTry) ||
m.nameLower.includes(fullTry)
);
if (matched.length > 0) {
textAfterName = args.slice(2).join(" ").trim();
}
}
if (matched.length === 0) {
return message.reply(getLang("notFound", searchQuery));
}
// অনেক ম্যাচ হলে শুধু প্রথম ১০ জন ট্যাগ (বড় গ্রুপে স্প্যাম আটকাতে)
if (matched.length > 10) {
matched = matched.slice(0, 10);
}
const mentions = [];
let body = "";
for (const m of matched) {
const tagText = `@${m.name}`;
mentions.push({ tag: tagText, id: m.id });
body += tagText + " ";
}
body = body.trim();
if (textAfterName) body += "\n" + textAfterName;
return message.reply({
body,
mentions
});
} catch (err) {
console.error("tagreply error:", err);
return message.reply("✗ Error occurred. Please try again.");
}
}
};