feat: nova conversa com número avulso + normalização WhatsApp + dark mode no modal
- Botão '+' na sidebar para iniciar conversa com qualquer número - Busca automática: cliente → dependente → número novo - Campo de mensagem inicial personalizável no modal - Normalização de número (DDI 55) ao enviar via Evolution API - Modal de nova conversa com suporte a dark mode - Correção: foto do cliente não é mais atualizada a cada mensagem - Correção: triagem não processa respostas se já tem atendente+equipe
This commit is contained in:
@@ -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');
|
||||
|
||||
Reference in New Issue
Block a user