INDEX / modules /BotCore.js
akra35567's picture
Update modules/BotCore.js
9124c31 verified
/**
* ═══════════════════════════════════════════════════════════════════════
* CLASSE: BotCore (HF SPACES EDITION - SMART LOAD)
* ═══════════════════════════════════════════════════════════════════════
* NΓΊcleo do bot: Baileys wrapper, event handling e orquestraΓ§Γ£o.
* ═══════════════════════════════════════════════════════════════════════
*/
const {
default: makeWASocket,
useMultiFileAuthState,
fetchLatestBaileysVersion,
Browsers,
delay,
DisconnectReason
} = require('@whiskeysockets/baileys');
const pino = require('pino');
const path = require('path');
const fs = require('fs');
/**
* FunΓ§Γ£o de carregamento inteligente para evitar erros de "Module Not Found"
* no ambiente do Hugging Face Spaces.
*/
function smartRequire(moduleName) {
try {
return require(`./${moduleName}`);
} catch (e) {
try {
return require(`./modules/${moduleName}`);
} catch (e2) {
console.error(`❌ [BotCore] Erro ao carregar componente: ${moduleName}`);
return null;
}
}
}
// Carregamento dos componentes e correΓ§Γ΅es
const HFCorrections = smartRequire('HFCorrections');
const ConfigManager = smartRequire('ConfigManager');
const APIClient = smartRequire('APIClient');
const AudioProcessor = smartRequire('AudioProcessor');
const MediaProcessor = smartRequire('MediaProcessor');
const MessageProcessor = smartRequire('MessageProcessor');
const ModerationSystem = smartRequire('ModerationSystem');
const LevelSystem = smartRequire('LevelSystem');
const CommandHandler = smartRequire('CommandHandler');
class BotCore {
constructor() {
this.config = ConfigManager ? ConfigManager.getInstance() : {};
this.logger = pino({ level: 'silent' });
this.sock = null;
this.state = null;
this.saveCreds = null;
this.currentQR = null;
this.isConnected = false;
this.reconnectAttempts = 0;
this.maxReconnectAttempts = 15; // Aumentado para resiliΓͺncia no HF
// InicializaΓ§Γ£o de Componentes
this.apiClient = APIClient ? new APIClient() : null;
this.moderation = ModerationSystem ? new ModerationSystem() : null;
this.levels = LevelSystem ? new LevelSystem() : null;
this.audioProcessor = AudioProcessor ? new AudioProcessor() : null;
this.mediaProcessor = MediaProcessor ? new MediaProcessor() : null;
this.commandHandler = null; // Definido apΓ³s o socket
}
/**
* Prepara o ambiente de arquivos
*/
async initialize() {
console.log('πŸ“‚ Preparando diretΓ³rios de sistema...');
const folders = ['auth_info', 'temp', '/tmp/akira_data'];
folders.forEach(f => {
if (!fs.existsSync(f)) fs.mkdirSync(f, { recursive: true });
});
return true;
}
/**
* Estabelece conexΓ£o com WhatsApp usando DNS Hard-Patch
*/
async connect() {
try {
console.log('πŸ”§ Configurando credenciais de autenticaΓ§Γ£o...');
const { state, saveCreds } = await useMultiFileAuthState(path.join(__dirname, 'auth_info'));
this.state = state;
this.saveCreds = saveCreds;
const { version } = await fetchLatestBaileysVersion();
console.log(`πŸ“‘ Baileys Version: ${version.join('.')}`);
// ═══════════════════════════════════════════════════════════════════════
// SOCKET CONFIGURATION (HF SPACES OPTIMIZED)
// ═══════════════════════════════════════════════════════════════════════
this.sock = makeWASocket({
version,
logger: this.logger,
printQRInTerminal: true,
auth: this.state,
browser: Browsers.ubuntu('Chrome'),
// Aplica Agente e Patch de DNS do HFCorrections
agent: HFCorrections ? HFCorrections.createHFAgent() : undefined,
socketConfig: HFCorrections ? HFCorrections.createWebSocketOptions() : {},
// ConfiguraΓ§Γ΅es de tempo de rede
connectTimeoutMs: 60000,
defaultQueryTimeoutMs: 0,
keepAliveIntervalMs: 30000,
// Prioriza IPv4 para evitar erros de rede do container
getNextIp: (host) => {
const ip = HFCorrections ? HFCorrections.getWhatsAppIP() : undefined;
return ip;
}
});
// Vincula o CommandHandler
if (CommandHandler) {
this.commandHandler = new CommandHandler(this, this.sock);
}
// --- EVENTOS DO WHATSAPP ---
this.sock.ev.on('creds.update', this.saveCreds);
this.sock.ev.on('connection.update', async (update) => {
const { connection, lastDisconnect, qr } = update;
if (qr) {
this.currentQR = qr;
console.log('✨ [QR CODE] Novo código disponível na Web UI.');
}
if (connection === 'close') {
this.isConnected = false;
const statusCode = (lastDisconnect?.error)?.output?.statusCode;
const shouldReconnect = statusCode !== DisconnectReason.loggedOut;
console.log(`⚠️ Conexão encerrada. Motivo: ${lastDisconnect?.error?.message || 'Desconhecido'}`);
if (shouldReconnect && this.reconnectAttempts < this.maxReconnectAttempts) {
this.reconnectAttempts++;
const backoff = Math.min(this.reconnectAttempts * 5000, 45000);
console.log(`πŸ”„ Tentando reconexΓ£o em ${backoff/1000}s...`);
setTimeout(() => this.connect(), backoff);
} else if (statusCode === DisconnectReason.loggedOut) {
console.error('❌ Sessão encerrada permanentemente. Apague a pasta auth_info.');
}
}
if (connection === 'open') {
this.isConnected = true;
this.reconnectAttempts = 0;
this.currentQR = null;
console.log('πŸš€ AKIRA BOT CONECTADO COM SUCESSO!');
}
});
// Listener de Mensagens
this.sock.ev.on('messages.upsert', async (chatUpdate) => {
try {
const m = chatUpdate.messages[0];
if (!m.message || m.key.fromMe) return;
if (MessageProcessor) {
const processor = new MessageProcessor(this, this.sock);
await processor.handle(m);
}
} catch (err) {
console.error('❌ Erro ao processar mensagem recebida:', err.message);
}
});
} catch (error) {
console.error('❌ Falha crítica no BotCore:', error);
throw error;
}
}
/**
* Status e Acesso para a UI
*/
getStatus() {
return {
isConnected: this.isConnected,
reconnectAttempts: this.reconnectAttempts,
botName: this.config.BOT_NAME || 'Akira Bot'
};
}
getQRCode() {
return this.currentQR;
}
/**
* Envio de mensagem com tratamento global
*/
async sendMessage(jid, content, options = {}) {
try {
if (!this.isConnected || !this.sock) return false;
return await this.sock.sendMessage(jid, content, options);
} catch (err) {
console.error(`❌ Falha no envio para ${jid}:`, err.message);
return false;
}
}
}
module.exports = BotCore;