(function() { console.log("%cClientsdesk:%c Capture form script ativo e capturando formulários e visitas.","font-weight: bold; background: linear-gradient(to right, rgb(255, 94, 0), rgb(255, 166, 97)); -webkit-background-clip: text; color: transparent;","color: inherit;"); const WEBHOOK_FORM_URL = "https://webhooks.automacoesweb.online/webhook/capture-data"; const WEBHOOK_VISIT_URL = "https://webhooks.automacoesweb.online/webhook/track-visit"; const CLIENT_SCRIPT = "YzlkN2FmNWYtZTk0NS00YzZhLWFiY2UtMTk0MjNiZDdhOTJk.js"; // 🔄 Cache para evitar múltiplos envios do mesmo formulário const processedForms = new Set(); let visitSent = false; // Flag para enviar visita apenas uma vez function cleanURL(url) { return url.split(/[?#]/)[0]; } function generateUUID(url, formIndex) { const cleanedUrl = cleanURL(url); const data = cleanedUrl + "-form[" + formIndex + "]"; let hash = 0; for (let i = 0; i < data.length; i++) { const char = data.charCodeAt(i); hash = (hash << 5) - hash + char; hash |= 0; } return "form-" + Math.abs(hash); } function captureTrafficSource() { const params = new URLSearchParams(window.location.search); const referrer = document.referrer; // 🎯 Busca por UTMs no localStorage (campanha persistente) const storedUtms = JSON.parse(localStorage.getItem('clientsdesk_utms') || '{}'); const trafficData = { utm_source: params.get('utm_source') || storedUtms.utm_source, utm_medium: params.get('utm_medium') || storedUtms.utm_medium, utm_campaign: params.get('utm_campaign') || storedUtms.utm_campaign, utm_content: params.get('utm_content') || storedUtms.utm_content, utm_term: params.get('utm_term') || storedUtms.utm_term, gclid: params.get('gclid'), fbclid: params.get('fbclid'), msclkid: params.get('msclkid'), ttclid: params.get('ttclid'), li_fat_id: params.get('li_fat_id'), referrer: referrer, traffic_source: determineTrafficSource(referrer, params, storedUtms), landing_page: window.location.href, user_agent: navigator.userAgent, page_views: parseInt(sessionStorage.getItem('clientsdesk_page_views') || '1'), time_on_site: getTimeOnSite(), scroll_depth: getScrollDepth() }; // 💾 Salva UTMs no localStorage para persistir na sessão if (params.get('utm_source')) { const utmsToStore = { utm_source: params.get('utm_source'), utm_medium: params.get('utm_medium'), utm_campaign: params.get('utm_campaign'), utm_content: params.get('utm_content'), utm_term: params.get('utm_term'), captured_at: new Date().toISOString() }; localStorage.setItem('clientsdesk_utms', JSON.stringify(utmsToStore)); } return trafficData; } function determineTrafficSource(referrer, params, storedUtms) { if (params.get('utm_source')) return params.get('utm_source'); if (storedUtms.utm_source) return storedUtms.utm_source; if (params.get('gclid')) return 'google_ads'; if (params.get('fbclid')) return 'facebook_ads'; if (params.get('msclkid')) return 'microsoft_ads'; if (params.get('ttclid')) return 'tiktok_ads'; if (params.get('li_fat_id')) return 'linkedin_ads'; if (!referrer || referrer === '' || referrer === window.location.href) return 'direct'; const domain = referrer.toLowerCase(); if (domain.includes('google.com') || domain.includes('google.com.br')) return 'google_organic'; if (domain.includes('facebook.com')) return 'facebook_organic'; if (domain.includes('instagram.com')) return 'instagram'; if (domain.includes('linkedin.com')) return 'linkedin'; if (domain.includes('youtube.com')) return 'youtube'; if (domain.includes('twitter.com') || domain.includes('x.com')) return 'twitter'; if (domain.includes('whatsapp.com') || domain.includes('wa.me')) return 'whatsapp'; if (domain.includes('tiktok.com')) return 'tiktok'; return 'referral'; } function getTimeOnSite() { const startTime = sessionStorage.getItem('clientsdesk_start_time'); if (!startTime) { sessionStorage.setItem('clientsdesk_start_time', Date.now().toString()); return 0; } return Math.floor((Date.now() - parseInt(startTime)) / 1000); } function getScrollDepth() { const scrollTop = window.pageYOffset || document.documentElement.scrollTop; const scrollHeight = document.documentElement.scrollHeight - window.innerHeight; return scrollHeight > 0 ? Math.round((scrollTop / scrollHeight) * 100) : 0; } function captureUserData() { const pageViews = parseInt(sessionStorage.getItem('clientsdesk_page_views') || '0') + 1; sessionStorage.setItem('clientsdesk_page_views', pageViews.toString()); return { timestamp: new Date().toISOString(), timezone: Intl.DateTimeFormat().resolvedOptions().timeZone, language: navigator.language, screen_resolution: `${screen.width}x${screen.height}`, viewport: `${window.innerWidth}x${window.innerHeight}`, device_type: /Mobi|Android/i.test(navigator.userAgent) ? 'mobile' : 'desktop', browser: getBrowserInfo(), os: getOSInfo(), cookies_enabled: navigator.cookieEnabled, session_id: getOrCreateSessionId(), is_returning_visitor: isReturningVisitor(), visit_count: getVisitCount(), first_visit: getFirstVisit() }; } function getBrowserInfo() { const ua = navigator.userAgent; if (ua.includes('Chrome') && !ua.includes('Edge')) return 'Chrome'; if (ua.includes('Firefox')) return 'Firefox'; if (ua.includes('Safari') && !ua.includes('Chrome')) return 'Safari'; if (ua.includes('Edge')) return 'Edge'; if (ua.includes('Opera')) return 'Opera'; return 'Other'; } function getOSInfo() { const ua = navigator.userAgent; if (ua.includes('Windows')) return 'Windows'; if (ua.includes('Mac')) return 'macOS'; if (ua.includes('Linux')) return 'Linux'; if (ua.includes('Android')) return 'Android'; if (ua.includes('iOS')) return 'iOS'; return 'Other'; } function getOrCreateSessionId() { let sessionId = sessionStorage.getItem('clientsdesk_session'); if (!sessionId) { sessionId = 'session_' + Date.now() + '_' + Math.random().toString(36).substr(2, 9); sessionStorage.setItem('clientsdesk_session', sessionId); } return sessionId; } function isReturningVisitor() { return localStorage.getItem('clientsdesk_visitor') !== null; } function getVisitCount() { const count = parseInt(localStorage.getItem('clientsdesk_visit_count') || '0') + 1; localStorage.setItem('clientsdesk_visit_count', count.toString()); return count; } function getFirstVisit() { let firstVisit = localStorage.getItem('clientsdesk_first_visit'); if (!firstVisit) { firstVisit = new Date().toISOString(); localStorage.setItem('clientsdesk_first_visit', firstVisit); localStorage.setItem('clientsdesk_visitor', 'true'); } return firstVisit; } // 🆕 NOVA FUNÇÃO: Salvar visita à página function saveVisitData() { if (visitSent) return; // Evita múltiplos envios da mesma visita const visitPayload = { script: CLIENT_SCRIPT, page_url: window.location.href, url: cleanURL(window.location.href), pagetitle: document.title, traffic_data: captureTrafficSource(), user_data: captureUserData(), captured_at: new Date().toISOString() }; console.log("📍 Dados da visita capturados:", visitPayload); const xhr = new XMLHttpRequest(); xhr.open("POST", WEBHOOK_VISIT_URL); xhr.setRequestHeader("Content-Type", "application/json"); xhr.setRequestHeader("X-Client-Script", CLIENT_SCRIPT); xhr.onload = function() { if (xhr.status === 200) { console.log("✅ Visita registrada com sucesso!"); visitSent = true; } else { console.error("❌ Erro ao registrar visita:", xhr.status); } }; xhr.onerror = function() { console.error("❌ Erro de conexão ao registrar visita"); }; xhr.send(JSON.stringify(visitPayload)); } function findLabelText(element) { if (element.id) { const label = document.querySelector(`label[for="${element.id}"]`); if (label) return label.textContent.trim(); } const parentLabel = element.closest('label'); if (parentLabel) { return parentLabel.textContent.replace(element.value, '').trim(); } if (element.dataset.label) return element.dataset.label; if (element.placeholder) return element.placeholder; const prevElement = element.previousElementSibling; if (prevElement && ['SPAN', 'P', 'DIV', 'LABEL'].includes(prevElement.tagName)) { const text = prevElement.textContent.trim(); if (text && text.length < 100) return text; } return ''; } function getFieldType(element) { const name = (element.name || '').toLowerCase(); const id = (element.id || '').toLowerCase(); const label = findLabelText(element).toLowerCase(); const placeholder = (element.placeholder || '').toLowerCase(); const className = (element.className || '').toLowerCase(); const allText = `${name} ${id} ${label} ${placeholder} ${className}`; if (element.type === 'email' || /email|e-mail|mail/.test(allText)) return 'email'; if (element.type === 'tel' || /phone|telefone|celular|whatsapp|fone|tel/.test(allText)) return 'phone'; if (/full.*name|nome.*completo|nome$/.test(allText)) return 'full_name'; if (/first.*name|primeiro.*nome|nome.*proprio/.test(allText)) return 'first_name'; if (/last.*name|sobrenome|ultimo.*nome|surname/.test(allText)) return 'last_name'; if (/\bname\b|\bnome\b/.test(allText)) return 'name'; if (/company|empresa|organization|corporat/.test(allText)) return 'company'; if (/job.*title|cargo|posicao|funcao|position/.test(allText)) return 'job_title'; if (/website|site|url|www/.test(allText)) return 'website'; if (element.tagName === 'TEXTAREA' || /message|mensagem|comentario|observa|texto/.test(allText)) return 'message'; if (/subject|assunto|titulo|title/.test(allText)) return 'subject'; if (/city|cidade|municipio/.test(allText)) return 'city'; if (/state|estado|uf/.test(allText)) return 'state'; if (/cep|zip|postal/.test(allText)) return 'postal_code'; if (/address|endereco|rua|street/.test(allText)) return 'address'; return 'other'; } function detectFormType(form) { const formClass = form.className.toLowerCase(); const formId = form.id.toLowerCase(); const formHTML = form.outerHTML.toLowerCase(); if (formClass.includes('wpforms') || formId.includes('wpforms') || formHTML.includes('wpforms')) return 'wpforms'; if (formClass.includes('wpcf7') || formId.includes('wpcf7') || formHTML.includes('wpcf7')) return 'contact_form_7'; if (formClass.includes('gform') || formId.includes('gform') || formHTML.includes('gravity')) return 'gravity_forms'; if (formClass.includes('ninja') || formId.includes('ninja') || formHTML.includes('ninja')) return 'ninja_forms'; if (formClass.includes('elementor') || formId.includes('elementor')) return 'elementor'; if (formClass.includes('divi') || formId.includes('divi')) return 'divi'; if (formClass.includes('hubspot') || formId.includes('hubspot')) return 'hubspot'; return 'custom_html'; } function saveFormDetails(form, formIndex) { const formId = form.id || `form-${formIndex}`; const formUUID = generateUUID(window.location.href, formIndex); const formKey = `${formUUID}-${Date.now()}`; if (processedForms.has(formKey)) { console.log("🔄 Formulário já processado, ignorando..."); return; } processedForms.add(formKey); const formData = { action: form.action || "", method: form.method || "GET", classes: form.className || "", inputs: [] }; Array.from(form.elements).forEach(function(element) { if (["INPUT", "TEXTAREA", "SELECT"].includes(element.tagName)) { const fieldData = { tag: element.tagName, type: element.type || "", id: element.id || "", class: element.className || "", name: element.name || "", value: element.value || "", placeholder: element.placeholder || "", label: findLabelText(element), required: element.required || false, field_type: getFieldType(element), max_length: element.maxLength || null, pattern: element.pattern || null }; formData.inputs.push(fieldData); } }); const payload = { script: CLIENT_SCRIPT, url: cleanURL(window.location.href), rawUrl: window.location.href, pagetitle: document.title, formId, formUUID, formEntries: formData, formIndex, traffic_data: captureTrafficSource(), user_data: captureUserData(), captured_at: new Date().toISOString(), form_type: detectFormType(form) }; console.log("📊 Dados do formulário capturados:", payload); const xhr = new XMLHttpRequest(); xhr.open("POST", WEBHOOK_FORM_URL); xhr.setRequestHeader("Content-Type", "application/json"); xhr.setRequestHeader("X-Client-Script", CLIENT_SCRIPT); xhr.onload = function() { if (xhr.status === 200) { console.log("✅ Formulário enviado com sucesso!"); processedForms.delete(formKey); } else { console.error("❌ Erro ao enviar formulário:", xhr.status); } }; xhr.onerror = function() { console.error("❌ Erro de conexão ao enviar formulário"); }; setTimeout(() => { xhr.send(JSON.stringify(payload)); }, 100); } function observeFormSubmissions() { document.querySelectorAll('form').forEach(function(form, index) { if (form._clientsdeskHandler) { form.removeEventListener('submit', form._clientsdeskHandler); } form._clientsdeskHandler = function(event) { setTimeout(() => { saveFormDetails(form, index); }, 50); }; form.addEventListener('submit', form._clientsdeskHandler); }); console.log(`🔍 ${document.querySelectorAll('form').length} formulários encontrados e monitorados`); } // 🆕 Inicialização: Salva visita + monitora formulários function initializeTracking() { // 📍 Salva a visita após um pequeno delay para capturar scroll/tempo setTimeout(saveVisitData, 2000); // 📝 Inicia monitoramento de formulários if (document.readyState === 'loading') { document.addEventListener('DOMContentLoaded', observeFormSubmissions); } else { observeFormSubmissions(); } } // 🔄 Observer para formulários dinâmicos const observer = new MutationObserver(function(mutations) { let shouldReobserve = false; mutations.forEach(function(mutation) { if (mutation.type === 'childList') { mutation.addedNodes.forEach(function(node) { if (node.nodeType === 1) { if (node.tagName === 'FORM') { shouldReobserve = true; } else if (node.querySelector && node.querySelector('form')) { shouldReobserve = true; } } }); } }); if (shouldReobserve) { clearTimeout(observer.timeoutId); observer.timeoutId = setTimeout(observeFormSubmissions, 100); } }); observer.observe(document.body, { childList: true, subtree: true }); // 🧹 Limpeza de cache setInterval(() => { if (processedForms.size > 50) { processedForms.clear(); } }, 300000); // 🚀 Inicia o tracking initializeTracking(); console.log("🚀 ClientsDesk Tracking iniciado para:", CLIENT_SCRIPT); })();