Skip to content

Commit b0aeabb

Browse files
authored
CELEBRATING 4 YEARS OF DEVELOPMENT
1 parent 0f7dfb3 commit b0aeabb

File tree

1 file changed

+76
-2
lines changed

1 file changed

+76
-2
lines changed

silva.js

Lines changed: 76 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -35,6 +35,9 @@ const tempDir = path.join(os.tmpdir(), 'silva-cache');
3535
const port = process.env.PORT || 25680;
3636
const pluginsDir = path.join(__dirname, 'plugins');
3737

38+
// ✅ Message Cache for Anti-Delete
39+
const messageCache = new Map();
40+
3841
// ✅ Message Logger Setup
3942
const logDir = path.join(__dirname, 'logs');
4043
if (!fs.existsSync(logDir)) fs.mkdirSync(logDir);
@@ -64,11 +67,20 @@ const globalContextInfo = {
6467
isForwarded: true,
6568
forwardedNewsletterMessageInfo: {
6669
newsletterJid: '120363200367779016@newsletter',
67-
newsletterName: '◢◤ Silva Tech Inc ◢◤',
70+
newsletterName: '◢◤ Silva Tech Nexus ◢◤',
6871
serverMessageId: 144
6972
}
7073
};
7174

75+
// ✅ Safe Get User JID
76+
function safeGetUserJid(sock) {
77+
try {
78+
return sock.user?.id || null;
79+
} catch {
80+
return null;
81+
}
82+
}
83+
7284
// ✅ Ensure Temp Directory Exists
7385
if (!fs.existsSync(tempDir)) fs.mkdirSync(tempDir, { recursive: true });
7486
setInterval(() => {
@@ -334,7 +346,69 @@ async function connectToWhatsApp() {
334346

335347
sock.ev.on('creds.update', saveCreds);
336348

337-
// Anti-delete handler
349+
// ✅ Cache messages for anti-delete
350+
sock.ev.on('messages.upsert', ({ messages }) => {
351+
if (!Array.isArray(messages)) return;
352+
353+
for (const m of messages) {
354+
if (!m.message || !m.key.id) continue;
355+
356+
const cacheKey = `${m.key.remoteJid}-${m.key.id}`;
357+
messageCache.set(cacheKey, {
358+
message: m.message,
359+
timestamp: Date.now()
360+
});
361+
}
362+
363+
// Clean old cache entries (older than 1 hour)
364+
const now = Date.now();
365+
for (const [key, value] of messageCache.entries()) {
366+
if (now - value.timestamp > 60 * 60 * 1000) { // 1 hour
367+
messageCache.delete(key);
368+
}
369+
}
370+
});
371+
372+
// ✅ Anti-delete handler (messages.update)
373+
sock.ev.on("messages.update", async (updates) => {
374+
for (const { key, update } of updates) {
375+
if (key.remoteJid === "status@broadcast") continue;
376+
if (update?.message === null && !key.fromMe) {
377+
const cacheKey = `${key.remoteJid}-${key.id}`;
378+
const original = messageCache.get(cacheKey);
379+
const owner = safeGetUserJid(sock);
380+
381+
if (!original?.message || !owner) continue;
382+
383+
sock.sendMessage(owner, {
384+
text: `🚨 *Anti-Delete* — Message recovered from ${key.participant || key.remoteJid}`,
385+
contextInfo: globalContextInfo
386+
}).catch(() => {});
387+
388+
const msgObj = original.message;
389+
const mType = Object.keys(msgObj)[0];
390+
391+
try {
392+
if (["conversation", "extendedTextMessage"].includes(mType)) {
393+
const text = msgObj.conversation || msgObj.extendedTextMessage?.text;
394+
await sock.sendMessage(owner, { text, contextInfo: globalContextInfo });
395+
} else if (["imageMessage", "videoMessage", "audioMessage", "stickerMessage", "documentMessage"].includes(mType)) {
396+
const stream = await downloadContentFromMessage(msgObj[mType], mType.replace("Message", ""));
397+
let buffer = Buffer.from([]);
398+
for await (const chunk of stream) buffer = Buffer.concat([buffer, chunk]);
399+
const field = mType.replace("Message", "");
400+
const payload = { [field]: buffer, contextInfo: globalContextInfo };
401+
if (msgObj[mType]?.caption) payload.caption = msgObj[mType].caption;
402+
await sock.sendMessage(owner, payload);
403+
}
404+
} catch (err) {
405+
logMessage("DEBUG", `Recovery failed: ${err.message}`);
406+
}
407+
}
408+
}
409+
});
410+
411+
// Anti-delete handler (messages.delete - existing)
338412
sock.ev.on('messages.delete', async (item) => {
339413
try {
340414
logMessage('DEBUG', 'messages.delete triggered');

0 commit comments

Comments
 (0)