addONU: Adicionado função de vincular ao TopSapp

Signed-off-by: Rodrigo Bertoldo de Sousa Martins <rodrigo.sousa.577@gmail.com>
This commit is contained in:
rodrigo committed 2026-03-29 12:02:44 -03:00
1 parent 001d1c099a
commit 235e0c0d43
3 files changed
+426 -5

No files matched your search

+380 -5
View File
@@ -1159,8 +1159,7 @@ Digite /help para ver todos os comandos disponíveis!
case 'adicionar_onu_fiberhome_step3':
// Recebeu confirmação de VLAN customizada
const vlanInput = text.trim();
const vlanInput = text.trim();
if (vlanInput && !isNaN(vlanInput)) {
const vlan = parseInt(vlanInput);
if (vlan >= 1 && vlan <= 4094) {
@@ -1177,7 +1176,11 @@ Digite /help para ver todos os comandos disponíveis!
this.userSessions.delete(userId);
// Executar adição da ONU
await this.executarAdicaoOnuFiberhome(chatId, session);
await this.executarAdicaoOnuFiberhome(chatId, session, userId);
return;
case 'topsapp_onu_aguardando_nome':
await this.topsappOnuBuscarCliente(chatId, userId, text.trim(), session.onuData);
return;
}
}
@@ -1211,7 +1214,7 @@ Digite /help para ver todos os comandos disponíveis!
/**
* Executar adição da ONU Fiberhome
*/
async executarAdicaoOnuFiberhome(chatId, session) {
async executarAdicaoOnuFiberhome(chatId, session, userId = null) {
try {
const { serial, usuario, vlan, onuType } = session;
@@ -1254,6 +1257,33 @@ Digite /help para ver todos os comandos disponíveis!
`⚡ A ONU foi reiniciada e estará disponível em alguns instantes.`,
{ parse_mode: 'Markdown' }
);
// Convidar para registrar no TopSapp
if (userId) {
this.userSessions.set(userId, {
action: 'topsapp_onu_pre_busca',
onuData: {
tipo: 'fiberhome',
location: 'guarai_colmeia',
oltHost: resultado.details.olt,
serial,
portaAlias: `${resultado.details.slot}-${resultado.details.ponPort}`
}
});
await this.bot.sendMessage(chatId,
`📋 *Registrar no TopSapp?*\n\nDeseja vincular esta ONU a um cliente no sistema TopSapp?`,
{
parse_mode: 'Markdown',
reply_markup: {
inline_keyboard: [[
{ text: '✅ Sim, vincular', callback_data: 'topsapp_onu_sim' },
{ text: '❌ Não', callback_data: 'cancel_action' }
]]
}
}
);
}
} else {
await this.bot.sendMessage(chatId,
`❌ *Erro ao adicionar ONU Fiberhome*\n\n` +
@@ -1439,6 +1469,9 @@ Digite /help para ver todos os comandos disponíveis!
} else if (data.startsWith('remove_readd_')) {
console.log(`🔍 Chamando handleRemoveAndReAddCallback`);
await this.handleRemoveAndReAddCallback(callbackQuery, data);
} else if (data.startsWith('topsapp_onu_')) {
console.log(`🔍 Condição topsapp_onu_ atendida`);
await this.handleTopSappOnuCallback(callbackQuery, data);
} else if (data.startsWith('add_onu_vlan_')) {
console.log(`🔍 Chamando handleAddOnuVlanCallback`);
await this.handleAddOnuVlanCallback(callbackQuery, data);
@@ -3180,7 +3213,7 @@ Digite /help para ver todos os comandos disponíveis!
this.userSessions.delete(userId);
// Executar adição da ONU
await this.executarAdicaoOnuFiberhome(chatId, session);
await this.executarAdicaoOnuFiberhome(chatId, session, userId);
} else if (data === 'fh_vlan_custom') {
// Pedir VLAN customizada - manter sessão no step3 para receber input do usuário
@@ -3201,6 +3234,7 @@ Digite /help para ver todos os comandos disponíveis!
*/
async handleConfirmAddCallback(callbackQuery, data) {
const chatId = callbackQuery.message.chat.id;
const userId = callbackQuery.from.id;
console.log(`🔍 handleConfirmAddCallback chamado com data: ${data}`);
// Parse do formato: confirm_add_olt_dito_1-1-3_0_603_DACM915E0F76
@@ -3284,6 +3318,33 @@ Digite /help para ver todos os comandos disponíveis!
parse_mode: 'Markdown'
}
);
// Convidar para registrar no TopSapp
const tsLocation = oltId.includes('pedro_afonso') ? 'pedro_afonso' : 'guarai_colmeia';
const oltEquipment = this.ssh.equipamentos.get(oltId);
this.userSessions.set(userId, {
action: 'topsapp_onu_pre_busca',
onuData: {
tipo: 'datacom',
location: tsLocation,
oltHost: oltEquipment ? oltEquipment.host : '',
serial: serialNumber,
portaAlias: slot
}
});
await this.bot.sendMessage(chatId,
`📋 *Registrar no TopSapp?*\n\nDeseja vincular esta ONU a um cliente no sistema TopSapp?`,
{
parse_mode: 'Markdown',
reply_markup: {
inline_keyboard: [[
{ text: '✅ Sim, vincular', callback_data: 'topsapp_onu_sim' },
{ text: '❌ Não', callback_data: 'cancel_action' }
]]
}
}
);
} else {
await this.bot.editMessageText(
`❌ **Erro na Adição**\n\n` +
@@ -5855,6 +5916,320 @@ Digite /help para ver todos os comandos disponíveis!
// Limpar sessão
this.suporteSessions.delete(sessionId);
}
// ─────────────────────────────────────────────────────────────────────────
// TopSapp — Vinculação de ONU após adição
// ─────────────────────────────────────────────────────────────────────────
/**
* Roteador de callbacks topsapp_onu_*
*/
async handleTopSappOnuCallback(callbackQuery, data) {
const chatId = callbackQuery.message.chat.id;
const userId = callbackQuery.from.id;
await this.bot.answerCallbackQuery(callbackQuery.id);
const session = this.userSessions.get(userId);
if (data === 'topsapp_onu_sim') {
if (!session || !session.onuData) {
await this.bot.sendMessage(chatId, '❌ Sessão expirada. Tente novamente após adicionar a ONU.');
return;
}
session.action = 'topsapp_onu_aguardando_nome';
this.userSessions.set(userId, session);
await this.bot.sendMessage(chatId,
`🔍 *Buscar Cliente no TopSapp*\n\nDigite o nome ou CPF do cliente:`,
{ parse_mode: 'Markdown' }
);
return;
}
if (data.startsWith('topsapp_onu_cli_')) {
const idCliente = data.replace('topsapp_onu_cli_', '');
if (!session || !session.onuData) {
await this.bot.sendMessage(chatId, '❌ Sessão expirada. Tente novamente.');
return;
}
await this.topsappOnuMostrarServicos(chatId, userId, idCliente, session.onuData);
return;
}
if (data.startsWith('topsapp_onu_svc_')) {
// formato: topsapp_onu_svc_<idServico>_<idCliente>
const parts = data.replace('topsapp_onu_svc_', '').split('_');
const idServico = parts[0];
const idCliente = parts[1];
if (!session || !session.onuData) {
await this.bot.sendMessage(chatId, '❌ Sessão expirada. Tente novamente.');
return;
}
await this.topsappOnuConfirmarVinculo(chatId, userId, idServico, idCliente, session.onuData);
return;
}
if (data === 'topsapp_onu_ok') {
if (!session || !session.ftthPayload) {
await this.bot.sendMessage(chatId, '❌ Sessão expirada. Tente novamente.');
return;
}
await this.topsappOnuExecutarVinculo(chatId, userId, session);
return;
}
await this.bot.sendMessage(chatId, '❓ Ação desconhecida.');
}
/**
* Busca cliente no TopSapp e exibe lista para seleção
*/
async topsappOnuBuscarCliente(chatId, userId, query, onuData) {
try {
await this.bot.sendMessage(chatId, '🔍 Buscando cliente...');
const resultado = await this.topsapp.buscarCliente(query, onuData.location);
if (!resultado.success) {
await this.bot.sendMessage(chatId,
`❌ *Erro na busca*\n\n${resultado.error}`,
{ parse_mode: 'Markdown' }
);
this.userSessions.delete(userId);
return;
}
if (!resultado.clientes || resultado.clientes.length === 0) {
await this.bot.sendMessage(chatId,
`🔍 *Nenhum cliente encontrado*\n\nTermo: "${query}"\n\nDigite outro nome ou CPF:`,
{
parse_mode: 'Markdown',
reply_markup: { inline_keyboard: [[{ text: '❌ Cancelar', callback_data: 'cancel_action' }]] }
}
);
// Mantém sessão ativa para nova tentativa
return;
}
const keyboard = [];
let msg = `👥 *${resultado.clientes.length > 1 ? resultado.clientes.length + ' clientes encontrados' : 'Cliente encontrado'}*\n\nSelecione o cliente:\n\n`;
resultado.clientes.slice(0, 8).forEach((cliente, i) => {
msg += `${i + 1}. *${cliente.nome}* (ID: ${cliente.id})\n`;
keyboard.push([{ text: `${i + 1}. ${cliente.nome}`, callback_data: `topsapp_onu_cli_${cliente.id}` }]);
});
keyboard.push([{ text: '❌ Cancelar', callback_data: 'cancel_action' }]);
await this.bot.sendMessage(chatId, msg, {
parse_mode: 'Markdown',
reply_markup: { inline_keyboard: keyboard }
});
} catch (error) {
console.error('❌ Erro ao buscar cliente TopSapp:', error);
await this.bot.sendMessage(chatId, `❌ Erro ao buscar cliente: ${error.message}`);
this.userSessions.delete(userId);
}
}
/**
* Lista serviços ativos do cliente para seleção
*/
async topsappOnuMostrarServicos(chatId, userId, idCliente, onuData) {
try {
await this.bot.sendMessage(chatId, '📋 Buscando serviços do cliente...');
const servicosResult = await this.topsapp.obterServicosCliente(idCliente, onuData.location);
if (!servicosResult.success) {
await this.bot.sendMessage(chatId, `❌ Erro ao buscar serviços: ${servicosResult.error}`);
this.userSessions.delete(userId);
return;
}
const servicos = servicosResult.servicos || [];
const servicosAtivos = servicos.filter(s =>
s.id_status === 1 || (s.status || '').toLowerCase() === 'liberado'
);
if (servicosAtivos.length === 0) {
await this.bot.sendMessage(chatId,
`⚠️ *Nenhum serviço ativo encontrado* para o cliente ID ${idCliente}.\n\nCancele e verifique o cliente.`,
{
parse_mode: 'Markdown',
reply_markup: { inline_keyboard: [[{ text: '❌ Cancelar', callback_data: 'cancel_action' }]] }
}
);
return;
}
const keyboard = [];
let msg = `📋 *Serviços ativos do cliente*\n\nSelecione o serviço FTTH:\n\n`;
servicosAtivos.slice(0, 8).forEach((servico, i) => {
const idSvc = servico.id_servico || servico.id;
const nome = servico.descricao || servico.nome || 'Serviço';
const login = servico.usuario ? ` (${servico.usuario})` : '';
msg += `${i + 1}. *${nome}*${login} — ID: ${idSvc}\n`;
keyboard.push([{ text: `${i + 1}. ${nome}${login}`, callback_data: `topsapp_onu_svc_${idSvc}_${idCliente}` }]);
});
keyboard.push([{ text: '❌ Cancelar', callback_data: 'cancel_action' }]);
await this.bot.sendMessage(chatId, msg, {
parse_mode: 'Markdown',
reply_markup: { inline_keyboard: keyboard }
});
} catch (error) {
console.error('❌ Erro ao listar serviços TopSapp:', error);
await this.bot.sendMessage(chatId, `❌ Erro: ${error.message}`);
this.userSessions.delete(userId);
}
}
/**
* Faz matching OLT/porta/perfil e mostra tela de confirmação
*/
async topsappOnuConfirmarVinculo(chatId, userId, idServico, idCliente, onuData) {
try {
await this.bot.sendMessage(chatId, '🔌 Buscando dados da OLT no TopSapp...');
const oltsResult = await this.topsapp.obterOlts(onuData.location);
if (!oltsResult.success) {
await this.bot.sendMessage(chatId, `❌ Erro ao buscar OLTs: ${oltsResult.error}`);
this.userSessions.delete(userId);
return;
}
const olts = oltsResult.data?.dados?.dados || oltsResult.data?.dados || [];
// Encontrar OLT pelo SSID (IP de gerência)
let oltEncontrada = olts.find(o => o.ssid === onuData.oltHost);
if (!oltEncontrada && olts.length > 0) {
oltEncontrada = olts[0];
console.log(`⚠️ OLT não encontrada por SSID "${onuData.oltHost}", usando a primeira: ${oltEncontrada.nome}`);
}
if (!oltEncontrada) {
await this.bot.sendMessage(chatId, `❌ Nenhuma OLT encontrada no TopSapp para este servidor.`);
this.userSessions.delete(userId);
return;
}
// Encontrar porta pelo alias
const portas = oltEncontrada.portas || [];
let portaEncontrada = portas.find(p => p.alias === onuData.portaAlias);
if (!portaEncontrada && portas.length > 0) {
portaEncontrada = portas[0];
console.log(`⚠️ Porta não encontrada por alias "${onuData.portaAlias}", usando a primeira: ${portaEncontrada.alias}`);
}
if (!portaEncontrada) {
await this.bot.sendMessage(chatId, `❌ Nenhuma porta encontrada na OLT "${oltEncontrada.nome}".`);
this.userSessions.delete(userId);
return;
}
// Encontrar perfil por tipo de ONU
const perfis = oltEncontrada.perfis || [];
let perfilEncontrado;
if (onuData.tipo === 'datacom') {
perfilEncontrado = perfis.find(p => p.identificacao && p.identificacao.includes('DATACOM ONU_BRIDGE_'));
} else {
perfilEncontrado = perfis.find(p => p.identificacao === 'ONU-BRIDGE-AN5506-02-B');
}
if (!perfilEncontrado && perfis.length > 0) {
perfilEncontrado = perfis[0];
console.log(`⚠️ Perfil não encontrado por tipo, usando o primeiro: ${perfilEncontrado.identificacao}`);
}
if (!perfilEncontrado) {
await this.bot.sendMessage(chatId, `❌ Nenhum perfil encontrado na OLT "${oltEncontrada.nome}".`);
this.userSessions.delete(userId);
return;
}
const ftthData = {
serial: onuData.serial,
idAP: oltEncontrada.id,
idPorta: portaEncontrada.id,
idPerfil: perfilEncontrado.id
};
// Salvar payload de confirmação na sessão
const session = this.userSessions.get(userId);
session.action = 'topsapp_onu_confirmando';
session.ftthPayload = {
idCliente,
idServico,
ftthData,
location: onuData.location
};
this.userSessions.set(userId, session);
await this.bot.sendMessage(chatId,
`🔌 *Confirmar Vinculação no TopSapp*\n\n` +
`📱 *Serial:* \`${onuData.serial}\`\n` +
`🏢 *OLT:* ${oltEncontrada.nome}\n` +
`📡 *Porta:* ${portaEncontrada.alias}\n` +
`⚙️ *Perfil:* ${perfilEncontrado.identificacao}\n` +
`🆔 *Serviço ID:* ${idServico}\n` +
`👤 *Cliente ID:* ${idCliente}\n\n` +
`Confirmar os dados acima?`,
{
parse_mode: 'Markdown',
reply_markup: {
inline_keyboard: [[
{ text: '✅ Confirmar', callback_data: 'topsapp_onu_ok' },
{ text: '❌ Cancelar', callback_data: 'cancel_action' }
]]
}
}
);
} catch (error) {
console.error('❌ Erro ao confirmar vínculo TopSapp:', error);
await this.bot.sendMessage(chatId, `❌ Erro: ${error.message}`);
this.userSessions.delete(userId);
}
}
/**
* Executa a atualização FTTH no TopSapp via AlterarServico
*/
async topsappOnuExecutarVinculo(chatId, userId, session) {
try {
const { idCliente, idServico, ftthData, location } = session.ftthPayload;
await this.bot.sendMessage(chatId, '⏳ Salvando dados no TopSapp...');
const resultado = await this.topsapp.atualizarFTTH(idCliente, idServico, ftthData, location);
if (resultado.success) {
await this.bot.sendMessage(chatId,
`✅ *ONU vinculada com sucesso no TopSapp!*\n\n` +
`📱 *Serial:* \`${ftthData.serial}\`\n` +
`🆔 *Serviço ID:* ${idServico}\n` +
`👤 *Cliente ID:* ${idCliente}`,
{ parse_mode: 'Markdown' }
);
} else {
await this.bot.sendMessage(chatId,
`❌ *Erro ao vincular no TopSapp*\n\n${resultado.error}`,
{ parse_mode: 'Markdown' }
);
}
} catch (error) {
console.error('❌ Erro ao executar vínculo TopSapp:', error);
await this.bot.sendMessage(chatId, `❌ Erro: ${error.message}`);
} finally {
this.userSessions.delete(userId);
}
}
}
module.exports = BotHandler;
+29
View File
@@ -823,6 +823,35 @@ class TopSappAPI {
}
}
/**
* Obter lista de OLTs cadastradas no TopSapp
*/
async obterOlts(location = '', credentials) {
const instance = this.getInstanceByLocation(location);
try {
const session = await this.getValidSession(instance, credentials);
return await this.makeRequest('ObterOlts', { idUsuario: session.idUsuario || 1 }, instance, credentials);
} catch (error) {
return { success: false, error: error.message };
}
}
/**
* Atualizar dados FTTH de um serviço (vincular ONU a cliente/serviço)
*/
async atualizarFTTH(idCliente, idServico, ftthData, location = '', credentials) {
const instance = this.getInstanceByLocation(location);
try {
return await this.makeRequest('AlterarServico', {
idCliente: parseInt(idCliente),
idServico: parseInt(idServico),
...ftthData
}, instance, credentials);
} catch (error) {
return { success: false, error: error.message };
}
}
/**
* Listar todas as instâncias disponíveis
*/
+17
View File
@@ -1261,6 +1261,23 @@ class TopSappManager {
};
}
}
/**
* Obter lista de OLTs cadastradas no TopSapp
*/
async obterOlts(location = '') {
if (!this.isReady()) return { success: false, error: 'TopSapp não configurado' };
const credentials = this.config.getCredentialsByLocation(location);
return await this.api.obterOlts(location, credentials);
}
/**
* Atualizar dados FTTH de um serviço (vincular ONU a cliente/serviço)
*/
async atualizarFTTH(idCliente, idServico, ftthData, location = '') {
if (!this.isReady()) return { success: false, error: 'TopSapp não configurado' };
const credentials = this.config.getCredentialsByLocation(location);
return await this.api.atualizarFTTH(idCliente, idServico, ftthData, location, credentials);
}
}
module.exports = TopSappManager;