adicionada função de reiniciar ONU

Signed-off-by: Rodrigo Martins <rodrigo@martinsevieira.adv.br>
This commit is contained in:
Rodrigo Martins committed 2026-04-05 20:08:41 -03:00
1 parent dbd581eb99
commit ec92ef1b88
3 files changed
+431 -1

No files matched your search

+359
View File
@@ -281,6 +281,11 @@ class BotHandler {
await this.handleMudarIPoE(chatId, target);
break;
case 'reiniciar_onu':
console.log(`🔄 Executando handleReiniciarOnu com target: ${target}`);
await this.handleReiniciarOnu(chatId, target);
break;
case 'conectar':
await this.handleConnect(chatId, target);
break;
@@ -2121,6 +2126,15 @@ Digite /help para ver todos os comandos disponíveis!
} else if (data.startsWith('diag_cliente_')) {
console.log(`🔍 Condição diag_cliente_ atendida`);
await this.handleDiagClienteCallback(callbackQuery, data);
} else if (data.startsWith('restart_onu_cli_')) {
console.log(`🔍 Condição restart_onu_cli_ atendida`);
await this.handleRestartOnuClienteCallback(callbackQuery, data);
} else if (data.startsWith('restart_onu_srv_')) {
console.log(`🔍 Condição restart_onu_srv_ atendida`);
await this.handleRestartOnuServicoCallback(callbackQuery, data);
} else if (data.startsWith('confirm_restart_onu_')) {
console.log(`🔍 Condição confirm_restart_onu_ atendida`);
await this.handleConfirmRestartOnuCallback(callbackQuery, data);
} else if (data.startsWith('diag_servico_')) {
console.log(`🔍 Condição diag_servico_ atendida`);
await this.handleDiagServicoCallback(callbackQuery, data);
@@ -8507,6 +8521,351 @@ Digite /help para ver todos os comandos disponíveis!
);
}
}
// ======================================================================
// REINICIAR ONU POR CLIENTE (Nome / CPF)
// ======================================================================
/**
* Reiniciar ONU buscando pelo nome ou CPF do cliente via TopSapp
*/
async handleReiniciarOnu(chatId, query) {
if (!query) {
await this.bot.sendMessage(chatId,
`🔄 *Reiniciar ONU*\n\n` +
`💡 *Como usar:*\n` +
`• "reiniciar onu João da Silva"\n` +
`• "reiniciar onu 123.456.789-10"\n\n` +
`O sistema busca o cliente no TopSapp, detecta a base (Fiberhome ou Datacom) e reinicia a ONU automaticamente.`,
{ parse_mode: 'Markdown' }
);
return;
}
try {
await this.bot.sendMessage(chatId, '🔍 Buscando cliente...');
let location = '';
let searchQuery = query;
if (/guarai|colmeia/i.test(query)) {
location = 'Guarai/Colmeia';
searchQuery = query.replace(/(guarai|colmeia)/gi, '').trim();
} else if (/pedro afonso/i.test(query)) {
location = 'Pedro Afonso';
searchQuery = query.replace(/pedro afonso/gi, '').trim();
}
const resultado = await this.topsapp.buscarCliente(searchQuery, location);
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: "${searchQuery}"`);
return;
}
const instancia = resultado.instancia || location;
if (resultado.clientes.length === 1) {
await this._mostrarServicosParaReiniciarOnu(chatId, resultado.clientes[0].id, instancia);
return;
}
// Múltiplos clientes → exibir teclado de seleção
let message = `🔍 *${resultado.clientes.length} clientes encontrados*\n\n`;
const keyboard = [];
resultado.clientes.slice(0, 8).forEach((cliente, index) => {
message += `*${index + 1}.* ${cliente.nome}`;
if (cliente.cpf) message += ` — CPF: \`${cliente.cpf}\``;
message += `\n`;
keyboard.push([{
text: `🔄 Reiniciar ONU: ${cliente.nome.substring(0, 28)}`,
callback_data: `restart_onu_cli_${cliente.id}_${instancia}`
}]);
});
await this.bot.sendMessage(chatId, message, {
parse_mode: 'Markdown',
reply_markup: { inline_keyboard: keyboard }
});
} catch (error) {
console.error('❌ Erro em handleReiniciarOnu:', error);
await this.bot.sendMessage(chatId, `❌ Erro: ${error.message}`);
}
}
/**
* Mostra serviços do cliente para selecionar qual ONU reiniciar
*/
async _mostrarServicosParaReiniciarOnu(chatId, 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;
}
// Se só tem 1 serviço, ir direto para confirmação
if (servicos.length === 1) {
const s = servicos[0];
await this._confirmarReiniciarOnu(chatId, idCliente, s, location);
return;
}
// Múltiplos serviços → seleção
let message = `🔄 *Selecione o serviço para reiniciar a ONU:*\n\n`;
const keyboard = [];
servicos.forEach((s, i) => {
const nome = s.descricao || s.nome || `Serviço ${i + 1}`;
const serial = s.serial || s.comodato_serial || s.mac || '';
message += `*${i + 1}.* ${nome}${serial ? ` — \`${serial}\`` : ''}\n`;
keyboard.push([{
text: `🔄 ${nome.substring(0, 35)}`,
callback_data: `restart_onu_srv_${idCliente}_${s.id_servico || s.id}_${location}`
}]);
});
await this.bot.sendMessage(chatId, message, {
parse_mode: 'Markdown',
reply_markup: { inline_keyboard: keyboard }
});
}
/**
* Mostra confirmação antes de reiniciar a ONU
*/
async _confirmarReiniciarOnu(chatId, idCliente, servico, location) {
const serial = servico.serial || servico.comodato_serial || servico.mac || '';
const base = servico.base || '';
const nome = servico.descricao || servico.nome || 'Serviço';
if (!serial) {
await this.bot.sendMessage(chatId, `❌ Serviço "${nome}" não possui serial de ONU cadastrado.`);
return;
}
const oltHint = this._resolverOLTporBase(base);
const tipoOLT = oltHint === 'fiberhome' ? '🔶 Fiberhome (TL1)' : '🔷 Datacom (SSH)';
const serialEscaped = serial.replace(/_/g, '\\_');
await this.bot.sendMessage(chatId,
`⚠️ *Confirmar Reinicialização de ONU*\n\n` +
`📦 *Serviço:* ${nome}\n` +
`📡 *Serial:* \`${serialEscaped}\`\n` +
`🏢 *Base:* ${base || 'N/A'}\n` +
`🔌 *Tipo:* ${tipoOLT}\n\n` +
`⚠️ A ONU será reiniciada e o cliente ficará sem conexão temporariamente.`,
{
parse_mode: 'Markdown',
reply_markup: {
inline_keyboard: [
[
{ text: '✅ SIM, Reiniciar', callback_data: `confirm_restart_onu_${serial}_${base}_${location}` },
{ text: '❌ Cancelar', callback_data: 'cancel_action' }
]
]
}
}
);
}
/**
* Callback: seleção de cliente para reiniciar ONU
*/
async handleRestartOnuClienteCallback(callbackQuery, data) {
const chatId = callbackQuery.message.chat.id;
const parts = data.replace('restart_onu_cli_', '').split('_');
const idCliente = parts[0];
const location = parts.slice(1).join('_');
await this.bot.answerCallbackQuery(callbackQuery.id);
await this._mostrarServicosParaReiniciarOnu(chatId, idCliente, location);
}
/**
* Callback: seleção de serviço para reiniciar ONU
*/
async handleRestartOnuServicoCallback(callbackQuery, data) {
const chatId = callbackQuery.message.chat.id;
const parts = data.replace('restart_onu_srv_', '').split('_');
const idCliente = parts[0];
const idServico = parts[1];
const location = parts.slice(2).join('_');
await this.bot.answerCallbackQuery(callbackQuery.id);
// Buscar o serviço completo
const servicosResult = await this.topsapp.obterServicosCliente(idCliente, location);
if (!servicosResult.success) {
await this.bot.sendMessage(chatId, `❌ Erro ao buscar serviço: ${servicosResult.error}`);
return;
}
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.`);
return;
}
await this._confirmarReiniciarOnu(chatId, idCliente, servico, location);
}
/**
* Callback: confirmação de reiniciar ONU — executa a reinicialização
*/
async handleConfirmRestartOnuCallback(callbackQuery, data) {
const chatId = callbackQuery.message.chat.id;
await this.bot.answerCallbackQuery(callbackQuery.id);
// Formato: confirm_restart_onu_SERIAL_BASE_LOCATION
const rest = data.replace('confirm_restart_onu_', '');
// Serial é o primeiro token (12 chars alfanuméricos)
const serialMatch = rest.match(/^([A-Za-z0-9]+)_(.*)$/);
if (!serialMatch) {
await this.bot.sendMessage(chatId, '❌ Erro ao processar dados de reinicialização.');
return;
}
const serial = serialMatch[1];
const remaining = serialMatch[2]; // BASE_LOCATION
const base = remaining; // usa o restante como base (pode conter location junto)
const oltHint = this._resolverOLTporBase(base);
const serialEscaped = serial.replace(/_/g, '\\_');
await this.bot.editMessageText(
`🔄 *Reiniciando ONU...*\n\n` +
`📡 Serial: \`${serialEscaped}\`\n` +
`⏳ Aguarde...`,
{
chat_id: chatId,
message_id: callbackQuery.message.message_id,
parse_mode: 'Markdown'
}
);
try {
let result;
if (oltHint === 'fiberhome') {
// Reiniciar via TL1 (Fiberhome)
result = await this.fiberhomeTL1.reiniciarOnu(serial);
} else if (oltHint) {
// Reiniciar via SSH (Datacom)
result = await this._reiniciarOnuDatacom(serial, oltHint);
} else {
// Sem base definida — tentar Fiberhome primeiro, depois Datacom
result = await this.fiberhomeTL1.reiniciarOnu(serial);
if (!result.success) {
result = await this._reiniciarOnuDatacomAutoDetect(serial);
}
}
if (result.success) {
await this.bot.sendMessage(chatId,
`✅ *ONU Reiniciada com Sucesso!*\n\n` +
`📡 *Serial:* \`${serialEscaped}\`\n` +
`${result.details ? `🏢 *OLT:* ${(result.details.olt || result.details.oltName || '').replace(/_/g, '\\_')}\n` : ''}` +
`${result.details && result.details.slot ? `📍 *Slot:* ${result.details.slot}\n` : ''}` +
`\n⚡ A ONU estará disponível em alguns instantes.`,
{ parse_mode: 'Markdown' }
);
} else {
await this.bot.sendMessage(chatId,
`❌ *Erro ao reiniciar ONU*\n\n` +
`📡 Serial: \`${serialEscaped}\`\n` +
`⚠️ ${result.error || 'Erro desconhecido'}`,
{ parse_mode: 'Markdown' }
);
}
} catch (error) {
console.error('❌ Erro ao reiniciar ONU:', error);
await this.bot.sendMessage(chatId,
`❌ *Erro ao reiniciar ONU*\n\n⚠️ ${error.message}`,
{ parse_mode: 'Markdown' }
);
}
}
/**
* Reiniciar ONU Datacom via SSH usando serial — busca na OLT indicada
*/
async _reiniciarOnuDatacom(serial, oltId) {
try {
const findResult = await this.ssh.findOnuBySerial(oltId, serial);
if (!findResult || !findResult.success) {
return { success: false, error: `ONU ${serial} não encontrada na OLT ${oltId}` };
}
const { slot, onuId } = findResult.onuInfo;
const oltEquip = this.ssh.equipamentos.get(oltId);
const result = await this.ssh.resetOnuAlternative(oltId, slot, onuId);
return {
...result,
details: {
oltName: oltEquip ? oltEquip.name : oltId,
slot,
onuId,
serial
}
};
} catch (error) {
return { success: false, error: error.message };
}
}
/**
* Reiniciar ONU Datacom — busca em todas as OLTs
*/
async _reiniciarOnuDatacomAutoDetect(serial) {
const olts = this.ssh.listOLTs();
for (const olt of olts) {
try {
const findResult = await this.ssh.findOnuBySerial(olt.id, serial);
if (findResult && findResult.success) {
const { slot, onuId } = findResult.onuInfo;
const result = await this.ssh.resetOnuAlternative(olt.id, slot, onuId);
return {
...result,
details: {
oltName: olt.name,
slot,
onuId,
serial
}
};
}
} catch (e) {
// Tentar próxima OLT
}
}
return { success: false, error: `ONU ${serial} não encontrada em nenhuma OLT Datacom` };
}
}
module.exports = BotHandler;