ipoe: adicionar nova função

Signed-off-by: Rodrigo Martins <rodrigo@martinsevieira.adv.br>
This commit is contained in:
Rodrigo Martins committed 2026-04-05 08:28:01 -03:00
1 parent 01f1315f9e
commit 468a15845a
4 files changed
+383

No files matched your search

+271
View File
@@ -276,6 +276,11 @@ class BotHandler {
await this.iniciarProcessoFecharSuporte(chatId, user.id, target);
break;
case 'mudar_ipoe':
console.log(`🔗 Executando handleMudarIPoE com target: ${target}`);
await this.handleMudarIPoE(chatId, target);
break;
case 'conectar':
await this.handleConnect(chatId, target);
break;
@@ -2013,6 +2018,15 @@ Digite /help para ver todos os comandos disponíveis!
} else if (data.startsWith('confirm_unblock_')) {
console.log(`🔍 Chamando handleConfirmUnblockCallback`);
await this.handleConfirmUnblockCallback(callbackQuery, data);
} else if (data.startsWith('ipoe_cliente_')) {
console.log(`🔍 Condição ipoe_cliente_ atendida`);
await this.handleIPoEClienteCallback(callbackQuery, data);
} else if (data.startsWith('ipoe_servico_')) {
console.log(`🔍 Condição ipoe_servico_ atendida`);
await this.handleIPoEServicoCallback(callbackQuery, data);
} else if (data.startsWith('confirm_ipoe_')) {
console.log(`🔍 Condição confirm_ipoe_ atendida`);
await this.handleConfirmIPoECallback(callbackQuery, data);
} else if (data.startsWith('block_service_')) {
console.log(`🔍 Chamando handleBlockServiceSelection`);
await this.handleBlockServiceSelection(callbackQuery, data);
@@ -8124,6 +8138,263 @@ Digite /help para ver todos os comandos disponíveis!
await this._enviarMenuConfigurarRoteador(chatId, session.device, session.instance);
}
// ========== IPoE ==========
/**
* Handler para comando "mudar para ipoe"
* Busca o cliente e inicia fluxo de seleção de serviço
*/
async handleMudarIPoE(chatId, target) {
if (!target) {
await this.bot.sendMessage(chatId,
`🔗 *Mudar para IPoE*\n\n` +
`💡 *Como usar:*\n` +
`• "mudar para ipoe João da Silva"\n` +
`• "ipoe 123.456.789-10"\n` +
`• "mudar ipoe 12345" (ID do cliente)\n\n` +
`O comando configura DHCP Option 82 (Agent Circuit ID) e habilita o DHCP no serviço do cliente no TopSapp.`,
{ parse_mode: 'Markdown' }
);
return;
}
try {
await this.bot.sendMessage(chatId, '🔍 Buscando cliente...');
let location = '';
let query = target;
if (/guarai|colmeia/i.test(target)) {
location = 'Guarai/Colmeia';
query = target.replace(/(guarai|colmeia)/gi, '').trim();
} else if (/pedro afonso/i.test(target)) {
location = 'Pedro Afonso';
query = target.replace(/pedro afonso/gi, '').trim();
}
const resultado = await this.topsapp.buscarCliente(query, 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: "${query}"`);
return;
}
const instancia = resultado.instancia || location;
if (resultado.clientes.length === 1) {
await this._mostrarServicosParaIPoE(chatId, resultado.clientes[0].id, instancia);
return;
}
// Múltiplos clientes → teclado de seleção
let message = `🔗 *Mudar para IPoE — Selecione o cliente:*\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: `🔗 ${cliente.nome.substring(0, 30)}`,
callback_data: `ipoe_cliente_${cliente.id}_${instancia}`
}]);
});
await this.bot.sendMessage(chatId, message, {
parse_mode: 'Markdown',
reply_markup: { inline_keyboard: keyboard }
});
} catch (error) {
console.error('❌ Erro em handleMudarIPoE:', error);
await this.bot.sendMessage(chatId, `❌ Erro: ${error.message}`);
}
}
/**
* Callback quando o usuário seleciona um cliente para IPoE
*/
async handleIPoEClienteCallback(callbackQuery, data) {
const chatId = callbackQuery.message.chat.id;
const parts = data.replace('ipoe_cliente_', '').split('_');
const idCliente = parts[0];
const location = parts.slice(1).join('_');
await this.bot.answerCallbackQuery(callbackQuery.id);
await this._mostrarServicosParaIPoE(chatId, idCliente, location);
}
/**
* Exibe serviços ativos do cliente para seleção (IPoE)
*/
async _mostrarServicosParaIPoE(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';
});
if (servicos.length === 0) {
await this.bot.sendMessage(chatId, `⚠️ Cliente sem serviços ativos para configurar IPoE.`);
return;
}
if (servicos.length === 1) {
await this._confirmarMudarIPoE(chatId, idCliente, servicos[0], location);
return;
}
let message = `🔗 *Mudar para IPoE — Selecione o serviço:*\n\n`;
const keyboard = [];
servicos.forEach((s, i) => {
const nome = s.descricao || s.nome || `Serviço ${i + 1}`;
const serial = s.serial || s.mac || 'sem serial';
message += `*${i + 1}.* ${nome} — Serial: \`${serial}\`\n`;
keyboard.push([{
text: `🔗 ${nome.substring(0, 35)}`,
callback_data: `ipoe_servico_${idCliente}_${s.id_servico || s.id}_${location}`
}]);
});
await this.bot.sendMessage(chatId, message, {
parse_mode: 'Markdown',
reply_markup: { inline_keyboard: keyboard }
});
}
/**
* Callback quando o usuário seleciona um serviço para IPoE
*/
async handleIPoEServicoCallback(callbackQuery, data) {
const chatId = callbackQuery.message.chat.id;
const parts = data.replace('ipoe_servico_', '').split('_');
const idCliente = parts[0];
const idServico = parts[1];
const location = parts.slice(2).join('_');
await this.bot.answerCallbackQuery(callbackQuery.id);
// Recarregar serviço para ter dados atualizados
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._confirmarMudarIPoE(chatId, idCliente, servico, location);
}
/**
* Mostra preview do que será alterado e pede confirmação
*/
async _confirmarMudarIPoE(chatId, idCliente, servico, location) {
const serial = servico.serial || servico.mac || '';
const baseInfo = servico.base || '';
const prefixo = this.topsapp._resolverPrefixoIPoE
? this.topsapp._resolverPrefixoIPoE(baseInfo)
: null;
if (!serial) {
await this.bot.sendMessage(chatId,
`❌ *Serviço sem serial de ONU cadastrado.*\n\n` +
`Não é possível gerar o Circuit-ID sem o serial.\n` +
`Verifique o cadastro do serviço no TopSapp.`,
{ parse_mode: 'Markdown' }
);
return;
}
if (!prefixo) {
await this.bot.sendMessage(chatId,
`❌ *Não foi possível identificar a OLT/base deste serviço.*\n\n` +
`Base cadastrada: "${baseInfo || 'vazio'}"\n` +
`Verifique o cadastro do serviço no TopSapp.`,
{ parse_mode: 'Markdown' }
);
return;
}
const circuitId = `${prefixo}:${serial}`;
const nome = servico.descricao || servico.nome || 'N/A';
const idServico = servico.id_servico || servico.id;
let message = `🔗 *Confirmar mudança para IPoE*\n\n`;
message += `📦 *Serviço:* ${nome}\n`;
message += `🆔 *ID Serviço:* ${idServico}\n`;
message += `📟 *Serial ONU:* \`${serial}\`\n`;
message += `🏢 *Base/OLT:* ${baseInfo}\n`;
message += `🏷️ *Prefixo:* ${prefixo}\n\n`;
message += `*Será configurado:*\n`;
message += `🔗 Agent Circuit ID: \`${circuitId}\`\n`;
message += `✅ DHCP Liberar: *Sim*\n\n`;
message += `Deseja confirmar?`;
const keyboard = [
[
{ text: '✅ Confirmar', callback_data: `confirm_ipoe_${idCliente}_${idServico}_${location}` },
{ text: '❌ Cancelar', callback_data: 'cancel_action' }
]
];
await this.bot.sendMessage(chatId, message, {
parse_mode: 'Markdown',
reply_markup: { inline_keyboard: keyboard }
});
}
/**
* Callback de confirmação: executa a mudança para IPoE
*/
async handleConfirmIPoECallback(callbackQuery, data) {
const chatId = callbackQuery.message.chat.id;
const parts = data.replace('confirm_ipoe_', '').split('_');
const idCliente = parts[0];
const idServico = parts[1];
const location = parts.slice(2).join('_');
await this.bot.answerCallbackQuery(callbackQuery.id);
await this.bot.sendMessage(chatId, '⏳ Configurando IPoE no TopSapp...');
const resultado = await this.topsapp.mudarParaIPoE(idCliente, idServico, location);
if (resultado.success) {
let msg = `✅ *IPoE configurado com sucesso!*\n\n`;
msg += `📦 Serviço: ${resultado.servico}\n`;
msg += `📟 Serial: \`${resultado.serial}\`\n`;
msg += `🏢 OLT: ${resultado.baseInfo} (${resultado.prefixo})\n`;
msg += `🔗 Agent Circuit ID: \`${resultado.circuitId}\`\n`;
msg += `✅ DHCP Liberar: *Ativado*`;
await this.bot.sendMessage(chatId, msg, { parse_mode: 'Markdown' });
} else {
await this.bot.sendMessage(chatId,
`❌ *Erro ao configurar IPoE*\n\n⚠️ ${resultado.error}`,
{ parse_mode: 'Markdown' }
);
}
}
}
module.exports = BotHandler;