| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584 |
- process.env['NODE_TLS_REJECT_UNAUTHORIZED'] = '1'
- import './config.js'
- import { createRequire } from 'module'
- import path, { join } from 'path'
- import {fileURLToPath, pathToFileURL} from 'url'
- import { platform } from 'process'
- import * as ws from 'ws'
- import fs, { watchFile, unwatchFile, writeFileSync, readdirSync, statSync, unlinkSync, existsSync, readFileSync, copyFileSync, watch, rmSync, readdir, stat, mkdirSync, rename } from 'fs';
- import { promises as fsPromises } from 'fs';
- import yargs from 'yargs'
- import { spawn } from 'child_process'
- import lodash from 'lodash'
- import chalk from 'chalk'
- import syntaxerror from 'syntax-error'
- import { format } from 'util'
- import pino from 'pino'
- import Pino from 'pino'
- import { Boom } from '@hapi/boom'
- import { makeWASocket, protoType, serialize } from './lib/simple.js'
- import {Low, JSONFile} from 'lowdb'
- import PQueue from 'p-queue'
- import store from './lib/store.js'
- import readline from 'readline'
- import NodeCache from 'node-cache'
- import { startSubBots } from './plugins/jadibot.js';
- import pkg from 'google-libphonenumber'
- const { PhoneNumberUtil } = pkg
- const phoneUtil = PhoneNumberUtil.getInstance()
- const { makeInMemoryStore, DisconnectReason, useMultiFileAuthState, MessageRetryMap, fetchLatestBaileysVersion, makeCacheableSignalKeyStore } = await import('@whiskeysockets/baileys')
- const { CONNECTING } = ws
- const { chain } = lodash
- const PORT = process.env.PORT || process.env.SERVER_PORT || 3000
- protoType()
- serialize()
- global.__filename = function filename(pathURL = import.meta.url, rmPrefix = platform !== 'win32') {
- return rmPrefix ? /file:\/\/\//.test(pathURL) ? fileURLToPath(pathURL) : pathURL : pathToFileURL(pathURL).toString();
- }; global.__dirname = function dirname(pathURL) {
- return path.dirname(global.__filename(pathURL, true));
- }; global.__require = function require(dir = import.meta.url) {
- return createRequire(dir);
- };
- //global.API = (name, path = '/', query = {}, apikeyqueryname) => (name in global.APIs ? global.APIs[name] : name) + path + (query || apikeyqueryname ? '?' + new URLSearchParams(Object.entries({...query, ...(apikeyqueryname ? {[apikeyqueryname]: global.APIKeys[name in global.APIs ? global.APIs[name] : name]} : {})})) : '')
- global.timestamp = { start: new Date }
- const __dirname = global.__dirname(import.meta.url);
- //const __dirname = join(fileURLToPath(import.meta.url), '..');
- global.opts = new Object(yargs(process.argv.slice(2)).exitProcess(false).parse());
- //global.prefix = new RegExp('^[' + (opts['prefix'] || '*/i!#$%+£¢€¥^°=¶∆×÷π√✓©®&.\\-.@').replace(/[|\\{}()[\]^$+*.\-\^]/g, '\\$&') + ']')
- //news
- const databasePath = path.join(__dirname, 'database');
- if (!fs.existsSync(databasePath)) fs.mkdirSync(databasePath);
- const paths = {
- users: path.join(databasePath, 'users'),
- chats: path.join(databasePath, 'chats'),
- settings: path.join(databasePath, 'settings'),
- msgs: path.join(databasePath, 'msgs'),
- sticker: path.join(databasePath, 'sticker'),
- stats: path.join(databasePath, 'stats'),
- };
- Object.values(paths).forEach(dir => {
- if (!fs.existsSync(dir)) fs.mkdirSync(dir);
- });
- const queue = new PQueue({ concurrency: 5 });
- global.db = {
- data: {
- users: {},
- chats: {},
- settings: {},
- msgs: {},
- sticker: {},
- stats: {},
- },
- };
- function getFilePath(category, id) {
- return path.join(paths[category], `${id}.json`);
- }
- async function readFile(category, id) {
- const filePath = getFilePath(category, id);
- const db = new Low(new JSONFile(filePath));
- await db.read();
- db.data = db.data || {};
- return db.data;
- }
- async function writeFile(category, id, data) {
- const filePath = getFilePath(category, id);
- const db = new Low(new JSONFile(filePath));
- await db.read();
- db.data = { ...db.data, ...data };
- await db.write();
- }
- global.db.readData = async function (category, id) {
- if (!global.db.data[category][id]) {
- const data = await queue.add(() => readFile(category, id));
- global.db.data[category][id] = data;
- }
- return global.db.data[category][id];
- };
- global.db.writeData = async function (category, id, data) {
- global.db.data[category][id] = { ...global.db.data[category][id], ...data };
- await queue.add(() => writeFile(category, id, global.db.data[category][id]));
- };
- global.db.loadDatabase = async function () {
- const categories = ['users', 'chats', 'settings', 'msgs', 'sticker', 'stats'];
- const loadPromises = [];
- for (const category of categories) {
- const files = fs.readdirSync(paths[category]);
- for (const file of files) {
- const id = path.basename(file, '.json');
- if (category === 'users' && (id.includes('@newsletter') || id.includes('lid'))) continue;
- if (category === 'chats' && id.includes('@newsletter')) continue;
- loadPromises.push(queue.add(() => readFile(category, id)).then(data => {
- global.db.data[category][id] = data;
- }).catch(err => console.error(`Error cargando ${category}/${id}:`, err))
- );
- }}
- await Promise.all(loadPromises);
- console.log('Base de datos cargada');
- };
- global.db.save = async function () {
- const categories = ['users', 'chats', 'settings', 'msgs', 'sticker', 'stats'];
- for (const category of categories) {
- for (const [id, data] of Object.entries(global.db.data[category])) {
- if (Object.keys(data).length > 0) {
- if (category === 'users' && (id.includes('@newsletter') || id.includes('lid'))) continue;
- if (category === 'chats' && id.includes('@newsletter')) continue;
- await queue.add(() => writeFile(category, id, data))
- }}}};
- global.db.loadDatabase().then(() => {
- }).catch(err => console.error(err));
- /*global.db = new Low(/https?:\/\//.test(opts['db'] || '') ? new cloudDBAdapter(opts['db']) : new JSONFile('database.json'))
- global.DATABASE = global.db;
- global.loadDatabase = async function loadDatabase() {
- if (global.db.READ) {
- return new Promise((resolve) => setInterval(async function() {
- if (!global.db.READ) {
- clearInterval(this);
- resolve(global.db.data == null ? global.loadDatabase() : global.db.data);
- }}, 1 * 1000));
- }
- if (global.db.data !== null) return;
- global.db.READ = true;
- await global.db.read().catch(console.error);
- global.db.READ = null;
- global.db.data = {
- users: {},
- chats: {},
- stats: {},
- msgs: {},
- sticker: {},
- settings: {},
- ...(global.db.data || {}),
- };
- global.db.chain = chain(global.db.data);
- };
- loadDatabase();*/
- //if (global.conns instanceof Array) {console.log('Conexiones ya inicializadas...');} else {global.conns = [];}
- /* ------------------------------------------------*/
- global.creds = 'creds.json'
- global.authFile = `BotSession`
- global.authFileJB = 'jadibts'
- global.rutaBot = join(__dirname, authFile)
- global.rutaJadiBot = join(__dirname, authFileJB)
- const respaldoDir = join(__dirname, 'BackupSession');
- const credsFile = join(global.rutaBot, global.creds);
- const backupFile = join(respaldoDir, global.creds);
- if (!fs.existsSync(rutaJadiBot)) {
- fs.mkdirSync(rutaJadiBot)}
- if (!fs.existsSync(respaldoDir)) fs.mkdirSync(respaldoDir);
- const {state, saveState, saveCreds} = await useMultiFileAuthState(global.authFile)
- const msgRetryCounterMap = new Map();
- const msgRetryCounterCache = new NodeCache({ stdTTL: 0, checkperiod: 0 });
- const userDevicesCache = new NodeCache({ stdTTL: 0, checkperiod: 0 });
- const {version} = await fetchLatestBaileysVersion()
- let phoneNumber = global.botNumberCode
- const methodCodeQR = process.argv.includes("qr")
- const methodCode = !!phoneNumber || process.argv.includes("code")
- const MethodMobile = process.argv.includes("mobile")
- let rl = readline.createInterface({
- input: process.stdin,
- output: process.stdout,
- terminal: true,
- })
- const question = (texto) => {
- rl.clearLine(rl.input, 0)
- return new Promise((resolver) => {
- rl.question(texto, (respuesta) => {
- rl.clearLine(rl.input, 0)
- resolver(respuesta.trim())
- })})
- }
- let opcion
- if (methodCodeQR) {
- opcion = '1'
- }
- if (!methodCodeQR && !methodCode && !fs.existsSync(`./${authFile}/creds.json`)) {
- do {
- let lineM = '⋯ ⋯ ⋯ ⋯ ⋯ ⋯ ⋯ ⋯ ⋯ ⋯ ⋯ 》'
- opcion = await question(`╭${lineM}
- ┊ ${chalk.blueBright('╭┅┅┅┅┅┅┅┅┅┅┅┅┅┅┅')}
- ┊ ${chalk.blueBright('┊')} ${chalk.blue.bgBlue.bold.cyan('MÉTODO DE VINCULACIÓN')}
- ┊ ${chalk.blueBright('╰┅┅┅┅┅┅┅┅┅┅┅┅┅┅┅')}
- ┊ ${chalk.blueBright('╭┅┅┅┅┅┅┅┅┅┅┅┅┅┅┅')}
- ┊ ${chalk.blueBright('┊')} ${chalk.green.bgMagenta.bold.yellow('¿CÓMO DESEA CONECTARSE?')}
- ┊ ${chalk.blueBright('┊')} ${chalk.bold.redBright('⇢ Opción 1:')} ${chalk.greenBright('Código QR.')}
- ┊ ${chalk.blueBright('┊')} ${chalk.bold.redBright('⇢ Opción 2:')} ${chalk.greenBright('Código de 8 digitos.')}
- ┊ ${chalk.blueBright('╰┅┅┅┅┅┅┅┅┅┅┅┅┅┅┅')}
- ┊ ${chalk.blueBright('╭┅┅┅┅┅┅┅┅┅┅┅┅┅┅┅')}
- ┊ ${chalk.blueBright('┊')} ${chalk.italic.magenta('Escriba sólo el número de')}
- ┊ ${chalk.blueBright('┊')} ${chalk.italic.magenta('la opción para conectarse.')}
- ┊ ${chalk.blueBright('╰┅┅┅┅┅┅┅┅┅┅┅┅┅┅┅')}
- ╰${lineM}\n${chalk.bold.magentaBright('---> ')}`)
- if (!/^[1-2]$/.test(opcion)) {
- console.log(chalk.bold.redBright(`NO SE PERMITE NÚMEROS QUE NO SEAN ${chalk.bold.greenBright("1")} O ${chalk.bold.greenBright("2")}, TAMPOCO LETRAS O SÍMBOLOS ESPECIALES. ${chalk.bold.yellowBright("CONSEJO: COPIE EL NÚMERO DE LA OPCIÓN Y PÉGUELO EN LA CONSOLA.")}`))
- }} while (opcion !== '1' && opcion !== '2' || fs.existsSync(`./${authFile}/creds.json`))
- }
- console.info = () => {}
- /*const connectionOptions = {
- logger: pino({ level: 'silent' }),
- printQRInTerminal: opcion == '1' ? true : methodCodeQR ? true : false,
- mobile: MethodMobile,
- browser: opcion == '1' ? ['KANTU-MD', 'Edge', '20.0.04'] : methodCodeQR ? ['KANTU-MD', 'Edge', '20.0.04'] : ["Ubuntu", "Chrome", "20.0.04"],
- auth: {
- creds: state.creds,
- keys: makeCacheableSignalKeyStore(state.keys, Pino({ level: "fatal" }).child({ level: "fatal" })),
- },
- markOnlineOnConnect: false,
- generateHighQualityLinkPreview: true,
- syncFullHistory: false,
- getMessage: async (key) => {
- try {
- let jid = jidNormalizedUser(key.remoteJid);
- let msg = await store.loadMessage(jid, key.id);
- return msg?.message || "";
- } catch (error) {
- return "";
- }},
- msgRetryCounterCache: msgRetryCounterCache || new Map(),
- userDevicesCache: userDevicesCache || new Map(),
- //msgRetryCounterMap,
- defaultQueryTimeoutMs: undefined,
- cachedGroupMetadata: (jid) => global.conn.chats[jid] ?? {},
- version: [2, 3000, 1015901307],
- };*/
- const connectionOptions = {
- logger: pino({ level: 'silent' }),
- printQRInTerminal: opcion == '1' ? true : methodCodeQR ? true : false,
- mobile: MethodMobile,
- auth: {
- creds: state.creds,
- keys: makeCacheableSignalKeyStore(state.keys, Pino({ level: "fatal" }).child({ level: "fatal" })),
- },
- browser: opcion == '1' ? ['KantuBot', 'Edge', '20.0.04'] : methodCodeQR ? ['KantuBot', 'Edge', '20.0.04'] : ["Ubuntu", "Chrome", "20.0.04"],
- version: version,
- generateHighQualityLinkPreview: true
- };
-
- global.conn = makeWASocket(connectionOptions)
- if (!fs.existsSync(`./${authFile}/creds.json`)) {
- if (opcion === '2' || methodCode) {
- opcion = '2'
- if (!conn.authState.creds.registered) {
- let addNumber
- if (!!phoneNumber) {
- addNumber = phoneNumber.replace(/[^0-9]/g, '')
- } else {
- do {
- phoneNumber = await question(chalk.bgBlack(chalk.bold.greenBright("\n\n✳️ Escriba su número\n\nEjemplo: 5491168xxxx\n\n\n\n")))
- phoneNumber = phoneNumber.replace(/\D/g,'')
- if (!phoneNumber.startsWith('+')) {
- phoneNumber = `+${phoneNumber}`
- }
- } while (!await isValidPhoneNumber(phoneNumber))
- rl.close()
- addNumber = phoneNumber.replace(/\D/g, '')
- setTimeout(async () => {
- let codeBot = await conn.requestPairingCode(addNumber)
- codeBot = codeBot?.match(/.{1,4}/g)?.join("-") || codeBot
- console.log(chalk.bold.white(chalk.bgMagenta(`CÓDIGO DE VINCULACIÓN:`)), chalk.bold.white(chalk.white(codeBot)))
- }, 2000)
- }}}
- }
- conn.isInit = false
- conn.well = false
- if (!opts['test']) {
- setInterval(async () => {
- if (global.db.data) await global.db.save();
- if (opts['autocleartmp'] && (global.support || {}).find) {
- const tmpDirs = [os.tmpdir(), 'tmp', "jadibts"];
- tmpDirs.forEach(dir => {
- cp.spawn('find', [dir, '-amin', '2', '-type', 'f', '-delete']);
- })}}, 30 * 1000)}
- if (opts['server']) (await import('./server.js')).default(global.conn, PORT)
- //respaldo de la sesión
- function manageCredentials(action) {
- const credsFile = join(global.rutaBot, global.creds);
- const backupFile = join(respaldoDir, global.creds);
- if (action === 'backup' && existsSync(credsFile)) {
- copyFileSync(credsFile, backupFile);
- console.log(`[✅] Respaldo creado en ${backupFile}`);
- } else if (action === 'restore' && existsSync(backupFile)) {
- copyFileSync(backupFile, credsFile);
- console.log(`[✅] creds.json restaurado desde el respaldo`);
- }
- }
- setInterval(() => manageCredentials('backup'), 5 * 60 * 1000);
- //tmp
- async function cleanUp(type) {
- const targets = {
- tmp: join(__dirname, 'tmp'),
- session: './BotSession',
- subbots: './jadibts/'
- };
- if (type === 'tmp') {
- const files = readdirSync(targets.tmp);
- files.forEach(file => unlinkSync(join(targets.tmp, file)));
- console.log(chalk.cyan(`┏━━━━━━⪻♻️ AUTO-CLEAR 🗑️⪼━━━━━━•\n┃→ ARCHIVOS DE LA CARPETA TMP ELIMINADOS\n┗━━━━━━━━━━━━━━━━━━━━━━━━━━━•`));
- } else if (type === 'session' || type === 'subbots') {
- const dir = targets[type];
- const files = readdirSync(dir).filter(f => f.startsWith('pre-key-'));
- const threshold = Date.now() - (24 * 60 * 60 * 1000);
- for (const file of files) {
- const filePath = join(dir, file);
- const { mtimeMs } = statSync(filePath);
- if (mtimeMs < threshold) await unlinkSync(filePath);
- }
- console.log(chalk.bold.cyanBright(`\n╭» 🔵 ${type} 🔵\n│→ SESIONES NO ESENCIALES ELIMINADAS\n╰― ― ― ― ― ― ― ― ― ― ― ― ― ― ― ― ― ― ― 🗑️♻️`));
- }}
- setInterval(() => cleanUp('tmp'), 1000 * 60 * 3);
- setInterval(() => { cleanUp('session'); cleanUp('subbots'); }, 1000 * 60 * 10);
- async function connectionUpdate(update) {
- const {connection, lastDisconnect, isNewLogin} = update
- global.stopped = connection
- if (isNewLogin) conn.isInit = true
- const code = lastDisconnect?.error?.output?.statusCode || lastDisconnect?.error?.output?.payload?.statusCode
- if (code && code !== DisconnectReason.loggedOut && conn?.ws.socket == null) {
- await global.reloadHandler(true).catch(console.error)
- //console.log(await global.reloadHandler(true).catch(console.error));
- global.timestamp.connect = new Date
- }
- if (global.db.data == null) loadDatabase()
- if (update.qr != 0 && update.qr != undefined || methodCodeQR) {
- if (opcion == '1' || methodCodeQR) {
- console.log(chalk.cyan('✅ ESCANEA EL CÓDIGO QR EXPIRA EN 45 SEGUNDOS ✅.'))
- }}
- if (connection == 'open') {
- console.log(chalk.bold.greenBright('\n▣─────────────────────────────···\n│\n│❧ 𝙲𝙾𝙽𝙴𝙲𝚃𝙰𝙳𝙾 𝙲𝙾𝚁𝚁𝙴𝙲𝚃𝙰𝙼𝙴𝙽𝚃𝙴 𝙰𝙻 𝚆𝙷𝙰𝚃𝚂𝙰𝙿𝙿 ✅\n│\n▣─────────────────────────────···'))
- await joinChannels(conn)
- }
- let reason = new Boom(lastDisconnect?.error)?.output?.statusCode
- if (connection === 'close') {
- if (reason === DisconnectReason.badSession) {
- conn.logger.error(`[ ⚠ ] Sesión incorrecta, por favor elimina la carpeta ${global.authFile} y escanea nuevamente.`);
- } else if (reason === DisconnectReason.connectionClosed) {
- conn.logger.warn(`[ ⚠ ] Conexión cerrada, reconectando...`);
- manageCredentials('restore');
- await global.reloadHandler(true).catch(console.error)
- } else if (reason === DisconnectReason.connectionLost) {
- conn.logger.warn(`[ ⚠ ] Conexión perdida con el servidor, reconectando...`);
- manageCredentials('restore');
- await global.reloadHandler(true).catch(console.error)
- } else if (reason === DisconnectReason.connectionReplaced) {
- conn.logger.error(`[ ⚠ ] Conexión reemplazada, se ha abierto otra nueva sesión. Por favor, cierra la sesión actual primero.`);
- } else if (reason === DisconnectReason.loggedOut) {
- conn.logger.error(`[ ⚠ ] Conexion cerrada, por favor elimina la carpeta ${global.authFile} y escanea nuevamente.`);
- await global.reloadHandler(true).catch(console.error)
- } else if (reason === DisconnectReason.restartRequired) {
- conn.logger.info(`[ ⚠ ] Reinicio necesario, reinicie el servidor si presenta algún problema.`);
- await global.reloadHandler(true).catch(console.error)
- } else if (reason === DisconnectReason.timedOut) {
- conn.logger.warn(`[ ⚠ ] Tiempo de conexión agotado, reconectando...`);
- await global.reloadHandler(true).catch(console.error) //process.send('reset')
- } else {
- conn.logger.warn(`[ ⚠ ] Razón de desconexión desconocida. ${reason || ''}: ${connection || ''}`);
- }}}
- process.on('uncaughtException', console.error);
- let isInit = true;
- let handler = await import('./handler.js');
- global.reloadHandler = async function(restatConn) {
- try {
- const Handler = await import(`./handler.js?update=${Date.now()}`).catch(console.error);
- if (Object.keys(Handler || {}).length) handler = Handler;
- } catch (e) {
- console.error(e);
- }
- if (restatConn) {
- const oldChats = global.conn.chats;
- try {
- global.conn.ws.close();
- } catch { }
- conn.ev.removeAllListeners();
- global.conn = makeWASocket(connectionOptions, {chats: oldChats});
- isInit = true;
- }
- if (!isInit) {
- conn.ev.off('messages.upsert', conn.handler);
- conn.ev.off('group-participants.update', conn.participantsUpdate);
- conn.ev.off('groups.update', conn.groupsUpdate);
- conn.ev.off('message.delete', conn.onDelete);
- conn.ev.off('call', conn.onCall);
- conn.ev.off('connection.update', conn.connectionUpdate);
- conn.ev.off('creds.update', conn.credsUpdate);
- }
- conn.welcome = 'HOLAA!! @user\n\n『Bienvenido A *@subject*』\n\n_`Recuerda leer las reglas del grupo para no tener ningun problema 🐣`_'
- conn.bye = 'Bueno, se fue @user 👋\n\nQue lo atropelle un tren 👻`'
- conn.spromote = 'Hey @user ya forma parte de staff 👑'
- conn.sdemote = '@user ya no eres admins'
- conn.sDesc = 'La descripción ha sido cambiada a \n@desc'
- conn.sSubject = 'El nombre del grupo ha sido cambiado a \n@group'
- conn.sIcon = 'El icono del grupo ha sido cambiado'
- conn.sRevoke = 'El enlace del grupo ha sido cambiado a \n@revoke'
- conn.handler = handler.handler.bind(global.conn);
- conn.participantsUpdate = handler.participantsUpdate.bind(global.conn);
- conn.groupsUpdate = handler.groupsUpdate.bind(global.conn);
- conn.onDelete = handler.deleteUpdate.bind(global.conn);
- conn.onCall = handler.callUpdate.bind(global.conn);
- conn.connectionUpdate = connectionUpdate.bind(global.conn);
- conn.credsUpdate = saveCreds.bind(global.conn, true);
- conn.ev.on('messages.upsert', conn.handler);
- conn.ev.on('group-participants.update', conn.participantsUpdate);
- conn.ev.on('groups.update', conn.groupsUpdate);
- conn.ev.on('message.delete', conn.onDelete);
- conn.ev.on('call', conn.onCall);
- conn.ev.on('connection.update', conn.connectionUpdate);
- conn.ev.on('creds.update', conn.credsUpdate);
- isInit = false
- return true
- }
- //Arranque nativo para subbots
- await startSubBots();
- /*const pluginFolder = global.__dirname(join(__dirname, './plugins/index'));
- const pluginFilter = (filename) => /\.js$/.test(filename);
- global.plugins = {};
- async function filesInit() {
- for (const filename of readdirSync(pluginFolder).filter(pluginFilter)) {
- try {
- const file = global.__filename(join(pluginFolder, filename));
- const module = await import(file);
- global.plugins[filename] = module.default || module;
- } catch (e) {
- conn.logger.error(e);
- delete global.plugins[filename];
- }}}
- filesInit().then((_) => Object.keys(global.plugins)).catch(console.error)*/
- const pluginFolder = global.__dirname(join(__dirname, './plugins/index'))
- const pluginFilter = (filename) => /\.js$/.test(filename)
- global.plugins = {}
- async function filesInit() {
- for (const filename of readdirSync(pluginFolder).filter(pluginFilter)) {
- try {
- const file = global.__filename(join(pluginFolder, filename))
- const module = await import(file)
- global.plugins[filename] = module.default || module
- } catch (e) {
- conn.logger.error(e)
- delete global.plugins[filename]
- }}}
- filesInit().then((_) => Object.keys(global.plugins)).catch(console.error)
- global.reload = async (_ev, filename) => {
- if (pluginFilter(filename)) {
- const dir = global.__filename(join(pluginFolder, filename), true)
- if (filename in global.plugins) {
- if (existsSync(dir)) conn.logger.info(` SE ACTULIZADO - '${filename}' CON ÉXITO`)
- else {
- conn.logger.warn(`SE ELIMINO UN ARCHIVO : '${filename}'`)
- return delete global.plugins[filename];
- }
- } else conn.logger.info(`SE DETECTO UN NUEVO PLUGINS : '${filename}'`)
- const err = syntaxerror(readFileSync(dir), filename, {
- sourceType: 'module',
- allowAwaitOutsideFunction: true,
- });
- if (err) conn.logger.error(`SE DETECTO UN ERROR DE SINTAXIS | SYNTAX ERROR WHILE LOADING '${filename}'\n${format(err)}`);
- else {
- try {
- const module = (await import(`${global.__filename(dir)}?update=${Date.now()}`));
- global.plugins[filename] = module.default || module;
- } catch (e) {
- conn.logger.error(`HAY UN ERROR REQUIERE EL PLUGINS '${filename}\n${format(e)}'`);
- } finally {
- global.plugins = Object.fromEntries(Object.entries(global.plugins).sort(([a], [b]) => a.localeCompare(b)));
- }}}};
- Object.freeze(global.reload);
- watch(pluginFolder, global.reload);
- await global.reloadHandler();
- async function _quickTest() {
- const test = await Promise.all([
- spawn('ffmpeg'),
- spawn('ffprobe'),
- spawn('ffmpeg', ['-hide_banner', '-loglevel', 'error', '-filter_complex', 'color', '-frames:v', '1', '-f', 'webp', '-']),
- spawn('convert'),
- spawn('magick'),
- spawn('gm'),
- spawn('find', ['--version']),
- ].map((p) => {
- return Promise.race([
- new Promise((resolve) => {
- p.on('close', (code) => {
- resolve(code !== 127);
- });
- }),
- new Promise((resolve) => {
- p.on('error', (_) => resolve(false));
- })]);
- }));
- const [ffmpeg, ffprobe, ffmpegWebp, convert, magick, gm, find] = test;
- const s = global.support = {ffmpeg, ffprobe, ffmpegWebp, convert, magick, gm, find};
- Object.freeze(global.support);
- }
- function redefineConsoleMethod(methodName, filterStrings) {
- const originalConsoleMethod = console[methodName]
- console[methodName] = function() {
- const message = arguments[0]
- if (typeof message === 'string' && filterStrings.some(filterString => message.includes(atob(filterString)))) {
- arguments[0] = ""
- }
- originalConsoleMethod.apply(console, arguments)
- }}
- _quickTest().then(() => conn.logger.info('Ƈᴀʀɢᴀɴᴅᴏ....\n'))
- .catch(console.error)
- async function isValidPhoneNumber(number) {
- try {
- number = number.replace(/\s+/g, '')
- // Si el número empieza con '+521' o '+52 1', quitar el '1'
- if (number.startsWith('+521')) {
- number = number.replace('+521', '+52'); // Cambiar +521 a +52
- } else if (number.startsWith('+52') && number[4] === '1') {
- number = number.replace('+52 1', '+52'); // Cambiar +52 1 a +52
- }
- const parsedNumber = phoneUtil.parseAndKeepRawInput(number)
- return phoneUtil.isValidNumber(parsedNumber)
- } catch (error) {
- return false
- }}
- async function joinChannels(conn) {
- for (const channelId of Object.values(global.ch)) {
- await conn.newsletterFollow(channelId).catch(() => {})
- }}
|