diff --git a/src/controllers/chatController.js b/src/controllers/chatController.js index 33cd573..eac8b3c 100644 --- a/src/controllers/chatController.js +++ b/src/controllers/chatController.js @@ -794,7 +794,9 @@ class ChatController { static async createConversation(req, res) { try { const { alias } = req.params; - const { empresaId, numero, nomeContato, mensagem, instanciaId, clienteId } = req.body; + const { empresaId, numero, mensagem, instanciaId } = req.body; + let clienteId = req.body.clienteId || null; + let nomeContato = req.body.nomeContato || ''; if (!empresaId || !numero || !mensagem) { return res.status(400).json({ success: false, error: 'Campos obrigatórios: empresaId, numero, mensagem' }); @@ -808,6 +810,60 @@ class ChatController { const numeroLimpo = numero.replace(/\D/g, '').substring(0, 15); + // Se não foi informado clienteId, tenta localizar pelo número de telefone + // Fluxo: cliente → dependente (titular) → número novo (sem vínculo) + let clienteEncontrado = null; + let nomeEncontrado = null; + if (!clienteId) { + // Variações do número para busca: completo, sem DDI (55), últimos 8 dígitos + const variantes = [numeroLimpo]; + if (numeroLimpo.startsWith('55')) variantes.push(numeroLimpo.substring(2)); + const ultimos8 = numeroLimpo.slice(-8); + if (!variantes.includes(ultimos8)) variantes.push(ultimos8); + + // 1) Busca CLIENTES + for (const termo of variantes) { + const cli = await db.query(alias, ` + SELECT CLI_CODIGO_ID, CLI_NOME + FROM CLIENTES + WHERE CLI_EMPRESA_ID = ? + AND (REPLACE(REPLACE(REPLACE(COALESCE(CLI_CELULAR,''),'-',''),'(',''),')','') LIKE '%' || ? || '%' + OR REPLACE(REPLACE(REPLACE(COALESCE(CLI_FONE1,''),'-',''),'(',''),')','') LIKE '%' || ? || '%' + OR REPLACE(REPLACE(REPLACE(COALESCE(CLI_FONE2,''),'-',''),'(',''),')','') LIKE '%' || ? || '%') + FETCH FIRST 1 ROWS ONLY + `, [empresaId, termo, termo, termo]); + if (cli.length > 0) { + clienteEncontrado = cli[0].CLI_CODIGO_ID; + nomeEncontrado = (cli[0].CLI_NOME || '').trim(); + break; + } + } + + // 2) Se não achou cliente, busca DEPENDENTES + if (!clienteEncontrado) { + for (const termo of variantes) { + const dep = await db.query(alias, ` + SELECT d.DEPC_CLIENTE_ID AS TITULAR_ID, d.DEPC_NOME, c.CLI_NOME AS TITULAR_NOME + FROM DEPENDENTES_CLI d + LEFT JOIN CLIENTES c ON d.DEPC_CLIENTE_ID = c.CLI_CODIGO_ID + WHERE d.DEPC_EMPRESA_ID = ? AND d.DEPC_SITUACAO = 'A' + AND REPLACE(REPLACE(REPLACE(COALESCE(d.DEPC_TELEFONE,''),'-',''),'(',''),')','') LIKE '%' || ? || '%' + FETCH FIRST 1 ROWS ONLY + `, [empresaId, termo]); + if (dep.length > 0) { + clienteEncontrado = dep[0].TITULAR_ID; + nomeEncontrado = (dep[0].TITULAR_NOME || dep[0].DEPC_NOME || '').trim(); + break; + } + } + } + + if (clienteEncontrado) { + clienteId = clienteEncontrado; + if (!nomeContato || nomeContato === numeroLimpo) nomeContato = nomeEncontrado; + } + } + // Verifica se já existe conversa ABERTA ou EM ESPERA para este número // Tenta com o número exato, e também com os últimos 8 dígitos let existente = await db.query(alias, ` @@ -1416,14 +1472,22 @@ class ChatController { } } +// Helper: normaliza número para formato WhatsApp (DDI + 9º dígito) +function _normalizarWhatsApp(numero) { + let n = String(numero || '').replace(/\D/g, ''); + if (!n) return ''; + if (!n.startsWith('55')) n = '55' + n; + const resto = n.slice(2); + if (resto.length === 10) n = '55' + resto.slice(0, 2) + '9' + resto.slice(2); + return n; +} + // Função auxiliar para enviar mensagem via Evolution API async function sendEvolutionMessage(instancia, numero, texto, tipo, midiaBase64, nomeArquivo) { const url = ((instancia.INS_URL || '').trim()).replace(/\/$/, ''); const apiKey = (instancia.INS_API_KEY || '').trim(); const instanceName = (instancia.INS_INSTANCE_NAME || '').trim(); - const numeroLimpo = numero.replace(/\D/g, ''); - - if (!url || !apiKey || !instanceName || !numeroLimpo) return { success: false, error: 'Parametros insuficientes' }; + const numeroLimpo = _normalizarWhatsApp(numero); const https = require('https'); const http = require('http'); diff --git a/src/controllers/triageController.js b/src/controllers/triageController.js index 4cc53ad..569ec45 100644 --- a/src/controllers/triageController.js +++ b/src/controllers/triageController.js @@ -18,6 +18,16 @@ function logTriage(msg) { } catch(e) {} } +// Helper: normaliza número para formato WhatsApp (DDI + 9º dígito) +function _normalizarWhatsApp(numero) { + let n = String(numero || '').replace(/\D/g, ''); + if (!n) return ''; + if (!n.startsWith('55')) n = '55' + n; + const resto = n.slice(2); + if (resto.length === 10) n = '55' + resto.slice(0, 2) + '9' + resto.slice(2); + return n; +} + class TriageController { /** * Envia o menu principal (equipes + boleto) @@ -784,7 +794,7 @@ class TriageController { // Envia PDF via Evolution var fileName = matricula + ' - ' + fmtDt(t.CAR_DT_VENCIMENTO) + '.pdf'; var mediaPayload = JSON.stringify({ - number: numero.replace(/\D/g, ''), + number: _normalizarWhatsApp(numero), mediatype: 'document', fileName: fileName, caption: 'Boleto Sistema', @@ -1031,7 +1041,8 @@ class TriageController { const instanceName = (inst[0].INS_INSTANCE_NAME || '').trim(); if (!url || !apiKey || !instanceName) return; - const numeroLimpo = numero.replace(/\D/g, ''); + // Normaliza para formato WhatsApp (com DDI) + const numeroLimpo = _normalizarWhatsApp(numero); const payload = JSON.stringify({ number: numeroLimpo, text: texto || '', delay: 0 }); const endpoint = '/message/sendText/' + encodeURIComponent(instanceName); const parsedUrl = new URL(url + endpoint); diff --git a/src/public/chat.html b/src/public/chat.html index 11b2ec4..d6a78e0 100644 --- a/src/public/chat.html +++ b/src/public/chat.html @@ -884,6 +884,7 @@ body.dark-mode .msg.enviando { opacity: 0.4; }