lead

Form contatti con anti-spam

Form contatti riusabile con stack anti-spam stratificato: honeypot + time-trap + rate limit per IP/email + reCAPTCHA v3/Turnstile opzionale, validazione DNS MX, blacklist disposable, notifica admin mail/Telegram e archivio lead in DB con stato letto/in-lavorazione/chiuso.

Cosa fa questo modulo

Modulo «Form contatti con anti-spam»: componente building-block riusabile per la classica pagina/sezione «Contattaci» di un sito vetrina o landing, pensato per massimizzare il rapporto segnale/rumore filtrando tentativi bot, scraper e submit automatici senza penalizzare la UX dell'utente reale. Differenza concettuale rispetto a #8104 form-contatti-lead (form generico già censito): questa scheda formalizza specificamente lo **strato anti-spam stratificato** come modulo a sé, con architettura difensiva a più livelli, configurabile per cliente in base al volume di spam ricevuto e al budget servizi esterni (reCAPTCHA Enterprise costa, Turnstile gratis, hCaptcha freemium). Architettura difensiva (defense in depth, dal più leggero al più invasivo): **1) Honeypot field** — campo nascosto via CSS (`position:absolute;left:-9999px;opacity:0;tabindex=-1;autocomplete=off`) con name plausibile (`website`/`phone2`/`url`) che bot indiscriminati compilano automaticamente — se valorizzato → silent drop (200 OK fake per non rivelare la trappola), zero attrito utente; **2) Time-trap** — timestamp `_form_start_at` settato JS al rendering (o server side via signed token con TTL), submit prima di N secondi (default 3s) → drop, oltre M minuti (default 30min) → token scaduto, rinegoziare; **3) Rate limit per IP** (Laravel `RateLimiter::for('contact-form')` con `Limit::perMinute(5)->by($request->ip())` + `Limit::perHour(20)`), per email (max 3 submit/24h stessa email per evitare flood mirato di un singolo indirizzo), per fingerprint browser opzionale (User-Agent+Accept-Language+screen hash via fingerprintjs-pro lato JS); **4) Validazione email server-side** con `egulias/email-validator` (`RFCValidation` + `DNSCheckValidation` per record MX esistente, blocca `pippo@xyznondominio.invalid`), normalizzazione `strtolower+trim`, opzionale rimozione plus-addressing (`mario+spam@gmail.com` → `mario@gmail.com` per dedupe lead duplicati); **5) Blacklist domini disposable** (lista curata + libreria `disposable-email-domains` aggiornata cron mensile: mailinator/guerrillamail/yopmail/tempmail/10minutemail/etc — soft block con messaggio gentile «sembra un indirizzo temporaneo, usa una mail personale» + opt-in admin per allow temporaneo se cliente segnala falso positivo); **6) Validazione contenuto** (regex link count: >3 link nel body → flag spam, >5 → drop; lingua attesa via lib `php-language-detection` o euristica caratteri non-ASCII/cirillici per cliente IT → flag review; keyword blacklist configurabile in DB `spam_keywords` con weight scoring tipo Bayes leggero — `viagra/loan/crypto/SEO services/guest post` → score+1, soglia totale per drop vs hold-for-review); **7) reCAPTCHA v3 invisible (opzionale)** — Google score 0.0-1.0, soglia configurabile (default 0.5: <0.3 drop silenzioso, 0.3-0.5 hold review, >0.5 ok), site key + secret key in `.env` per cliente, fallback a Turnstile/hCaptcha se cliente preferisce non dipendere da Google (GDPR-friendlier); **8) Turnstile Cloudflare (alternativa)** — captcha invisible/managed gratuito, no profilazione cookies, GDPR-safer per mercato EU, endpoint verify server-side; **9) hCaptcha (alternativa)** — visible checkbox o invisible, freemium, opzione privacy-first. Modello dati: tabella `contact_leads` (id, name, email, phone nullable, subject, message text, source_url referrer, source_form variant slug, utm_source/medium/campaign/term/content per attribuzione, ip_address, user_agent, fingerprint nullable, locale rilevato, status enum `new`/`spam`/`review`/`replied`/`closed`/`archived`, spam_score float 0-1, spam_reasons JSON array (`["honeypot","time_trap","disposable_email","recaptcha_low_score","keyword_match"]`), assigned_to nullable FK user admin, replied_at, replied_by, internal_note text, tags JSON, gdpr_consent_privacy_at+ip, created_at/updated_at), tabella `contact_form_submissions_log` (audit raw payload per debug e antifraud — id+form_slug+payload JSON+ip+ua+result enum `accepted`/`dropped_honeypot`/`dropped_timetrap`/`dropped_ratelimit`/`dropped_invalid`/`dropped_recaptcha`/`hold_review`+timestamp, retention 90gg poi purge GDPR), tabella `spam_blocklist` (rule_type enum `email`/`domain`/`ip`/`keyword`/`country_code`, value, weight int, reason, created_by admin, expires_at nullable per ban temporanei, hit_count per stats), tabella `contact_form_configs` (per cliente/form slug: rate_limit_per_minute, rate_limit_per_hour, time_trap_min_seconds, recaptcha_threshold, captcha_provider enum `none`/`recaptcha_v3`/`turnstile`/`hcaptcha`, captcha_site_key, blacklist_disposable_bool, languages_allowed JSON, notify_emails JSON, notify_telegram_chat_id, notify_slack_webhook). Endpoint pubblici: `POST /contact/submit/{formSlug}` (validazione + anti-spam pipeline + persist + dispatch notify job; risposta 200 OK uniforme anche su silent drop honeypot per non rivelare difese), `GET /contact/health/{formSlug}` (endpoint diagnostico admin-only signed: ritorna config attiva + ultimi N drop con reason per tuning soglie). Pipeline di submission (ordine middleware): `ThrottleRequests:contact-form` → `VerifyHoneypot` (drop silenzioso se compilato) → `VerifyTimeTrap` (drop se <minSec o >maxSec) → `VerifyCaptcha` (se config provider≠none, chiama API verify, score injection nel request) → `FormRequest` Laravel validation (name min:2, email rfc+dns, message min:10 max:5000, gdpr_consent accepted) → `EmailDomainValidator` (MX + disposable blacklist) → `ContentSpamScorer` (link count + keyword bayes + language) → `LeadStoreAction` (persiste in `contact_leads` con `spam_score` + `spam_reasons` + status `new` o `review` o `spam` in base a soglia) → `DispatchNotificationJob` (mail admin via #8331 mail transazionali template branded con dettagli lead + link admin per reply, opz. Telegram via bot API chat_id config, opz. Slack incoming webhook, opz. SMS Twilio #8332 per lead high-value qualificati), → `RedirectToThankYouPage` (con flash success). Componente blade: `<x-contact.form variant="default|inline|sidebar|modal|fullpage" :form-slug="..." :fields="['name','email','phone','subject','message','privacy']" :captcha="auto|none|recaptcha|turnstile|hcaptcha" :time-trap-min="3" />` con: HTML5 native validation lato client per UX immediata (required, type=email, pattern phone), honeypot field hidden, hidden timestamp `_form_start_at` impostato via JS inline al mount (o server-side signed con TTL), data binding Livewire opzionale per submit AJAX con stati loading/success/error senza reload, integrazione captcha JS provider scelto (recaptcha v3 token execute on submit, Turnstile widget render, hCaptcha challenge), messaggi errore i18n IT/EN, accessibilità WCAG 2.1 AA (label esplicite, `aria-describedby` per errori, focus management post-submit). Admin CRUD: datatable Livewire #8327 `contact_leads` con filtri (status, spam_score range, source_form, range date, has_phone, assigned_to, tags), bulk actions (mark replied, assign, export #8328, mark spam batch + auto-aggiunge mittente a `spam_blocklist` email rule weight=10, archive), dettaglio lead con tab «Conversazione» (mail reply inline che invia da indirizzo `replies+{lead_id}@dominio.it` con header `In-Reply-To` per threading nel client mail cliente; risposte ricevute via webhook inbound parser Mailgun/Postmark/Brevo arrivano in tab come messaggi successivi del thread — mini-ticketing leggero), tab «Audit» con `contact_form_submissions_log` per debug perché lead è finito in spam, tab «Tecnico» con IP/UA/fingerprint/referrer/utm/ip-geo, dashboard analytics widget (lead totali periodo, % spam filtrato, top source_form per conversion, top spam_reason per tuning soglie, conversion lead → cliente effettivo se #8326 area cliente collegato, response time medio admin). Comandi artisan: `php artisan contact:purge-logs --older-than-days=90` (cron GDPR retention), `php artisan contact:update-disposable-domains` (refresh blacklist da fonti pubbliche), `php artisan contact:report-spam-stats {--month=}` (report tuning soglie: % drop per reason, falsi positivi segnalati admin, suggerimento threshold ottimale), `php artisan contact:cleanup-blocklist` (purga rule scadute e weight<1 mai hittate da 6 mesi), `php artisan contact:export-leads {--status=} {--format=csv|xlsx}`. Compliance GDPR: consenso privacy esplicito separato (checkbox unflagged default + link informativa + opzionale checkbox marketing separato per opt-in newsletter cross-modulo #8314), audit log immutabile `contact_form_submissions_log` retention configurabile, diritto oblio (cancellazione lead + log da admin con motivazione), no-tracking opt-in di default (no cookie analytics 3rd-party fino a banner consent), reCAPTCHA v3 documentato come trattamento dati Google nell'informativa (sub-responsabile) o sostituito con Turnstile per evitare. Compliance Italia: titolare + DPO + base giuridica art.6.1.b (esecuzione precontrattuale) per richieste commerciali + art.6.1.a consenso per marketing esplicito separato. Differenze e relazioni con altri moduli: **#8104 form-contatti-lead** è il modulo storico generico già censito (CRM-lite + export CSV + notifiche mail/Telegram, in pratica già usato su tutti i siti vetrina del workspace) — questa scheda #8313 ne formalizza lo strato anti-spam come prodotto dedicato e configurabile per scaling clienti con volume spam alto (es. siti B2B con form `info@`/`commerciale@` esposti a scraping massivo); **#8314 newsletter-signup-brevo-mailchimp** è opt-in marketing puro, no conversazione attesa — anti-spam pipeline simile (honeypot/timetrap/captcha) ma flusso DOI diverso; **#8316 lead-capture-multi-step** è qualificazione lead multi-step → riusa anti-spam pipeline ultimo step submit; **#8326 area cliente** può ricevere conversione lead in cliente registrato; **#8327 datatable Livewire** per admin CRUD leads; **#8328 export Excel/PDF** per export segmentati; **#8330 audit log azioni utente** può unificare `contact_form_submissions_log` come categoria audit; **#8331 mail transazionali con template** è dipendenza diretta per notifica admin lead + auto-reply «abbiamo ricevuto la tua richiesta» + reply admin con threading; **#8332 SMS gateway Twilio** opz. per notifica admin lead high-priority via SMS; **#8333 WhatsApp Business API** opz. per notifica/risposta admin via WhatsApp; **#8334 notifiche web push** opz. per dashboard admin notify nuovo lead in tempo reale. Casi d'uso workspace: Footility (pagina `/contatti` footility.com con form qualificazione richiesta workspace «di che progetto hai bisogno?» + dropdown progetto + descrizione, anti-spam su captcha Turnstile gratis dato volume basso), Klabhouse (form contatti pre-iscrizione corsi su `klabhouse.com/contatti` con campo «corso interesse» dropdown — alto volume spam scraper edu, Turnstile + honeypot + blacklist domini disposable + score Bayes su keyword `seo/backlink/guestpost`), Holiday Self Drive (form richiesta info veicolo `/contatti` + form richiesta preventivo flotta b2b separato `/business-contatti` con form-slug diverso e config rate-limit più alto e notify_emails sales team), gestionali B2B Casarile/Altramusica/LB advisory (form `/demo-richiesta` con qualifying questions `numero_dipendenti`/`giro_affari`/`fatturato_annuo` per qualifica pre-call, notify Slack channel sales con thread per ogni nuovo lead qualificato, anti-spam alto con reCAPTCHA Enterprise data sensibilità lead high-value), the-body-code/realpilates (form richiesta lezione prova `/lezione-prova` con scelta sede + giorno preferito → integra con #8323 calendario per proporre slot in auto-reply mail, anti-spam medio Turnstile sufficiente), mscarichi (form richiesta preventivo sopralluogo con upload foto camion/locale via #8336 file uploader, anti-spam medio + validazione phone IT con libphonenumber required perché preventivo richiede contatto telefonico), prontointervento (form emergenza 24/7 `/richiesta-urgente` con notify SMS Twilio #8332 immediato al tecnico reperibile + push web admin #8334, anti-spam basso `time_trap_min_seconds=1` perché urgenza prevale, ma honeypot+rate-limit attivi per evitare DoS form). Estensioni roadmap: AI classification lead pre-routing (LLM legge messaggio → categoria `commerciale`/`supporto`/`partnership`/`carriera`/`spam` → routing auto a inbox admin diverso), AI auto-reply draft (LLM genera bozza risposta che admin approva/edita prima invio — riduce time-to-reply medio), sentiment analysis lead urgente/incazzato → priority high + notify SMS, integrazione CRM esterno HubSpot/Pipedrive sync deal+contact, A/B test copy form (titolo+CTA+lunghezza) con conversion tracking per variante, conversational form chat-style (sostituisce form classico con chat 1-domanda-alla-volta in stile Typeform — alza conversion mobile), magic link follow-up (post-submit cliente riceve link area cliente passwordless #8326 per tracciare stato richiesta), webhook outbound configurabile (su nuovo lead, POST payload a URL esterno cliente per integrare con suo CRM custom). Anti-abuse avanzato (opt-in via config): GeoIP block paesi noti per scraping (CN/RU/IN se cliente non opera in quei mercati, override per casi business legittimi), reverse DNS check (mancanza PTR record per IP → flag), Cloudflare Bot Score sync se sito dietro Cloudflare proxy (header `cf-bot-score` <30 → drop), browser fingerprint via fingerprintjs-pro per detect headless puppeteer/playwright, behavior analytics opzionale (tempo medio digitazione campo email, pattern movimento mouse via trail JS — bot hanno traiettorie troppo lineari). Performance: pipeline anti-spam ottimizzata <200ms p95 (honeypot+timetrap immediati, validazione email DNS cached 24h per dominio, blacklist disposable in-memory cache Redis, captcha verify async non-blocking con score check post-submit + retry async se API provider lenta), endpoint submit idempotente (POST stesso payload+IP entro 5min → dedupe), persistent connection HTTP keep-alive verso API captcha provider per ridurre TLS handshake overhead. Costo nuovo modulo (work greenfield strato anti-spam strutturato, oltre #8104 form generico): 0.5g migrazioni `contact_form_configs`+`contact_form_submissions_log`+`spam_blocklist`+estensione `contact_leads` con campi spam_score/reasons, 1g pipeline middleware anti-spam (honeypot/timetrap/ratelimit/captcha verify) + interface `SpamFilterInterface` con N filtri concatenati e short-circuit, 0.5g integrazione provider captcha (reCAPTCHA v3 + Turnstile + hCaptcha) con factory driver-based via config, 0.5g `EmailDomainValidator` + cache MX + lib disposable + comando refresh, 0.5g `ContentSpamScorer` Bayes leggero + admin UI tuning weight keyword, 0.5g componente blade `<x-contact.form>` con varianti UI + Livewire AJAX + i18n + WCAG, 0.5g notifiche multi-canale (mail+Telegram+Slack+SMS opt) con job async retry, 0.5g admin datatable + dettaglio thread reply inline + audit tab + dashboard analytics spam tuning, 0.5g comandi artisan (purge-logs/update-disposable/report-spam-stats/cleanup-blocklist/export-leads), 0.5g compliance GDPR (consenso separato + retention + diritto oblio), 0.5g testing flussi (honeypot drop, timetrap min+max, rate-limit IP/email, captcha 0.2 score drop, MX invalid drop, disposable domain drop, keyword score hold review, lead valido → mail admin → reply threading, falso positivo unmark spam admin). Costo riuso nuovo cliente (modulo pronto): 0.25g config form-slug + scelta provider captcha + soglie rate-limit per volume cliente, 0.25g personalizzazione copy + branding + campi custom (es. dropdown progetto/corso/destinazione cliente-specific), 0.25g notify channel setup (mail destinatari, opz Telegram bot, opz Slack webhook), 0.25g test E2E (submit valido → admin notify → reply, submit honeypot → silent drop, rate-limit IP triggered). Dipendenze: Laravel 10/11 + Livewire 3 opz, `egulias/email-validator` per DNS MX, lib `disposable-email-domains` o equivalente, opz. `google/recaptcha` SDK PHP per v3, opz. Turnstile verify (HTTP semplice via Guzzle), opz. hCaptcha verify, opz. `giggsey/libphonenumber-for-php` per validazione telefono, opz. `php-language-detection` per lingua, mailer #8331 per notify admin + auto-reply + threading, opz. Telegram bot API token, opz. Slack incoming webhook, opz. #8332 SMS Twilio per notify high-priority, opz. #8326 area cliente per conversione lead → cliente registrato, opz. #8327 datatable Livewire admin, opz. #8328 export Excel/PDF, opz. #8330 audit log unificato, opz. #8334 web push notifica admin real-time, opz. Cloudflare Turnstile API key (gratis), opz. reCAPTCHA Enterprise per clienti high-value (a pagamento Google).

Esempi d'uso

  • lead

Disponibile nei pacchetti