genieacs: sync with topsapp parameters

Signed-off-by: Rodrigo Bertoldo de Sousa Martins <rodrigo.sousa.577@gmail.com>
This commit is contained in:
rodrigo committed 2026-04-02 23:36:53 -03:00
1 parent ad2c6fd485
commit 6717f5d7f2
1 file changed
+203 -9
+203 -9
View File
@@ -2033,6 +2033,36 @@ Digite /help para ver todos os comandos disponíveis!
} else if (data.startsWith('router_cfg_')) { } else if (data.startsWith('router_cfg_')) {
console.log(`🔍 Condição router_cfg_ atendida`); console.log(`🔍 Condição router_cfg_ atendida`);
await this.handleRouterCfgCallback(callbackQuery, data); await this.handleRouterCfgCallback(callbackQuery, data);
} else if (data.startsWith('cfg_roteador_cli_')) {
console.log(`🔍 Condição cfg_roteador_cli_ atendida`);
await this.bot.answerCallbackQuery(callbackQuery.id);
const parts = data.replace('cfg_roteador_cli_', '').split('_');
const idCliente = parts[0];
const location = parts.slice(1).join('_');
await this._configurarRoteadorSelecionarServico(chatId, userId, idCliente, location);
} else if (data.startsWith('cfg_roteador_srv_')) {
console.log(`🔍 Condição cfg_roteador_srv_ atendida`);
await this.bot.answerCallbackQuery(callbackQuery.id);
// formato: cfg_roteador_srv_<idCliente>_<idServico>_<location>
const rest = data.replace('cfg_roteador_srv_', '');
const parts = rest.split('_');
const idCliente = parts[0];
const idServico = parts[1];
const location = parts.slice(2).join('_');
// Recarregar o serviço para ter o objeto completo com pppoeLogin
const servicosResult = await this.topsapp.obterServicosCliente(idCliente, location);
if (!servicosResult.success) {
await this.bot.sendMessage(chatId, `❌ Erro ao buscar serviço: ${servicosResult.error}`);
} else {
const servico = (servicosResult.servicos || []).find(s =>
String(s.id_servico || s.id) === String(idServico)
);
if (!servico) {
await this.bot.sendMessage(chatId, `❌ Serviço #${idServico} não encontrado.`);
} else {
await this._configurarRoteadorPorServico(chatId, userId, servico, location);
}
}
} else if (data.startsWith('diag_cliente_')) { } else if (data.startsWith('diag_cliente_')) {
console.log(`🔍 Condição diag_cliente_ atendida`); console.log(`🔍 Condição diag_cliente_ atendida`);
await this.handleDiagClienteCallback(callbackQuery, data); await this.handleDiagClienteCallback(callbackQuery, data);
@@ -7520,36 +7550,201 @@ Digite /help para ver todos os comandos disponíveis!
} }
/** /**
* Comando "configurar roteador <serial|tag>". * Comando "configurar roteador <termo>".
* Busca o dispositivo e exibe o menu de configurações com inline keyboard. *
* Fluxo:
* 1. Se o termo parece serial/tag GenieACS (alphanumérico sem espaços) → busca direto no GenieACS.
* 2. Caso contrário, busca no TopSapp por nome/CPF:
* a. Seleciona o cliente (se houver múltiplos)
* b. Seleciona o serviço com login PPPoE
* c. Usa o login PPPoE como TAG para buscar no GenieACS
* d. Se não encontrar TAG no GenieACS → informa que não é possível configurar
*/ */
async handleConfigurarRoteador(chatId, userId, termo) { async handleConfigurarRoteador(chatId, userId, termo) {
if (!termo) { if (!termo) {
await this.bot.sendMessage(chatId, await this.bot.sendMessage(chatId,
'⚙️ *Configurar Roteador*\n\n' + '⚙️ *Configurar Roteador*\n\n' +
'Informe o serial ou a TAG (login TopSapp) do dispositivo.\n' + 'Informe o serial, TAG, nome do cliente ou CPF.\n' +
'Exemplos:\n' + 'Exemplos:\n' +
'• `configurar roteador ABCD12345678`\n' + '• `configurar roteador ABCD12345678`\n' +
'• `configurar roteador joao.silva`', '• `configurar roteador joao.silva`\n' +
'• `configurar roteador João da Silva`\n' +
'• `configurar roteador 123.456.789-10`',
{ parse_mode: 'Markdown' } { parse_mode: 'Markdown' }
); );
return; return;
} }
await this.bot.sendMessage(chatId, `🔍 Buscando dispositivo \`${termo}\` no GenieACS...`, { parse_mode: 'Markdown' }); // CPF sem formatação: 11 dígitos numéricos → formata e encaminha para TopSapp
if (/^\d{11}$/.test(termo)) {
const cpfFormatado = `${termo.slice(0,3)}.${termo.slice(3,6)}.${termo.slice(6,9)}-${termo.slice(9,11)}`;
return this._configurarRoteadorBuscarTopSapp(chatId, userId, cpfFormatado);
}
// Heurística: serial/tag GenieACS não tem espaço e não é CPF formatado
const pareceGenieACS = !/\s/.test(termo) && !/^\d{3}\.\d{3}\.\d{3}-\d{2}$/.test(termo);
if (pareceGenieACS) {
// Caminho direto: buscar no GenieACS por serial ou TAG
await this._configurarRoteadorPorGenieACS(chatId, userId, termo);
} else {
// Caminho via TopSapp: buscar cliente por nome/CPF
await this._configurarRoteadorBuscarTopSapp(chatId, userId, termo);
}
}
/**
* Busca o dispositivo diretamente no GenieACS e abre o menu de configuração.
*/
async _configurarRoteadorPorGenieACS(chatId, userId, termo) {
await this.bot.sendMessage(chatId, `🔍 Buscando dispositivo \`${termo}\` no GenieACS...`, { parse_mode: 'Markdown' });
try { try {
const resultado = await this.genieacs.buscarRoteador(termo); const resultado = await this.genieacs.buscarRoteador(termo);
if (!resultado.success) {
await this.bot.sendMessage(chatId,
`❌ *Dispositivo não encontrado no GenieACS*\n\n` +
`🔍 Busca: \`${termo}\`\n` +
`⚠️ ${resultado.error || 'Nenhum resultado'}\n\n` +
`_Tente buscar pelo nome ou CPF do cliente._`,
{ parse_mode: 'Markdown' }
);
return;
}
this.userSessions.set(userId, {
action: 'router_cfg',
deviceId: resultado.device.deviceId,
device: resultado.device,
instance: resultado.instance || '',
timestamp: Date.now()
});
await this._enviarMenuConfigurarRoteador(chatId, resultado.device, resultado.instance || '');
} catch (error) {
logger.error('Erro em _configurarRoteadorPorGenieACS:', error);
await this.bot.sendMessage(chatId, `❌ Erro ao consultar o GenieACS: ${error.message}`);
}
}
/**
* Busca o cliente no TopSapp por nome/CPF e apresenta seleção.
*/
async _configurarRoteadorBuscarTopSapp(chatId, userId, query) {
await this.bot.sendMessage(chatId, `🔍 Buscando cliente "${query}" no TopSapp...`);
try {
const resultado = await this.topsapp.buscarCliente(query);
if (!resultado.success) {
await this.bot.sendMessage(chatId, `❌ Erro na busca: ${resultado.error}`);
return;
}
if (!resultado.clientes || resultado.clientes.length === 0) {
await this.bot.sendMessage(chatId, `🔍 Nenhum cliente encontrado para: "${query}"`);
return;
}
const instancia = resultado.instancia || '';
if (resultado.clientes.length === 1) {
await this._configurarRoteadorSelecionarServico(chatId, userId, resultado.clientes[0].id, instancia);
return;
}
// Múltiplos clientes → seleção
let msg = `🔍 *${resultado.clientes.length} clientes encontrados:*\n\n`;
const keyboard = [];
resultado.clientes.slice(0, 8).forEach((c, i) => {
msg += `*${i + 1}.* ${c.nome}`;
if (c.cpf) msg += ` — \`${c.cpf}\``;
msg += '\n';
keyboard.push([{
text: `⚙️ ${c.nome.substring(0, 35)}`,
callback_data: `cfg_roteador_cli_${c.id}_${instancia}`
}]);
});
await this.bot.sendMessage(chatId, msg, {
parse_mode: 'Markdown',
reply_markup: { inline_keyboard: keyboard }
});
} catch (error) {
logger.error('Erro em _configurarRoteadorBuscarTopSapp:', error);
await this.bot.sendMessage(chatId, `❌ Erro: ${error.message}`);
}
}
/**
* Busca os serviços do cliente e apresenta seleção (ou vai direto se só há 1).
*/
async _configurarRoteadorSelecionarServico(chatId, userId, idCliente, location) {
const servicosResult = await this.topsapp.obterServicosCliente(idCliente, location);
if (!servicosResult.success) {
await this.bot.sendMessage(chatId, `❌ Erro ao buscar serviços: ${servicosResult.error}`);
return;
}
const servicos = (servicosResult.servicos || []).filter(s => {
const st = s.id_status || s.statusNumerico;
return st === 1 || st === '1' ||
String(s.status).toLowerCase() === 'liberado' ||
String(s.status).toLowerCase() === 'ativo';
});
if (servicos.length === 0) {
await this.bot.sendMessage(chatId, `⚠️ Cliente sem serviços ativos.`);
return;
}
if (servicos.length === 1) {
await this._configurarRoteadorPorServico(chatId, userId, servicos[0], location);
return;
}
let msg = `⚙️ *Selecione o serviço:*\n\n`;
const keyboard = [];
servicos.forEach((s, i) => {
const nome = s.descricao || s.nome || `Serviço ${i + 1}`;
const login = s.usuario || s.pppoe_login || s.login || '';
msg += `*${i + 1}.* ${nome}${login ? ` — \`${login}\`` : ''}\n`;
keyboard.push([{
text: `⚙️ ${nome.substring(0, 35)}`,
callback_data: `cfg_roteador_srv_${idCliente}_${s.id_servico || s.id}_${location}`
}]);
});
await this.bot.sendMessage(chatId, msg, {
parse_mode: 'Markdown',
reply_markup: { inline_keyboard: keyboard }
});
}
/**
* A partir de um serviço TopSapp, extrai o login PPPoE, busca a TAG no GenieACS e abre o menu.
*/
async _configurarRoteadorPorServico(chatId, userId, servico, location) {
const pppoeLogin = servico.usuario || servico.pppoe_login || servico.login || null;
if (!pppoeLogin) {
await this.bot.sendMessage(chatId,
`⚠️ O serviço selecionado não possui login PPPoE cadastrado.\n` +
`Não é possível localizar o roteador no GenieACS sem esse dado.`
);
return;
}
await this.bot.sendMessage(chatId, `🔍 Localizando roteador pela TAG \`${pppoeLogin}\` no GenieACS...`, { parse_mode: 'Markdown' });
try {
const resultado = await this.genieacs.buscarRoteador(pppoeLogin, location);
if (!resultado.success) { if (!resultado.success) {
await this.bot.sendMessage(chatId, await this.bot.sendMessage(chatId,
`❌ *Dispositivo não encontrado*\n\n🔍 Busca: \`${termo}\`\n⚠️ ${resultado.error || 'Nenhum resultado'}`, `⚠️ *Roteador não encontrado no GenieACS*\n\n` +
`🏷️ TAG pesquisada: \`${pppoeLogin}\`\n\n` +
`Não é possível realizar alterações no roteador deste cliente pelo bot.\n` +
`_O dispositivo pode não estar cadastrado no GenieACS ou a TAG ainda não foi sincronizada._`,
{ parse_mode: 'Markdown' } { parse_mode: 'Markdown' }
); );
return; return;
} }
// Salva contexto na sessão para os callbacks seguintes
this.userSessions.set(userId, { this.userSessions.set(userId, {
action: 'router_cfg', action: 'router_cfg',
deviceId: resultado.device.deviceId, deviceId: resultado.device.deviceId,
@@ -7559,9 +7754,8 @@ Digite /help para ver todos os comandos disponíveis!
}); });
await this._enviarMenuConfigurarRoteador(chatId, resultado.device, resultado.instance || ''); await this._enviarMenuConfigurarRoteador(chatId, resultado.device, resultado.instance || '');
} catch (error) { } catch (error) {
logger.error('Erro em handleConfigurarRoteador:', error); logger.error('Erro em _configurarRoteadorPorServico:', error);
await this.bot.sendMessage(chatId, `❌ Erro ao consultar o GenieACS: ${error.message}`); await this.bot.sendMessage(chatId, `❌ Erro ao consultar o GenieACS: ${error.message}`);
} }
} }