const TARGET_CITY_ALIASES = new Set([ 'santo antonio de jesus', 'santo antonio de jesus ba', 'saj' ]); const TARGET_SEGMENTS = new Set([ 'mercado', 'supermercado', 'farmacia', 'drogaria', 'restaurante', 'delivery', 'distribuidora', 'autopecas', 'material de construcao', 'clinica', 'loja', 'varejo', 'atacado', 'oficina', 'escola', 'salao de beleza', 'barbearia', 'estetica', 'celular', 'transportadora', 'logistica' ]); const SEGMENT_STOPWORDS = new Set(['de', 'da', 'do', 'e']); function segmentTokens(value = '') { return cleanText(value) .split(/[^a-z0-9]+/) .filter((token) => token.length > 2 && !SEGMENT_STOPWORDS.has(token)); } const TARGET_SEGMENT_TOKENS = new Set( [...TARGET_SEGMENTS].flatMap((term) => segmentTokens(term)) ); function tokenMatches(token, targetToken) { return token === targetToken || (token.length > 4 && targetToken.length > 4 && (token.startsWith(targetToken) || targetToken.startsWith(token))); } function isTargetSegmentMatch(segmentKey) { if (!segmentKey) return false; if (TARGET_SEGMENTS.has(segmentKey)) return true; return segmentTokens(segmentKey).some((token) => [...TARGET_SEGMENT_TOKENS].some((targetToken) => tokenMatches(token, targetToken)) ); } const SERVICE_LABELS = { erp: 'ERP / sistema de gestao', ti: 'Gestao de TI', whatsapp: 'Autoatendimento para WhatsApp', indefinido: 'A definir' }; const URGENCY_LABELS = { alta: 'Alta', media: 'Media', baixa: 'Baixa', indefinida: 'Indefinida' }; export function stripAccents(value = '') { return String(value) .normalize('NFD') .replace(/[\u0300-\u036f]/g, ''); } export function cleanText(value = '') { return stripAccents(value) .toLowerCase() .replace(/[^a-z0-9\s@._+-]/g, ' ') .replace(/\s+/g, ' ') .trim(); } function firstDefined(...values) { return values.find((value) => value !== undefined && value !== null && value !== '') ?? ''; } function numberFrom(value) { if (value === undefined || value === null || value === '') return 0; if (typeof value === 'number' && Number.isFinite(value)) return value; const match = String(value).match(/\d+/); return match ? Number(match[0]) : 0; } function toArray(value) { if (Array.isArray(value)) return value.filter(Boolean).map(String); if (!value) return []; return String(value) .split(/[,;|]/) .map((item) => item.trim()) .filter(Boolean); } export function normalizePhone(value = '') { let digits = String(value).replace(/\D/g, ''); while (digits.startsWith('0')) digits = digits.slice(1); if (digits.length === 10 || digits.length === 11) { digits = `55${digits}`; } return digits; } export function detectService(value = '') { const text = cleanText(value); if (!text) return 'indefinido'; if (/\b(1|erp|sistema|gestao empresarial|estoque|financeiro|fiscal|nfce|nfe|pdv)\b/.test(text)) { return 'erp'; } if (/\b(2|ti|suporte|servidor|rede|backup|seguranca|computador|infraestrutura)\b/.test(text)) { return 'ti'; } if (/\b(3|whatsapp|autoatendimento|chatbot|bot|atendimento automatico|mensagem)\b/.test(text)) { return 'whatsapp'; } return 'indefinido'; } export function normalizeUrgency(value = '') { const text = cleanText(value); if (!text) return 'indefinida'; if (/\b(alta|urgente|imediato|hoje|agora|essa semana|parado|problema serio|1)\b/.test(text)) return 'alta'; if (/\b(media|medio|proximo mes|em breve|avaliando|2)\b/.test(text)) return 'media'; if (/\b(baixa|sem pressa|futuro|pesquisa|so pesquisando|3)\b/.test(text)) return 'baixa'; return 'indefinida'; } export function normalizeCurrentSystem(value = '') { const text = cleanText(value); if (!text) return 'nao_informado'; if (/\b(trocar|insatisfeito|migrar|outro sistema|uso outro|4)\b/.test(text)) return 'quer_trocar'; if (/\b(planilha|excel|manual|papel|3)\b/.test(text)) return 'planilhas'; if (/\b(sim|tenho|uso sistema|ja uso|1)\b/.test(text)) return 'usa_sistema'; if (/\b(nao|nenhum|nao tenho|sem sistema|2)\b/.test(text)) return 'sem_sistema'; return 'nao_informado'; } export function normalizeLead(input = {}) { const body = input.body && typeof input.body === 'object' ? input.body : input; const contact = body.contact ?? body.contato ?? {}; const company = body.company ?? body.empresa_dados ?? {}; const message = body.message ?? body.mensagem ?? body.text ?? body.texto ?? body.description ?? ''; const serviceRaw = firstDefined( body.service, body.servico, body.interest, body.interesse, body.solution, body.solucao, message ); const city = firstDefined(company.city, company.cidade, body.city, body.cidade); const state = firstDefined(company.state, company.uf, body.state, body.uf, body.estado); const segment = firstDefined(company.segment, company.segmento, body.segment, body.segmento); const phone = normalizePhone(firstDefined(contact.phone, contact.whatsapp, body.phone, body.telefone, body.whatsapp, body.from)); const name = firstDefined(contact.name, contact.nome, body.name, body.nome, body.contact_name, 'Lead sem nome'); const email = firstDefined(contact.email, body.email); const companyName = firstDefined(company.name, company.nome, body.company_name, body.empresa, body.nome_empresa, 'Empresa nao informada'); const pains = toArray(firstDefined(body.pains, body.dores, body.pain, body.dor, body.maior_dificuldade)); const source = firstDefined(body.source, body.origem, body.canal, 'indefinida'); const service = detectService(serviceRaw); const urgency = normalizeUrgency(firstDefined(body.urgency, body.urgencia, body.prazo, message)); const currentSystem = normalizeCurrentSystem(firstDefined(body.current_system, body.sistema_atual, body.usa_sistema, body.sistema, message)); const employees = numberFrom(firstDefined(company.employees, company.funcionarios, body.employees, body.funcionarios)); const computers = numberFrom(firstDefined(company.computers, company.computadores, body.computers, body.computadores, body.usuarios)); const whatsappVolume = numberFrom(firstDefined(body.whatsapp_volume, body.volume_whatsapp, body.mensagens_dia)); const consent = Boolean(firstDefined(body.consent, body.consentimento, body.opt_in, body.lgpd, false)); const cityKey = cleanText(city); const segmentKey = cleanText(segment); return { id: body.id ?? body.lead_id ?? `GTI-${Date.now()}-${Math.random().toString(36).slice(2, 8).toUpperCase()}`, createdAt: body.created_at ?? body.createdAt ?? new Date().toISOString(), source: String(source || 'indefinida'), name: String(name), phone, email: String(email || ''), companyName: String(companyName), city: String(city || ''), state: String(state || ''), segment: String(segment || ''), service, serviceLabel: SERVICE_LABELS[service], urgency, urgencyLabel: URGENCY_LABELS[urgency], currentSystem, pains, message: String(message || ''), employees, computers, whatsappVolume, consent, isLocal: TARGET_CITY_ALIASES.has(cityKey) || (cityKey.includes('santo antonio') && cityKey.includes('jesus')), isTargetSegment: isTargetSegmentMatch(segmentKey), raw: body }; } export function prioritizeLead(lead) { const hasWhatsapp = Boolean(lead.phone); return { priority: hasWhatsapp ? 'com_whatsapp' : 'sem_whatsapp', hasWhatsapp, reasons: hasWhatsapp ? ['Possui WhatsApp/telefone para contato'] : [] }; } export function buildNextQuestion(lead) { if (lead.service === 'indefinido') { return [ 'Para te direcionar melhor, escolha uma opcao:', '1 - Sistema ERP / gestao empresarial', '2 - Suporte e gestao de TI', '3 - Autoatendimento para WhatsApp', '4 - Ainda nao sei, preciso de orientacao' ].join('\n'); } if (lead.service === 'erp') { if (!lead.segment) { return [ 'Qual o segmento da sua empresa?', '1 - Comercio / loja', '2 - Restaurante / delivery', '3 - Mercado / supermercado', '4 - Distribuidora', '5 - Servicos', '6 - Outro' ].join('\n'); } if (lead.currentSystem === 'nao_informado') { return [ 'Hoje voce ja usa algum sistema?', '1 - Sim', '2 - Nao', '3 - Uso planilhas', '4 - Uso outro sistema, mas quero trocar' ].join('\n'); } if (!lead.pains.length) { return [ 'Qual sua maior dificuldade hoje?', '1 - Controle financeiro', '2 - Estoque', '3 - Vendas', '4 - Emissao fiscal', '5 - Relatorios', '6 - Tudo muito manual' ].join('\n'); } } if (lead.service === 'ti') { if (!lead.computers) { return [ 'Sua empresa possui quantos computadores ou usuarios?', '1 - Ate 5', '2 - 6 a 15', '3 - 16 a 30', '4 - Mais de 30' ].join('\n'); } if (!lead.pains.length) { return [ 'Qual sua maior necessidade de TI?', '1 - Suporte tecnico', '2 - Servidores', '3 - Rede / internet', '4 - Backup', '5 - Seguranca', '6 - Terceirizar o TI' ].join('\n'); } } if (lead.service === 'whatsapp') { if (!lead.pains.length) { return [ 'Voce quer automatizar qual tipo de atendimento?', '1 - Vendas', '2 - Suporte', '3 - Agendamento', '4 - Cardapio / pedidos', '5 - Triagem de mensagens', '6 - Financeiro / segunda via' ].join('\n'); } if (!lead.whatsappVolume) { return [ 'Em media, quantas mensagens chegam no WhatsApp da empresa por dia?', '1 - Ate 20', '2 - 21 a 50', '3 - 51 a 100', '4 - Mais de 100' ].join('\n'); } } if (lead.urgency === 'indefinida') { return [ 'Qual a urgencia para resolver isso?', '1 - Alta, preciso resolver agora', '2 - Media, quero avaliar para breve', '3 - Baixa, estou pesquisando' ].join('\n'); } return [ 'Pelo que voce informou, faz sentido um diagnostico rapido com a GTI.', 'Escolha o melhor horario:', '1 - Hoje pela manha', '2 - Hoje a tarde', '3 - Amanha pela manha', '4 - Amanha a tarde' ].join('\n'); } export function buildInternalWhatsAppMessage(lead, priorityInfo) { const pains = lead.pains.length ? lead.pains.join(', ') : 'Nao informado'; const phone = lead.phone || 'Nao informado'; const priority = priorityInfo.priority === 'com_whatsapp' ? 'COM WHATSAPP' : 'SEM WHATSAPP'; return [ `Novo lead captado - ${priority}`, '', `Empresa: ${lead.companyName}`, `Contato: ${lead.name}`, `WhatsApp: ${phone}`, `Cidade/UF: ${lead.city || 'Nao informada'}${lead.state ? `/${lead.state}` : ''}`, `Segmento: ${lead.segment || 'Nao informado'}`, `Origem: ${lead.source}`, `Dores: ${pains}`, '', 'Acao recomendada: tratar manualmente pela equipe GTI.' ].join('\n'); } export function buildCrmRecord(lead, priorityInfo) { return { lead_id: lead.id, data_criacao: lead.createdAt, status: 'Captado', prioridade: priorityInfo.priority, tem_whatsapp: Boolean(lead.phone), origem: lead.source, servico: lead.service, servico_label: lead.serviceLabel, empresa: lead.companyName, contato: lead.name, whatsapp: lead.phone, email: lead.email, cidade: lead.city, uf: lead.state, segmento: lead.segment, urgencia: lead.urgency, sistema_atual: lead.currentSystem, dores: lead.pains.join('; '), funcionarios: lead.employees, computadores: lead.computers, volume_whatsapp: lead.whatsappVolume, consentimento: lead.consent, proxima_acao: 'Tratamento manual', observacao: lead.message }; } export function processLead(input = {}, options = {}) { const lead = normalizeLead(input); const priority = prioritizeLead(lead); const commercialWhatsApp = options.commercialWhatsApp || process.env.GTI_COMMERCIAL_WHATSAPP || '{{GTI_COMMERCIAL_WHATSAPP}}'; return { lead, priority, crmRecord: buildCrmRecord(lead, priority), whatsapp: { internal: { to: commercialWhatsApp, message: buildInternalWhatsAppMessage(lead, priority) } }, nextAction: 'tratamento_manual' }; }