cgnat: fix de novo

Signed-off-by: Rodrigo Martins <rodrigo@martinsevieira.adv.br>
This commit is contained in:
Rodrigo Martins committed 2026-04-10 11:24:52 -03:00
1 parent b0f58144a8
commit abf9b71484
1 file changed
+100 -75
+100 -75
View File
@@ -9032,116 +9032,141 @@ Digite /help para ver todos os comandos disponíveis!
return;
}
const aviso = result.modoFallback
? '\n⚠️ _IP não encontrado nos registros (sessão encerrada). Mostrando sessões ativas nesse horário._\n'
: '';
if (result.modoFallback) {
await this.bot.sendMessage(chatId,
`⚠️ _IP não armazenado para sessões encerradas. Mostrando sessões ativas às ${horaStr}._`,
{ parse_mode: 'Markdown' }
);
}
const titulo = `Sessão em ${dataStr}${horaStr ? ' ' + horaStr : ''}`;
await this._exibirAcessosCgnat(chatId, session.privateIP, result.dados, titulo + aviso);
await this._exibirAcessosCgnat(chatId, session.privateIP, result.dados, titulo);
}
/**
* Consulta conexões ATIVAS agora para o IP privado CGNAT
* Usa ObterClientesServicos com conexao: "online" e filtra por IP
* Consulta conexões ATIVAS agora para o IP privado CGNAT,
* identifica o cliente e exibe seus dados cadastrais.
*/
async handleCgnatConsultarAtivas(chatId, privateIP) {
await this.bot.sendMessage(chatId,
`🔍 Consultando conexões ativas para \`${privateIP}\`...`,
`🔍 Consultando conexão ativa para \`${privateIP}\`...`,
{ parse_mode: 'Markdown' }
);
const result = await this.topsapp.buscarConexaoAtivaPorIp(privateIP);
if (!result.success) {
await this.bot.sendMessage(chatId,
`❌ Erro ao consultar TopSapp: ${result.error}`,
{ parse_mode: 'Markdown' }
);
await this.bot.sendMessage(chatId, `❌ Erro ao consultar TopSapp: ${result.error}`, { parse_mode: 'Markdown' });
return;
}
if (result.total === 0) {
const extra = result.totalGeral > 0
? `\n\n_(${result.totalGeral} conexões online, nenhuma com IP \`${privateIP}\`)_`
: `\n\n_(nenhuma conexão online no momento)_`;
? `_(${result.totalGeral} sessões ativas, nenhuma com IP \`${privateIP}\`)_`
: `_(nenhuma sessão ativa no momento)_`;
await this.bot.sendMessage(chatId,
`ℹ️ Nenhuma conexão ativa encontrada para o IP \`${privateIP}\`.${extra}`,
`ℹ️ Nenhuma conexão ativa encontrada para \`${privateIP}\`.\n${extra}`,
{ parse_mode: 'Markdown' }
);
return;
}
await this._exibirConexoesAtivasCgnat(chatId, privateIP, result.dados);
const sessao = result.dados[0];
await this._exibirClienteCgnat(chatId, sessao, privateIP);
}
/**
* Exibe histórico de acessos CGNAT (ObterClientesServicosAcessos)
* Identifica o cliente a partir de um registro de sessão CGNAT e exibe seus dados.
*/
async _exibirClienteCgnat(chatId, sessao, privateIP) {
const { id_cliente, usuario, inicio, termino, nas_ip } = sessao;
const inicioFmt = inicio ? inicio.replace(/-\d{2}$/, '').replace('T', ' ') : '—';
const terminoFmt = termino ? termino.replace(/-\d{2}$/, '').replace('T', ' ') : 'ativo';
// Se não tem id_cliente válido, mostra só o que temos
if (!id_cliente || id_cliente < 0) {
await this.bot.sendMessage(chatId,
`🌐 *Sessão CGNAT — \`${privateIP}\`*\n\n` +
`👤 Login: \`${usuario || '—'}\`\n` +
`🕐 ${inicioFmt} → ${terminoFmt}\n` +
`⚠️ _Cliente não identificado (registro sem ID)_`,
{ parse_mode: 'Markdown' }
);
return;
}
await this.bot.sendMessage(chatId, `🔍 Buscando dados do cliente (ID ${id_cliente})...`, { parse_mode: 'Markdown' });
const dadosResult = await this.topsapp.obterDadosCadastrais(id_cliente);
if (!dadosResult.success || !dadosResult.cliente) {
// Fallback: mostra só os dados da sessão
await this.bot.sendMessage(chatId,
`🌐 *Sessão CGNAT — \`${privateIP}\`*\n\n` +
`👤 Login: \`${usuario || '—'}\`\n` +
`🕐 ${inicioFmt} → ${terminoFmt}\n` +
`❌ Erro ao buscar dados do cliente: ${dadosResult.error || 'desconhecido'}`,
{ parse_mode: 'Markdown' }
);
return;
}
const c = dadosResult.cliente;
const servAtivo = (dadosResult.servicos || []).find(s => s.login === usuario) || (dadosResult.servicos || [])[0];
let msg = `🌐 *Cliente identificado via CGNAT*\n`;
msg += `📡 IP Privado: \`${privateIP}\`\n\n`;
msg += `👤 *${c.nome || '—'}*\n`;
if (c.cpf_cnpj) msg += `🪪 CPF/CNPJ: \`${c.cpf_cnpj}\`\n`;
if (c.telefone || c.celular) msg += `📞 Tel: ${c.telefone || c.celular}\n`;
if (c.email) msg += `📧 ${c.email}\n`;
msg += `\n🔌 *Serviço:*\n`;
msg += ` Login: \`${usuario}\`\n`;
msg += ` 🕐 Sessão: ${inicioFmt} → ${terminoFmt}\n`;
if (servAtivo) {
if (servAtivo.planoNome) msg += ` 📦 Plano: ${servAtivo.planoNome}\n`;
if (servAtivo.statusFormatado) msg += ` 🔄 Status: ${servAtivo.statusFormatado}\n`;
}
await this.bot.sendMessage(chatId, msg, { parse_mode: 'Markdown' });
// Botões de ação
const keyboard = {
inline_keyboard: [[
{ text: '📋 Diagnóstico completo', callback_data: `diag_cliente_${id_cliente}_guarai_colmeia` },
{ text: '❌ Fechar', callback_data: 'cancel_action' }
]]
};
await this.bot.sendMessage(chatId, '💡 Deseja ver o diagnóstico completo do cliente?', { reply_markup: keyboard });
}
/**
* Exibe sessões CGNAT do histórico e busca dados do cliente se identificado
*/
async _exibirAcessosCgnat(chatId, privateIP, acessos, titulo) {
let msg = `🌐 *${titulo} — \`${privateIP}\`*\n\n`;
// Se há apenas uma sessão com id_cliente válido, vai direto para o cliente
const comCliente = acessos.filter(a => a.id_cliente && a.id_cliente > 0);
if (comCliente.length === 1) {
await this._exibirClienteCgnat(chatId, comCliente[0], privateIP);
return;
}
for (const a of acessos.slice(0, 10)) {
const inicio = a.inicio ? a.inicio.replace(/\.\d+.*$/, '').replace('T', ' ') : '—';
const termino = a.termino ? a.termino.replace(/\.\d+.*$/, '').replace('T', ' ') : 'ativo';
msg += `👤 *${a.usuario || '—'}*\n`;
// Múltiplas sessões — lista para o usuário escolher
let msg = `🌐 *${titulo}*\n\`${privateIP}\`\n\n`;
for (const a of acessos.slice(0, 8)) {
const inicio = a.inicio ? a.inicio.replace(/-\d{2}$/, '').replace('T', ' ') : '—';
const termino = a.termino ? a.termino.replace(/-\d{2}$/, '').replace('T', ' ') : 'ativo';
msg += `👤 *${a.usuario || '—'}* (ID cliente: ${a.id_cliente || '?'})\n`;
msg += ` 🕐 ${inicio} → ${termino}\n`;
if (a.ip) msg += ` 🖥️ IP: \`${a.ip}\`\n`;
if (a.estacao) msg += ` 📡 Estação: ${a.estacao}\n`;
if (a.ip) msg += ` 🖥️ \`${a.ip}\`\n`;
msg += '\n';
}
if (acessos.length > 10) {
msg += `_... e mais ${acessos.length - 10} registro(s)._\n`;
}
if (acessos.length > 8) msg += `_... e mais ${acessos.length - 8} registro(s)._\n`;
await this.bot.sendMessage(chatId, msg, { parse_mode: 'Markdown' });
const logins = [...new Set(acessos.slice(0, 10).map(a => a.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
});
}
}
/**
* 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
});
}
}
/**