Spaces:
Running
Running
| import { createRequire } from 'module'; | |
| const require = createRequire(import.meta.url); | |
| const baileys = require('@whiskeysockets/baileys'); | |
| const makeWASocket = baileys.default || baileys; | |
| const { | |
| useMultiFileAuthState, | |
| DisconnectReason, | |
| fetchLatestBaileysVersion, | |
| Browsers, | |
| makeCacheableSignalKeyStore | |
| } = baileys; | |
| import { Boom } from '@hapi/boom'; | |
| import pino from 'pino'; | |
| import express from 'express'; | |
| import fs from 'fs-extra'; | |
| import QRCode from 'qrcode'; | |
| import admin from "firebase-admin"; | |
| const app = express(); | |
| const logger = pino({ level: 'silent' }); | |
| // --- FIREBASE INITIALIZATION --- | |
| const firebaseKeyPath = "./firebase-key.json"; | |
| const serviceAccount = JSON.parse(fs.readFileSync(firebaseKeyPath, "utf-8")); | |
| if (admin.apps.length === 0) { | |
| admin.initializeApp({ | |
| credential: admin.credential.cert(serviceAccount), | |
| databaseURL: "https://fixmerah-db-default-rtdb.asia-southeast1.firebasedatabase.app" | |
| }); | |
| } | |
| const db = admin.database(); | |
| // --- DATA CONFIG & WHITELIST --- | |
| const WHITELIST = [ | |
| "4915511371360@s.whatsapp.net", "628815163761@s.whatsapp.net", | |
| "213664469870@s.whatsapp.net", "6285878003200@s.whatsapp.net", | |
| "62882008454236@s.whatsapp.net", "6283831201977@s.whatsapp.net", | |
| "4915511232477@s.whatsapp.net" | |
| ]; | |
| const localTracker = {}; | |
| let waQrBase64 = ""; | |
| let waConnected = false; | |
| let isStarting = false; | |
| const sleep = (ms) => new Promise(resolve => setTimeout(resolve, ms)); | |
| async function startBot() { | |
| if (isStarting) return; | |
| isStarting = true; | |
| const authFolder = './session_wa'; | |
| await fs.ensureDir(authFolder); | |
| const credsPath = `${authFolder}/creds.json`; | |
| // 1. SYNC SESSION CLOUD | |
| try { | |
| const cloudSnapshot = await db.ref("sessions/scyllora_v9").once("value"); | |
| if (cloudSnapshot.exists()) { | |
| await fs.writeJSON(credsPath, cloudSnapshot.val()); | |
| } | |
| } catch (e) { console.log("Firebase Sync Error") } | |
| const { state, saveCreds } = await useMultiFileAuthState(authFolder); | |
| const { version } = await fetchLatestBaileysVersion(); | |
| const sock = makeWASocket({ | |
| version, | |
| auth: { | |
| creds: state.creds, | |
| keys: makeCacheableSignalKeyStore(state.keys, logger), | |
| }, | |
| logger, | |
| browser: Browsers.ubuntu('Chrome'), | |
| syncFullHistory: false, | |
| markOnlineOnConnect: false, | |
| shouldSyncHistoryMessage: () => false, | |
| maxMsgRetryCount: 1, | |
| multicast: true | |
| }); | |
| sock.ev.on('creds.update', async () => { | |
| await saveCreds(); | |
| const currentCreds = await fs.readJSON(credsPath); | |
| db.ref("sessions/scyllora_v9").set(currentCreds).catch(() => {}); | |
| }); | |
| // --- SHADOW GUARD ENGINE (INSTANT GODSPEED MODE) --- | |
| sock.ev.on('group-participants.update', async (update) => { | |
| const { id, participants, action, author } = update; | |
| const botId = sock.user.id.split(':')[0] + '@s.whatsapp.net'; | |
| // Bypass: Whitelist, Bot sendiri, atau aksi tanpa author | |
| if (!author || WHITELIST.includes(author) || author === botId) return; | |
| try { | |
| // 1. INSTANT ACTION UNTUK TARGET WHITELIST | |
| const isTargetWhitelist = participants.some(p => WHITELIST.includes(p)); | |
| if (isTargetWhitelist) { | |
| // Eksekusi Paralel (Tanpa nunggu satu-satu): Demote Pelaku & Restore Korban | |
| Promise.all([ | |
| sock.groupParticipantsUpdate(id, [author], "demote"), | |
| action === 'remove' | |
| ? sock.groupParticipantsUpdate(id, participants, "add") | |
| : sock.groupParticipantsUpdate(id, participants, "promote") | |
| ]).catch(() => {}); | |
| // Jika aksi kick pada Whitelist, kembalikan status Admin setelah add | |
| if (action === 'remove') { | |
| await sleep(2500); // Jeda minimal agar sistem WA tidak reject | |
| await sock.groupParticipantsUpdate(id, participants, "promote").catch(() => {}); | |
| } | |
| return; | |
| } | |
| // 2. DETEKSI MASSAL (NON-WHITELIST) | |
| const trackerId = `${id}_${author}`; | |
| if (!localTracker[trackerId]) localTracker[trackerId] = { count: 0 }; | |
| if (action === 'remove' || action === 'demote') { | |
| localTracker[trackerId].count += participants.length; | |
| // Threshold: Jika menindak 2 orang sekaligus -> Copot Jabatan | |
| if (localTracker[trackerId].count >= 2) { | |
| await sock.groupParticipantsUpdate(id, [author], "demote").catch(() => {}); | |
| localTracker[trackerId].count = 0; // Reset tracker pelaku | |
| } | |
| } | |
| // Backup tracker ke Firebase secara asinkron | |
| db.ref(`tracker/${id.split('@')[0]}/${author.split('@')[0]}`).set({ | |
| lastAction: action, | |
| totalViolations: localTracker[trackerId].count, | |
| timestamp: Date.now() | |
| }).catch(() => {}); | |
| } catch (e) {} | |
| }); | |
| // Ghost Mode: Abaikan semua pesan masuk demi performa | |
| sock.ev.on('messages.upsert', () => { return; }); | |
| sock.ev.on('connection.update', async (up) => { | |
| const { connection, lastDisconnect, qr } = up; | |
| if (qr) waQrBase64 = await QRCode.toDataURL(qr); | |
| if (connection === 'open') { | |
| waConnected = true; waQrBase64 = ""; isStarting = false; | |
| console.log("🚀 Scyllora GhostSpeed Online!"); | |
| } | |
| if (connection === 'close') { | |
| waConnected = false; isStarting = false; | |
| const reason = new Boom(lastDisconnect?.error)?.output?.statusCode; | |
| if (reason !== DisconnectReason.loggedOut) { | |
| setTimeout(() => startBot(), 3000); | |
| } else { | |
| await fs.remove(authFolder); | |
| await db.ref("sessions/scyllora_v9").remove(); | |
| setTimeout(() => startBot(), 3000); | |
| } | |
| } | |
| }); | |
| } | |
| // --- WEB PANEL --- | |
| app.get('/', (req, res) => { | |
| res.send(`<html><body style="background:#000;color:#0f0;text-align:center;padding:50px;font-family:monospace;"> | |
| <h1 style="text-shadow: 0 0 10px #0f0;">SCYLLORA V9 [GHOSTSPEED]</h1> | |
| <div style="border:1px solid #0f0; display:inline-block; padding:20px; box-shadow: 0 0 20px rgba(0,255,0,0.2);"> | |
| ${waConnected ? '<h2 style="color:#0f0;">SYSTEM ACTIVE</h2><p style="color:#666;">Mode: Shadow Guard | Status: Stealth</p>' : (waQrBase64 ? `<p>Scan QR to Link</p><img src="${waQrBase64}" style="border: 5px solid #fff;">` : '<h2>INITIALIZING...</h2>')} | |
| </div> | |
| <script>setTimeout(()=>location.reload(), 10000)</script></body></html>`); | |
| }); | |
| app.listen(7860, '0.0.0.0', () => startBot()); | |