From 0ae32bb1a1fbc073240dfee751d45e597b1c54bc Mon Sep 17 00:00:00 2001 From: Rodrigo Martins Date: Thu, 9 Apr 2026 20:57:50 -0300 Subject: [PATCH] cgnat: fix search topsapp active2 Signed-off-by: Rodrigo Martins --- src/bot/handler.js | 49 +++++++++++++++++++++++++++++++++++------- src/topsapp/api.js | 12 +++++++++++ src/topsapp/manager.js | 43 +++++++++++++++++++++++++----------- 3 files changed, 84 insertions(+), 20 deletions(-) diff --git a/src/bot/handler.js b/src/bot/handler.js index 15c2a39..4c8be2c 100644 --- a/src/bot/handler.js +++ b/src/bot/handler.js @@ -9057,7 +9057,8 @@ Digite /help para ver todos os comandos disponíveis! } /** - * Consulta conexões ATIVAS agora para o IP privado CGNAT (status: on) + * Consulta conexões ATIVAS agora para o IP privado CGNAT + * Usa ObterClientesServicos com conexao: "online" e filtra por IP */ async handleCgnatConsultarAtivas(chatId, privateIP) { await this.bot.sendMessage(chatId, @@ -9065,7 +9066,7 @@ Digite /help para ver todos os comandos disponíveis! { parse_mode: 'Markdown' } ); - const result = await this.topsapp.obterAcessosPorEstacao(privateIP, null, null, '', 'on'); + const result = await this.topsapp.buscarConexaoAtivaPorIp(privateIP); if (!result.success) { await this.bot.sendMessage(chatId, @@ -9075,9 +9076,7 @@ Digite /help para ver todos os comandos disponíveis! return; } - const acessos = result.data?.dados || []; - - if (acessos.length === 0) { + if (result.total === 0) { await this.bot.sendMessage(chatId, `ℹ️ Nenhuma conexão ativa encontrada para o IP \`${privateIP}\` no momento.`, { parse_mode: 'Markdown' } @@ -9085,11 +9084,11 @@ Digite /help para ver todos os comandos disponíveis! return; } - await this._exibirAcessosCgnat(chatId, privateIP, acessos, '🟢 Conexões ativas'); + await this._exibirConexoesAtivasCgnat(chatId, privateIP, result.dados); } /** - * Exibe os acessos CGNAT e oferece botão para ver dados do cliente + * Exibe histórico de acessos CGNAT (ObterClientesServicosAcessos) */ async _exibirAcessosCgnat(chatId, privateIP, acessos, titulo) { let msg = `🌐 *${titulo} — \`${privateIP}\`*\n\n`; @@ -9110,7 +9109,6 @@ Digite /help para ver todos os comandos disponíveis! await this.bot.sendMessage(chatId, msg, { parse_mode: 'Markdown' }); - // Se único login, oferecer busca no TopSapp const logins = [...new Set(acessos.slice(0, 10).map(a => a.usuario).filter(Boolean))]; if (logins.length === 1) { const keyboard = { @@ -9125,6 +9123,41 @@ Digite /help para ver todos os comandos disponíveis! } } + /** + * Exibe conexões ativas CGNAT (ObterClientesServicos com conexao: online) + */ + async _exibirConexoesAtivasCgnat(chatId, privateIP, servicos) { + let msg = `🟢 *Conexões ativas — \`${privateIP}\`*\n\n`; + + for (const s of servicos.slice(0, 10)) { + msg += `👤 *${s.usuario || '—'}*\n`; + if (s.nome_cliente || s.cliente) msg += ` 🏷️ Cliente: ${s.nome_cliente || s.cliente}\n`; + msg += ` 🖥️ IP: \`${s.ip || '—'}\`\n`; + if (s.descricao) msg += ` 📦 Plano: ${s.descricao}\n`; + if (s.status) msg += ` 🔄 Status: ${s.status}\n`; + msg += '\n'; + } + + if (servicos.length > 10) { + msg += `_... e mais ${servicos.length - 10} registro(s)._\n`; + } + + await this.bot.sendMessage(chatId, msg, { parse_mode: 'Markdown' }); + + const logins = [...new Set(servicos.slice(0, 10).map(s => s.usuario).filter(Boolean))]; + if (logins.length === 1) { + const keyboard = { + inline_keyboard: [[ + { text: `🔍 Ver dados de ${logins[0]}`, callback_data: `buscar_cgnat_user_${logins[0]}` }, + { text: '❌ Fechar', callback_data: 'cancel_action' } + ]] + }; + await this.bot.sendMessage(chatId, '💡 Deseja ver os dados cadastrais do cliente?', { + reply_markup: keyboard + }); + } + } + /** * Reiniciar ONU Datacom — busca em todas as OLTs */ diff --git a/src/topsapp/api.js b/src/topsapp/api.js index 9248010..6e7e597 100644 --- a/src/topsapp/api.js +++ b/src/topsapp/api.js @@ -1018,6 +1018,18 @@ class TopSappAPI { }, instance, credentials); } + /** + * Listar conexões ativas (ObterClientesServicos com conexao: "online") + */ + async obterConexoesAtivas(instance, credentials) { + const session = await this.getValidSession(instance, credentials); + return this.makeRequest('ObterClientesServicos', { + idUsuario: session.idUsuario, + conexao: 'online', + calcDadosAcesso: true + }, instance, credentials); + } + /** * Calcular similaridade entre duas strings (algoritmo de Jaro-Winkler simplificado) */ diff --git a/src/topsapp/manager.js b/src/topsapp/manager.js index a7298b5..acbb178 100644 --- a/src/topsapp/manager.js +++ b/src/topsapp/manager.js @@ -1331,13 +1331,8 @@ class TopSappManager { /** * Busca acessos por estação/IP privado CGNAT no TopSapp - * @param {string} estacao - IP privado (ex: 100.110.0.5) ou nome da estação - * @param {string|null} dataInicial - formato dd/mm/yyyy (ignorado se status='on') - * @param {string|null} dataFinal - formato dd/mm/yyyy (ignorado se status='on') - * @param {string} location - * @param {string} status - 'on' para listar apenas conexões ativas (ignora período) */ - async obterAcessosPorEstacao(estacao, dataInicial, dataFinal, location = '', status = null) { + async obterAcessosPorEstacao(estacao, dataInicial, dataFinal, location = '') { if (!this.isReady()) { return { success: false, error: 'TopSapp não está configurado' }; } @@ -1345,18 +1340,42 @@ class TopSappManager { const credentials = this.config.getCredentialsByLocation(location); const instance = this.api.getInstanceByLocation(location); const params = { estacao }; - if (status) { - params.status = status; - } else { - if (dataInicial) params.dataInicial = dataInicial; - if (dataFinal) params.dataFinal = dataFinal; - } + if (dataInicial) params.dataInicial = dataInicial; + if (dataFinal) params.dataFinal = dataFinal; return await this.api.obterAcessos(params, instance, credentials); } catch (error) { return { success: false, error: error.message }; } } + /** + * Busca qual serviço está usando um IP privado CGNAT agora (conexões ativas) + */ + async buscarConexaoAtivaPorIp(privateIP, location = '') { + if (!this.isReady()) { + return { success: false, error: 'TopSapp não está configurado' }; + } + try { + const credentials = this.config.getCredentialsByLocation(location); + const instance = this.api.getInstanceByLocation(location); + const result = await this.api.obterConexoesAtivas(instance, credentials); + + if (!result.success) return result; + + const todos = result.data?.dados || []; + const encontrados = todos.filter(s => s.ip === privateIP); + + return { + success: true, + dados: encontrados, + total: encontrados.length, + instance: result.instance + }; + } catch (error) { + return { success: false, error: error.message }; + } + } + } module.exports = TopSappManager;