lordceaser-baileys 2.0.28 → 2.0.32
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/index.js +392 -167
- package/package.json +19 -5
package/index.js
CHANGED
|
@@ -1,192 +1,417 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
console.log(banner);
|
|
1
|
+
/**
|
|
2
|
+
* C⁴ SOCIETY MD — WhatsApp Bot (Baileys - Pairing Code)
|
|
3
|
+
* Developer: ¿[ℓσя∂ ƒαмσυѕ тнє ƒαтнєя σƒ ∂υαℓ gσ∂ѕ]?[⁰⁰¹] σƒ C⁴
|
|
4
|
+
* Creator: +2348058314787
|
|
5
|
+
*/
|
|
6
|
+
|
|
7
|
+
const { default: makeWASocket, useMultiFileAuthState, DisconnectReason, fetchLatestBaileysVersion } = require("@whiskeysockets/baileys");
|
|
8
|
+
const { Boom } = require("@hapi/boom");
|
|
9
|
+
const axios = require("axios");
|
|
10
|
+
const path = require("path");
|
|
11
|
+
const fs = require("fs");
|
|
12
|
+
const pino = require("pino");
|
|
13
|
+
require("dotenv").config();
|
|
14
|
+
|
|
15
|
+
const readline = require("readline");
|
|
16
|
+
|
|
17
|
+
const BOT_NAME = "C⁴ SOCIETY MD";
|
|
18
|
+
const DEVELOPER = "¿[ℓσя∂ ƒαмσυѕ тнє ƒαтнєя σƒ ∂υαℓ gσ∂ѕ]?[⁰⁰¹] σƒ C⁴";
|
|
19
|
+
const CREATOR = "+2348058314787";
|
|
20
|
+
|
|
21
|
+
function getOwnerNumber() {
|
|
22
|
+
return (process.env.OWNER_NUMBER || "").replace(/\D/g, "").replace(/^0+/, "");
|
|
24
23
|
}
|
|
25
24
|
|
|
26
|
-
|
|
25
|
+
const MENU_IMAGE = path.join(__dirname, "assets", "menu.jpg");
|
|
26
|
+
|
|
27
|
+
// ---------- Access control ----------
|
|
28
|
+
let privateMode = "public";
|
|
29
|
+
const whitelist = new Set();
|
|
30
|
+
|
|
31
|
+
function normalize(jid) { return jid.replace(/[^0-9]/g, ""); }
|
|
27
32
|
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
+
function canUseBot(senderJid, ownerJid) {
|
|
34
|
+
if (senderJid === ownerJid) return true;
|
|
35
|
+
if (privateMode === "public") return true;
|
|
36
|
+
if (privateMode === "self") return false;
|
|
37
|
+
if (privateMode === "whitelist") return whitelist.has(normalize(senderJid));
|
|
38
|
+
return false;
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
// ---------- Content ----------
|
|
42
|
+
const JOKES = [
|
|
43
|
+
"Why do programmers prefer dark mode? Because light attracts bugs.",
|
|
44
|
+
"I told my computer I needed a break — it said no problem, it'll go to sleep too.",
|
|
45
|
+
"There are 10 types of people: those who understand binary, and those who don't.",
|
|
46
|
+
];
|
|
47
|
+
const QUOTES = [
|
|
48
|
+
'"The only way to do great work is to love what you do." — Steve Jobs',
|
|
49
|
+
'"Success is not final, failure is not fatal." — Winston Churchill',
|
|
50
|
+
'"Stay hungry, stay foolish." — Steve Jobs',
|
|
51
|
+
];
|
|
52
|
+
const FAQ = {
|
|
53
|
+
hours: "We're available 9 AM – 6 PM, Monday to Saturday.",
|
|
54
|
+
pricing: "Please tell us what product/service you're asking about.",
|
|
55
|
+
contact: "Reply here and our support team will get back to you ASAP.",
|
|
56
|
+
location: "We're online-only — no physical location.",
|
|
57
|
+
};
|
|
58
|
+
|
|
59
|
+
function pickRandom(arr) { return arr[Math.floor(Math.random() * arr.length)]; }
|
|
60
|
+
|
|
61
|
+
function helpText() {
|
|
62
|
+
return (
|
|
63
|
+
`*${BOT_NAME}*\n` +
|
|
64
|
+
`Developer: ${DEVELOPER}\n` +
|
|
65
|
+
`Creator: ${CREATOR}\n\n` +
|
|
66
|
+
"*Commands (everyone):*\n" +
|
|
67
|
+
"!help — show this menu\n" +
|
|
68
|
+
"!joke — random joke\n" +
|
|
69
|
+
"!quote — random quote\n" +
|
|
70
|
+
"!roll — roll a dice (1–6)\n" +
|
|
71
|
+
"!flip — flip a coin\n" +
|
|
72
|
+
"!faq hours / pricing / contact / location\n" +
|
|
73
|
+
"!ai <question> — ask the AI assistant\n" +
|
|
74
|
+
"Send image with caption *!sticker* to convert it\n\n" +
|
|
75
|
+
"*Download commands:*\n" +
|
|
76
|
+
"!ytmp3 <url> — download YouTube audio (mp3)\n" +
|
|
77
|
+
"!ytmp4 <url> — download YouTube video (mp4)\n" +
|
|
78
|
+
"!tiktok <url> — download TikTok video (no watermark)\n" +
|
|
79
|
+
"!ig <url> — download Instagram video/photo\n" +
|
|
80
|
+
"!fb <url> — download Facebook video\n\n" +
|
|
81
|
+
"*Group commands (admin only):*\n" +
|
|
82
|
+
"!tag <message> — mention every member\n" +
|
|
83
|
+
"!kick — reply to a member's msg to kick them\n" +
|
|
84
|
+
"!welcome on / off — toggle welcome message\n\n" +
|
|
85
|
+
"*Owner only:*\n" +
|
|
86
|
+
"!self — lock bot to owner only\n" +
|
|
87
|
+
"!self off — unlock back to public\n" +
|
|
88
|
+
"!whitelist add 234... — whitelist a number\n" +
|
|
89
|
+
"!whitelist remove 234... — remove a number\n" +
|
|
90
|
+
"!whitelist list — show whitelisted numbers\n" +
|
|
91
|
+
"!whitelist on / off — toggle whitelist mode\n\n" +
|
|
92
|
+
`*Current mode:* ${privateMode}`
|
|
93
|
+
);
|
|
94
|
+
}
|
|
95
|
+
|
|
96
|
+
async function askAI(prompt) {
|
|
33
97
|
try {
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
98
|
+
const res = await axios.post(
|
|
99
|
+
"https://api.openai.com/v1/chat/completions",
|
|
100
|
+
{ model: "gpt-4o-mini", messages: [{ role: "user", content: prompt }] },
|
|
101
|
+
{ headers: { Authorization: `Bearer ${process.env.AI_API_KEY}`, "Content-Type": "application/json" } }
|
|
102
|
+
);
|
|
103
|
+
return res.data.choices[0].message.content;
|
|
104
|
+
} catch (err) {
|
|
105
|
+
return "Sorry, couldn't reach the AI service right now.";
|
|
39
106
|
}
|
|
40
107
|
}
|
|
41
108
|
|
|
42
|
-
//
|
|
43
|
-
const originalMakeWASocket = lib.default || lib.makeWASocket;
|
|
109
|
+
// ---------- Downloader functions ----------
|
|
44
110
|
|
|
45
|
-
function
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
return
|
|
111
|
+
async function downloadYT(url, type) {
|
|
112
|
+
try {
|
|
113
|
+
const api = `https://api.ryzendesu.vip/api/downloader/${type === "mp3" ? "ytmp3" : "ytmp4"}?url=${encodeURIComponent(url)}`;
|
|
114
|
+
const res = await axios.get(api, { timeout: 30000 });
|
|
115
|
+
return res.data?.url || res.data?.link || res.data?.download || null;
|
|
116
|
+
} catch (err) {
|
|
117
|
+
return null;
|
|
52
118
|
}
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
} else if (b.text) {
|
|
62
|
-
// If only text, assume quick_reply with text as id
|
|
63
|
-
return { name: "quick_reply", buttonParamsJson: JSON.stringify({ display_text: b.text, id: b.text.toLowerCase().replace(/\s+/g, '_') }) };
|
|
64
|
-
}
|
|
65
|
-
return null;
|
|
66
|
-
}).filter(Boolean);
|
|
67
|
-
|
|
68
|
-
const newContent = { ...content };
|
|
69
|
-
delete newContent.nativeFlow;
|
|
70
|
-
newContent.interactiveButtons = flowButtons;
|
|
71
|
-
return newContent;
|
|
119
|
+
}
|
|
120
|
+
|
|
121
|
+
async function downloadTikTok(url) {
|
|
122
|
+
try {
|
|
123
|
+
const res = await axios.get(`https://api.ryzendesu.vip/api/downloader/ttdl?url=${encodeURIComponent(url)}`, { timeout: 30000 });
|
|
124
|
+
return res.data?.video || res.data?.url || null;
|
|
125
|
+
} catch (err) {
|
|
126
|
+
return null;
|
|
72
127
|
}
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
}
|
|
83
|
-
return { name: "quick_reply", buttonParamsJson: JSON.stringify({ display_text: text, id: id }) };
|
|
84
|
-
});
|
|
85
|
-
|
|
86
|
-
const newContent = { ...content };
|
|
87
|
-
delete newContent.buttons;
|
|
88
|
-
delete newContent.headerType;
|
|
89
|
-
newContent.interactiveButtons = flowButtons;
|
|
90
|
-
return newContent;
|
|
128
|
+
}
|
|
129
|
+
|
|
130
|
+
async function downloadIG(url) {
|
|
131
|
+
try {
|
|
132
|
+
const res = await axios.get(`https://api.ryzendesu.vip/api/downloader/igdl?url=${encodeURIComponent(url)}`, { timeout: 30000 });
|
|
133
|
+
const items = res.data?.data || res.data?.result || [];
|
|
134
|
+
return items[0]?.url || null;
|
|
135
|
+
} catch (err) {
|
|
136
|
+
return null;
|
|
91
137
|
}
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
138
|
+
}
|
|
139
|
+
|
|
140
|
+
async function downloadFB(url) {
|
|
141
|
+
try {
|
|
142
|
+
const res = await axios.get(`https://api.ryzendesu.vip/api/downloader/fbdl?url=${encodeURIComponent(url)}`, { timeout: 30000 });
|
|
143
|
+
return res.data?.hd || res.data?.sd || res.data?.url || null;
|
|
144
|
+
} catch (err) {
|
|
145
|
+
return null;
|
|
99
146
|
}
|
|
100
|
-
|
|
101
|
-
return content;
|
|
102
147
|
}
|
|
103
148
|
|
|
104
|
-
function
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
149
|
+
async function sendDownload(sock, from, msg, downloadUrl, type, caption) {
|
|
150
|
+
try {
|
|
151
|
+
const response = await axios.get(downloadUrl, { responseType: "arraybuffer", timeout: 60000 });
|
|
152
|
+
const buffer = Buffer.from(response.data);
|
|
153
|
+
if (type === "audio") {
|
|
154
|
+
await sock.sendMessage(from, { audio: buffer, mimetype: "audio/mp4", fileName: "audio.mp3" }, { quoted: msg });
|
|
155
|
+
} else {
|
|
156
|
+
await sock.sendMessage(from, { video: buffer, caption }, { quoted: msg });
|
|
157
|
+
}
|
|
158
|
+
} catch (err) {
|
|
159
|
+
await sock.sendMessage(from, { text: "❌ Failed to send file. The file may be too large or the link expired." }, { quoted: msg });
|
|
160
|
+
}
|
|
161
|
+
}
|
|
162
|
+
|
|
163
|
+
const welcomeSettings = new Map();
|
|
164
|
+
|
|
165
|
+
// ---------- Main ----------
|
|
166
|
+
async function startBot() {
|
|
167
|
+
const { state, saveCreds } = await useMultiFileAuthState("auth_info");
|
|
168
|
+
const { version } = await fetchLatestBaileysVersion();
|
|
169
|
+
|
|
170
|
+
// Always ask for the number to pair
|
|
171
|
+
const rl = readline.createInterface({ input: process.stdin, output: process.stdout });
|
|
172
|
+
const phoneNumber = await new Promise((resolve) => {
|
|
173
|
+
rl.question("\n📱 Enter the WhatsApp number to link (with country code, no + sign):\n> ", (ans) => {
|
|
174
|
+
rl.close();
|
|
175
|
+
resolve(ans.replace(/\D/g, "").replace(/^0+/, ""));
|
|
176
|
+
});
|
|
177
|
+
});
|
|
178
|
+
|
|
179
|
+
const OWNER_JID = (process.env.OWNER_NUMBER || phoneNumber).replace(/\D/g, "") + "@s.whatsapp.net";
|
|
180
|
+
console.log(`\n✅ Linking number: ${phoneNumber}`);
|
|
181
|
+
|
|
182
|
+
const sock = makeWASocket({
|
|
183
|
+
version,
|
|
184
|
+
auth: state,
|
|
185
|
+
logger: pino({ level: "silent" }),
|
|
186
|
+
printQRInTerminal: false,
|
|
187
|
+
browser: ["C⁴ SOCIETY MD", "Chrome", "1.0.0"],
|
|
188
|
+
syncFullHistory: false,
|
|
189
|
+
markOnlineOnConnect: false,
|
|
190
|
+
});
|
|
191
|
+
|
|
192
|
+
// ---- PAIRING CODE ----
|
|
193
|
+
if (!sock.authState.creds.registered) {
|
|
194
|
+
console.log(`\n⏳ Requesting pairing code for: ${phoneNumber} ...\n`);
|
|
195
|
+
setTimeout(async () => {
|
|
196
|
+
try {
|
|
197
|
+
const code = await sock.requestPairingCode(phoneNumber);
|
|
198
|
+
const formatted = code.match(/.{1,4}/g)?.join("-") || code;
|
|
199
|
+
console.log("\n╔══════════════════════════════════════╗");
|
|
200
|
+
console.log("║ C⁴ SOCIETY MD — PAIRING ║");
|
|
201
|
+
console.log("╠══════════════════════════════════════╣");
|
|
202
|
+
console.log(`║ Code: ${formatted.padEnd(30)}║`);
|
|
203
|
+
console.log("╠══════════════════════════════════════╣");
|
|
204
|
+
console.log("║ Steps: ║");
|
|
205
|
+
console.log("║ 1. Open WhatsApp on your phone ║");
|
|
206
|
+
console.log("║ 2. Go to Linked Devices ║");
|
|
207
|
+
console.log("║ 3. Tap Link a Device ║");
|
|
208
|
+
console.log("║ 4. Tap Link with phone number ║");
|
|
209
|
+
console.log("║ 5. Enter the code above QUICKLY ║");
|
|
210
|
+
console.log("║ (code expires in 60 seconds) ║");
|
|
211
|
+
console.log("╚══════════════════════════════════════╝\n");
|
|
212
|
+
} catch (err) {
|
|
213
|
+
console.error("❌ Pairing code error:", err.message);
|
|
214
|
+
console.log("➡ Delete the auth_info folder and restart");
|
|
215
|
+
console.log("➡ Make sure the number has country code, no + sign");
|
|
216
|
+
console.log("➡ Example: 2348058314787");
|
|
119
217
|
}
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
218
|
+
}, 5000);
|
|
219
|
+
}
|
|
220
|
+
|
|
221
|
+
sock.ev.on("creds.update", saveCreds);
|
|
222
|
+
|
|
223
|
+
sock.ev.on("connection.update", ({ connection, lastDisconnect }) => {
|
|
224
|
+
if (connection === "close") {
|
|
225
|
+
const shouldReconnect = new Boom(lastDisconnect?.error)?.output?.statusCode !== DisconnectReason.loggedOut;
|
|
226
|
+
console.log("Connection closed. Reconnecting:", shouldReconnect);
|
|
227
|
+
if (shouldReconnect) startBot();
|
|
228
|
+
} else if (connection === "open") {
|
|
229
|
+
console.log(`✅ ${BOT_NAME} connected successfully!`);
|
|
230
|
+
}
|
|
231
|
+
});
|
|
232
|
+
|
|
233
|
+
sock.ev.on("group-participants.update", async ({ id, participants, action }) => {
|
|
234
|
+
if (action !== "add") return;
|
|
235
|
+
if (!(welcomeSettings.get(id) ?? true)) return;
|
|
236
|
+
const groupMeta = await sock.groupMetadata(id);
|
|
237
|
+
for (const participant of participants) {
|
|
238
|
+
await sock.sendMessage(id, {
|
|
239
|
+
text: `👋 Welcome @${participant.split("@")[0]} to *${groupMeta.subject}*!`,
|
|
240
|
+
mentions: [participant],
|
|
241
|
+
});
|
|
242
|
+
}
|
|
243
|
+
});
|
|
244
|
+
|
|
245
|
+
sock.ev.on("messages.upsert", async ({ messages, type }) => {
|
|
246
|
+
if (type !== "notify") return;
|
|
247
|
+
const msg = messages[0];
|
|
248
|
+
if (!msg.message || msg.key.fromMe) return;
|
|
249
|
+
|
|
250
|
+
const from = msg.key.remoteJid;
|
|
251
|
+
const sender = msg.key.participant || msg.key.remoteJid;
|
|
252
|
+
const isGroup = from.endsWith("@g.us");
|
|
253
|
+
const isOwner = sender === OWNER_NUMBER;
|
|
254
|
+
const body = msg.message?.conversation || msg.message?.extendedTextMessage?.text || "";
|
|
255
|
+
const text = body.trim();
|
|
256
|
+
const lower = text.toLowerCase();
|
|
257
|
+
const imageMsg = msg.message?.imageMessage;
|
|
258
|
+
|
|
259
|
+
const reply = (text) => sock.sendMessage(from, { text }, { quoted: msg });
|
|
260
|
+
|
|
261
|
+
// Access control for private chats
|
|
262
|
+
if (!isGroup && !canUseBot(sender)) {
|
|
263
|
+
return reply(
|
|
264
|
+
privateMode === "self"
|
|
265
|
+
? "🔒 Bot is in *self mode* — only the owner can use it."
|
|
266
|
+
: "🔒 Your number is not whitelisted to use this bot."
|
|
267
|
+
);
|
|
268
|
+
}
|
|
269
|
+
|
|
270
|
+
// Sticker from image
|
|
271
|
+
if (imageMsg && imageMsg.caption?.trim().toLowerCase() === "!sticker") {
|
|
272
|
+
const buffer = await sock.downloadMediaMessage(msg);
|
|
273
|
+
await sock.sendMessage(from, { sticker: buffer }, { quoted: msg });
|
|
274
|
+
return;
|
|
275
|
+
}
|
|
276
|
+
|
|
277
|
+
// Help with image
|
|
278
|
+
if (lower === "!help") {
|
|
279
|
+
const imageBuffer = fs.readFileSync(MENU_IMAGE);
|
|
280
|
+
await sock.sendMessage(from, { image: imageBuffer, caption: helpText() });
|
|
281
|
+
return;
|
|
282
|
+
}
|
|
283
|
+
|
|
284
|
+
// Fun commands
|
|
285
|
+
if (lower === "!joke") return reply(pickRandom(JOKES));
|
|
286
|
+
if (lower === "!quote") return reply(pickRandom(QUOTES));
|
|
287
|
+
if (lower === "!roll") return reply(`🎲 You rolled a ${1 + Math.floor(Math.random() * 6)}`);
|
|
288
|
+
if (lower === "!flip") return reply(`🪙 ${Math.random() < 0.5 ? "Heads" : "Tails"}`);
|
|
289
|
+
|
|
290
|
+
if (lower.startsWith("!faq")) {
|
|
291
|
+
const topic = lower.replace("!faq", "").trim();
|
|
292
|
+
return reply(FAQ[topic] || `Available topics: ${Object.keys(FAQ).join(", ")}\nUse: !faq <topic>`);
|
|
293
|
+
}
|
|
294
|
+
|
|
295
|
+
if (lower.startsWith("!ai ")) {
|
|
296
|
+
return reply(await askAI(text.slice(4).trim()));
|
|
297
|
+
}
|
|
298
|
+
|
|
299
|
+
// ---------- Download commands ----------
|
|
300
|
+
if (lower.startsWith("!ytmp3 ")) {
|
|
301
|
+
const url = text.slice(7).trim();
|
|
302
|
+
if (!url) return reply("Usage: !ytmp3 <YouTube URL>");
|
|
303
|
+
await reply("⏳ Downloading audio, please wait...");
|
|
304
|
+
const dlUrl = await downloadYT(url, "mp3");
|
|
305
|
+
if (!dlUrl) return reply("❌ Couldn't download. Check the URL and try again.");
|
|
306
|
+
return sendDownload(sock, from, msg, dlUrl, "audio", "🎵 Here's your audio!");
|
|
307
|
+
}
|
|
308
|
+
if (lower.startsWith("!ytmp4 ")) {
|
|
309
|
+
const url = text.slice(7).trim();
|
|
310
|
+
if (!url) return reply("Usage: !ytmp4 <YouTube URL>");
|
|
311
|
+
await reply("⏳ Downloading video, please wait...");
|
|
312
|
+
const dlUrl = await downloadYT(url, "mp4");
|
|
313
|
+
if (!dlUrl) return reply("❌ Couldn't download. Check the URL and try again.");
|
|
314
|
+
return sendDownload(sock, from, msg, dlUrl, "video", "🎬 Here's your video!");
|
|
315
|
+
}
|
|
316
|
+
if (lower.startsWith("!tiktok ")) {
|
|
317
|
+
const url = text.slice(8).trim();
|
|
318
|
+
if (!url) return reply("Usage: !tiktok <TikTok URL>");
|
|
319
|
+
await reply("⏳ Downloading TikTok video...");
|
|
320
|
+
const dlUrl = await downloadTikTok(url);
|
|
321
|
+
if (!dlUrl) return reply("❌ Couldn't download. Check the URL and try again.");
|
|
322
|
+
return sendDownload(sock, from, msg, dlUrl, "video", "🎵 Here's your TikTok!");
|
|
323
|
+
}
|
|
324
|
+
if (lower.startsWith("!ig ")) {
|
|
325
|
+
const url = text.slice(4).trim();
|
|
326
|
+
if (!url) return reply("Usage: !ig <Instagram URL>");
|
|
327
|
+
await reply("⏳ Downloading Instagram media...");
|
|
328
|
+
const dlUrl = await downloadIG(url);
|
|
329
|
+
if (!dlUrl) return reply("❌ Couldn't download. Make sure the post is public.");
|
|
330
|
+
return sendDownload(sock, from, msg, dlUrl, "video", "📸 Here's your Instagram media!");
|
|
331
|
+
}
|
|
332
|
+
if (lower.startsWith("!fb ")) {
|
|
333
|
+
const url = text.slice(4).trim();
|
|
334
|
+
if (!url) return reply("Usage: !fb <Facebook URL>");
|
|
335
|
+
await reply("⏳ Downloading Facebook video...");
|
|
336
|
+
const dlUrl = await downloadFB(url);
|
|
337
|
+
if (!dlUrl) return reply("❌ Couldn't download. Make sure the video is public.");
|
|
338
|
+
return sendDownload(sock, from, msg, dlUrl, "video", "📘 Here's your Facebook video!");
|
|
339
|
+
}
|
|
340
|
+
|
|
341
|
+
// Owner: !self
|
|
342
|
+
if (lower === "!self") {
|
|
343
|
+
if (!isOwner) return reply("⛔ Only the owner can use this command.");
|
|
344
|
+
privateMode = "self";
|
|
345
|
+
return reply("🔒 *Self mode ON* — only you can use the bot in private chats.");
|
|
346
|
+
}
|
|
347
|
+
if (lower === "!self off") {
|
|
348
|
+
if (!isOwner) return reply("⛔ Only the owner can use this command.");
|
|
349
|
+
privateMode = "public";
|
|
350
|
+
return reply("🔓 *Self mode OFF* — bot is public again.");
|
|
351
|
+
}
|
|
352
|
+
|
|
353
|
+
// Owner: !whitelist
|
|
354
|
+
if (lower.startsWith("!whitelist")) {
|
|
355
|
+
if (!isOwner) return reply("⛔ Only the owner can manage the whitelist.");
|
|
356
|
+
const args = text.slice(10).trim().split(/\s+/);
|
|
357
|
+
const action = args[0];
|
|
358
|
+
const numArg = args[1] ? normalize(args[1]) : null;
|
|
359
|
+
|
|
360
|
+
if (action === "on") { privateMode = "whitelist"; return reply("✅ *Whitelist mode ON.*"); }
|
|
361
|
+
if (action === "off") { privateMode = "public"; return reply("🔓 *Whitelist mode OFF.*"); }
|
|
362
|
+
if (action === "add" && numArg) {
|
|
363
|
+
whitelist.add(numArg);
|
|
364
|
+
privateMode = "whitelist";
|
|
365
|
+
return reply(`✅ *${numArg}* added to whitelist.\nWhitelist mode is now ON.`);
|
|
124
366
|
}
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
// Preserve thumbnail
|
|
367
|
+
if (action === "remove" && numArg) {
|
|
368
|
+
whitelist.delete(numArg);
|
|
369
|
+
return reply(`✅ *${numArg}* removed from whitelist.`);
|
|
129
370
|
}
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
} catch (e) {
|
|
133
|
-
console.log("⚠️ sendMessage patch error, trying original:", e.message);
|
|
134
|
-
// Fallback to original
|
|
135
|
-
try {
|
|
136
|
-
return await originalSendMessage(jid, content, options);
|
|
137
|
-
} catch (e2) {
|
|
138
|
-
console.log("❌ Original also failed:", e2.message);
|
|
139
|
-
throw e2;
|
|
371
|
+
if (action === "list") {
|
|
372
|
+
return reply(whitelist.size === 0 ? "📋 Whitelist is empty." : `📋 *Whitelisted:*\n${[...whitelist].join("\n")}`);
|
|
140
373
|
}
|
|
374
|
+
return reply("Usage:\n!whitelist add 234...\n!whitelist remove 234...\n!whitelist list\n!whitelist on\n!whitelist off");
|
|
141
375
|
}
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
return
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
throw new Error("Bot must be admin to change group settings");
|
|
154
|
-
}
|
|
155
|
-
throw e;
|
|
376
|
+
|
|
377
|
+
// Group admin commands
|
|
378
|
+
if (isGroup) {
|
|
379
|
+
const groupMeta = await sock.groupMetadata(from);
|
|
380
|
+
const isAdmin = groupMeta.participants.find(p => p.id === sender)?.admin != null;
|
|
381
|
+
|
|
382
|
+
if (lower.startsWith("!tag")) {
|
|
383
|
+
if (!isAdmin) return reply("Only group admins can use !tag.");
|
|
384
|
+
const tagMsg = text.slice(4).trim() || "📢 Attention everyone!";
|
|
385
|
+
const mentions = groupMeta.participants.map(p => p.id);
|
|
386
|
+
return sock.sendMessage(from, { text: tagMsg, mentions });
|
|
156
387
|
}
|
|
157
|
-
};
|
|
158
|
-
}
|
|
159
|
-
|
|
160
|
-
sock._ceaserPatched = true;
|
|
161
|
-
console.log("✅ Socket patched - all button types + ping media + group responding fixed");
|
|
162
|
-
return sock;
|
|
163
|
-
}
|
|
164
388
|
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
|
|
389
|
+
if (lower === "!kick") {
|
|
390
|
+
if (!isAdmin) return reply("Only group admins can use !kick.");
|
|
391
|
+
const quoted = msg.message?.extendedTextMessage?.contextInfo?.participant;
|
|
392
|
+
if (!quoted) return reply("Reply to a member's message with !kick to remove them.");
|
|
393
|
+
try {
|
|
394
|
+
await sock.groupParticipantsUpdate(from, [quoted], "remove");
|
|
395
|
+
return reply("✅ Member removed.");
|
|
396
|
+
} catch {
|
|
397
|
+
return reply("Couldn't remove — make sure I'm an admin in this group.");
|
|
398
|
+
}
|
|
399
|
+
}
|
|
169
400
|
|
|
170
|
-
|
|
171
|
-
if (
|
|
172
|
-
|
|
173
|
-
}
|
|
174
|
-
if (
|
|
175
|
-
|
|
176
|
-
}
|
|
401
|
+
if (lower.startsWith("!welcome")) {
|
|
402
|
+
if (!isAdmin) return reply("Only group admins can change this setting.");
|
|
403
|
+
const setting = lower.replace("!welcome", "").trim();
|
|
404
|
+
if (setting === "on") { welcomeSettings.set(from, true); return reply("✅ Welcome messages ON."); }
|
|
405
|
+
if (setting === "off") { welcomeSettings.set(from, false); return reply("✅ Welcome messages OFF."); }
|
|
406
|
+
return reply("Use: !welcome on or !welcome off");
|
|
407
|
+
}
|
|
408
|
+
}
|
|
177
409
|
|
|
178
|
-
//
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
if (lib.default) module.exports.default = makeWASocketFixed;
|
|
184
|
-
|
|
185
|
-
// Keep other exports
|
|
186
|
-
for (const key in lib) {
|
|
187
|
-
if (!(key in module.exports)) {
|
|
188
|
-
module.exports[key] = lib[key];
|
|
189
|
-
}
|
|
410
|
+
// Default auto-reply
|
|
411
|
+
if (!text.startsWith("!")) {
|
|
412
|
+
return reply(`Thanks for your message! This is *${BOT_NAME}* 🤖\nSend *!help* to see what I can do.`);
|
|
413
|
+
}
|
|
414
|
+
});
|
|
190
415
|
}
|
|
191
416
|
|
|
192
|
-
|
|
417
|
+
startBot();
|
package/package.json
CHANGED
|
@@ -1,12 +1,17 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "lordceaser-baileys",
|
|
3
|
-
"version": "2.0.
|
|
4
|
-
"description": "CEASER - Premium WhatsApp engine v2.0.
|
|
3
|
+
"version": "2.0.32",
|
|
4
|
+
"description": "CEASER - Premium WhatsApp engine v2.0.32 - Perfect 2.0.26 + All button types + ping media + group responding + Pterodactyl fixed",
|
|
5
5
|
"main": "index.js",
|
|
6
6
|
"type": "commonjs",
|
|
7
7
|
"license": "MIT",
|
|
8
8
|
"author": "Lord Ceaser Himself",
|
|
9
|
-
"keywords": [
|
|
9
|
+
"keywords": [
|
|
10
|
+
"whatsapp",
|
|
11
|
+
"baileys",
|
|
12
|
+
"ceaser",
|
|
13
|
+
"bot"
|
|
14
|
+
],
|
|
10
15
|
"dependencies": {
|
|
11
16
|
"@adiwajshing/keyed-db": "^0.2.4",
|
|
12
17
|
"@cacheable/node-cache": "^1.1.4",
|
|
@@ -25,5 +30,14 @@
|
|
|
25
30
|
"qrcode-terminal": "^0.12.0",
|
|
26
31
|
"lodash": "^4.17.21",
|
|
27
32
|
"mysql2": "^3.9.7"
|
|
28
|
-
}
|
|
29
|
-
|
|
33
|
+
},
|
|
34
|
+
"files": [
|
|
35
|
+
"lib/",
|
|
36
|
+
"WAProto/",
|
|
37
|
+
"WASignalGroup/",
|
|
38
|
+
"WABinary/",
|
|
39
|
+
"WAMessage/",
|
|
40
|
+
"index.js",
|
|
41
|
+
"README.md"
|
|
42
|
+
]
|
|
43
|
+
}
|