1class AdHocAnalyst { 2 3 // Variabili di configurazione 4 region = "eu-south-1"; // Regione AWS 5 identityPoolId = "eu-south-1:56a7f634-bdc9-42f1-83e7-a2830ac50283"; // ID del pool di identità Cognito 6 docClient; // Client per interagire con DynamoDB 7 userId; // ID dell'utente 8 sessionId; // ID della sessione 9 labelUtente = "adhoc-analyst-user"; // Etichetta per il cookie dell'utente 10 labelSession = "adhoc-analyst-session"; // Etichetta per il cookie della sessione 11 labelTime = "adhoc-analyst-time"; // Etichetta per il cookie della sessione 12 tempoUtente = 365; // Durata del cookie dell'utente (in giorni) 13 tempoSessione = 1 / 24; // Durata del cookie della sessione (in giorni, equivalente a 1 ora) 14 click = 0; // Flag per il clic dell'utente 15 scrolling = 0; // Flag per lo scroll della pagina 16 trenta_secondi = 0; // Flag per il tempo di 30 secondi 17 durataSessione = 0; // Durata della sessione 18 skipCheck = false; // Flag per saltare il controllo iniziale 19 intervalloTime = false; 20 elementiClickParentDaEscludere = ["#cconsent-bar"]; 21 elementiClickEvento = [ 22 { 23 selector: ".ahe_stampa_button", 24 evento: "stampa_button", 25 to: ["gtmweb"] 26 }, 27 { 28 selector: ".ahe_optional_view", 29 evento: "optional_view", 30 to: ["gtmweb"] 31 }, 32 { 33 selector: ".ahe_info_prezzo_view", 34 evento: "info_prezzo_view", 35 to: ["gtmweb"] 36 }, 37 { 38 selector: ".ahe_click_call", 39 evento: "click_call", 40 to: ["gtmweb", "tagmanagerserver"] 41 }, 42 { 43 selector: ".chatbot-toggle-btn", 44 evento: "click_chat", 45 to: ["gtmweb", "tagmanagerserver"] 46 }, 47 { 48 selector: ".ahe_click_messenger", 49 evento: "click_messenger", 50 to: ["gtmweb", "tagmanagerserver"] 51 }, 52 { 53 selector: ".ahe_click_whatsapp", 54 evento: "click_whatsapp", 55 to: ["gtmweb", "tagmanagerserver"] 56 }, 57 { 58 selector: ".ahe_click_calendly", 59 evento: "click_calendly", 60 to: ["gtmweb", "tagmanagerserver"] 61 }, 62 { 63 // Da sistemare perchè non funziona. Problema potrebbe essere in public.js su on click di add-comparatore 64 selector: ".add-comparatore", 65 evento: "add_wishlist", 66 to: ["gtmweb", "tagmanagerserver"] 67 }, 68 { 69 selector: ".btn-favorite", 70 evento: "add_wishlist", 71 to: ["gtmweb", "tagmanagerserver"] 72 } 73 ]; 74 urlTagManager = "https://tagmanager.adhc.it/"; 75 76 77 // Funzione per il rendering iniziale 78 render() { 79 80 if (window.location.hostname.includes("romana-auto.it") || window.location.hostname.includes("romanaauto.locl")) { 81 this.urlTagManager = "https://tagmanager.romana-auto.it/"; 82 } 83 84 if (window.location.hostname.includes("romana-auto-viterbo.it") || window.location.hostname.includes("romanaautoviterbo.locl")) { 85 this.urlTagManager = "https://tagmanager.romana-auto-viterbo.it/"; 86 } 87 88 if (window.location.hostname.includes("jazzoni.com") || window.location.hostname.includes("jazzoni.locl")) { 89 this.urlTagManager = "https://tagmanager.jazzoni.com/"; 90 } 91 92 if (window.location.hostname.includes("autoceriani.it") || window.location.hostname.includes("cerianiusato.locl")) { 93 this.urlTagManager = "https://tagmanager.autoceriani.it/"; 94 } 95 96 if (window.location.hostname.includes("erreti-auto.com") || window.location.hostname.includes("erretiauto.locl")) { 97 this.urlTagManager = "https://tagmanager.erreti-auto.com/"; 98 } 99 100 if (window.location.hostname.includes("autouau.it") || window.location.hostname.includes("autouau.locl")) { 101 this.urlTagManager = "https://tagmanager.autouau.it/"; 102 } 103 104 // Carica lo script AWS SDK 105 const script = document.createElement('script'); 106 script.src = "https://sdk.amazonaws.com/js/aws-sdk-2.1486.0.min.js"; 107 script.onload = () => { 108 109 if (navigator.userAgent != null && ( 110 navigator.userAgent.toLowerCase().includes("bot") || 111 navigator.userAgent.toLowerCase().includes("spider") || 112 navigator.userAgent.toLowerCase().includes("crawl") || 113 navigator.userAgent.toLowerCase().includes("slurp") || 114 navigator.userAgent.toLowerCase().includes("curl") || 115 navigator.userAgent.toLowerCase().includes("wget") 116 )) { 117 return; 118 } 119 120 // Configura AWS con la regione e le credenziali Cognito 121 AWS.config.update({ 122 region: this.region, 123 credentials: new AWS.CognitoIdentityCredentials({ 124 IdentityPoolId: this.identityPoolId, 125 }), 126 }); 127 128 this.docClient = new AWS.DynamoDB.DocumentClient(); // Inizializza il client DynamoDB 129 130 this.getUtente(); // Ottieni o crea l'utente 131 132 // Aggiungi un listener per il click 133 document.addEventListener('click', (event) => { 134 135 // Se l'elemento cliccato è un elemento padre da escludere, non fare nulla 136 if (this.elementiClickParentDaEscludere.some(selector => event.target.closest(selector))) { 137 return; 138 } 139 140 if (this.click == 0) { 141 this.click = 1; // Imposta il flag del clic 142 this.aggiornaClick(); 143 } 144 145 this.elaboraClick(event); // Elabora il clic dell'utente 146 }); 147 148 // Aggiungi un listener per lo scroll 149 document.addEventListener('scroll', (event) => { 150 if (this.scrolling == 0) { 151 this.scrolling = 1; // Imposta il flag dello scroll 152 // this.aggiornaScrolling(); 153 // Mando evento scroll ad gtmweb 154 this.eventsToGTMWeb("scrolling"); 155 } 156 }); 157 158 this.intervalloTime = setInterval(() => { 159 this.checkTime(); 160 }, 1000); 161 162 // Mando evento pageview a Tag Manager Server 163 this.eventsToTagManagerServer("custom_page_view"); 164 165 // se la url della pgina contiene /thankyou, mando evento lead ad gtmweb e Tag Manager Server 166 if (window.location.href.includes("/thankyou-appuntamento")) { 167 this.eventsToGTMWeb("lead_appuntamento"); 168 this.eventsToTagManagerServer("lead_appuntamento"); 169 } else if (window.location.href.includes("/thankyou")) { 170 this.eventsToGTMWeb("lead"); 171 this.eventsToTagManagerServer("lead"); 172 } 173 174 }; 175 document.head.appendChild(script); // Aggiungi lo script al documento 176 } 177 178 // Funzione per elaborare il clic dell'utente 179 elaboraClick(event) { 180 181 for (const elem of this.elementiClickEvento) { 182 const targetMatch = event.target.closest(elem.selector); 183 if (targetMatch) { 184 for (const to of elem.to) { 185 if (to == "gtmweb") { 186 this.eventsToGTMWeb(elem.evento); 187 } 188 if (to == "tagmanagerserver") { 189 this.eventsToTagManagerServer(elem.evento); 190 } 191 } 192 break; // Esci dal ciclo se vuoi gestire solo il primo match 193 } 194 } 195 196 } 197 198 eventsToGTMWeb(eventName) { 199 window.dataLayer = window.dataLayer || []; 200 window.dataLayer.push({ 201 'event': eventName 202 }); 203 } 204 205 eventsToTagManagerServer(eventName) { 206 // Invio a tag manager tramite Tag Manager Server Side tagmanager.adhc.it c
206on fetch 207 208 var valoreCookieConsent = this.getCookie("cconsentc"); 209 valoreCookieConsent = JSON.parse(valoreCookieConsent); 210 if (valoreCookieConsent.categories.marketing_cookie.wanted == true) { 211 212 var body = { 213 "event_name": eventName, 214 "page_url": window.location.href, 215 "page_title": document.title, 216 "user_agent": navigator.userAgent, 217 "language": navigator.language 218 }; 219 220 if (this.sessionId != undefined) { 221 body.session_id = this.sessionId; // Aggiungi l'ID della sessione se disponibile 222 } 223 if (this.userId != undefined) { 224 body.user_id = this.userId; // Aggiungi l'ID dell'utente se disponibile 225 } 226 227 var url = this.urlTagManager + "ah-event"; 228 229 var headers = { 230 'Content-Type': 'application/json', 231 'Origin': window.location.origin 232 }; 233 234 // se in origin trovo .locl allora metto anche server-preview 235 if (window.location.origin.includes(".locl")) { 236 headers['x-gtm-server-preview'] = 'ZW52LTN8dk13WmhMWF94ZF82TmlPWkdoUlh2Z3wxOTZlODliNDBmOTA5ZDA3NzljMGU='; 237 } 238 239 fetch(url, { 240 method: 'POST', 241 headers: headers, 242 body: JSON.stringify(body), 243 credentials: 'include' 244 }); 245 } 246 } 247 248 aggiornaScrolling() { 249 if (this.sessionId == undefined) { 250 setTimeout(() => { 251 this.aggiornaScrolling(); 252 }, 1000); 253 } else { 254 this.editSession(this.sessionId, "scrolling", 1); 255 } 256 } 257 258 aggiornaClick() { 259 if (this.sessionId == undefined) { 260 setTimeout(() => { 261 this.aggiornaClick(); 262 }, 1000); 263 } else { 264 this.editSession(this.sessionId, "click", 1); 265 } 266 } 267 268 // Funzione per il controllo del tempo di permanenza 269 checkTime() { 270 var tempoPassato = 0; 271 if (this.getCookie(this.labelTime)) { 272 tempoPassato = parseInt(this.getCookie(this.labelTime)); 273 } 274 tempoPassato++; 275 if (tempoPassato >= 30) { 276 this.editSession(this.sessionId, "trenta_secondi", 1); // Modifica la sessione nel database 277 tempoPassato = 0; 278 clearInterval(this.intervalloTime); 279 } 280 this.setCookie(this.labelTime, tempoPassato, 365); 281 } 282 283 // Modifica una sessione nel database DynamoDB 284 editSession(sessione, campo, valore) { 285 286 var refThis = this; 287 288 // Recupera i dati dell'utente da DynamoDB 289 this.docClient.get({ 290 TableName: "Sessioni", 291 Key: { 292 "identificativo": sessione // Usa l'ID dell'utente per la chiave primaria 293 } 294 }, function (err, data) { 295 if (err) { 296 refThis.scriviErrore("Errore nel recupero della sessione " + sessione + " per modifica campo " + campo + ": " + err); 297 } 298 if (data) { 299 if (data.Item) { 300 var u = data.Item; // Dati dell'utente 301 u[campo] = valore; // Aggiorna il campo della sessione 302 refThis.editElement("Sessioni", u); // Modifica l'elemento nel database 303 } 304 } 305 }); 306 307 } 308 309 scriviErrore(testo) { 310 311 // Se il testo contiene RequestAbortedError: Request aborted, non scrivere l'errore 312 if (testo.includes("RequestAbortedError: Request aborted")) { 313 return; 314 } 315 316 // Se il testo contiene NetworkingError: Network Failure, non scrivere l'errore 317 if (testo.includes("NetworkingError: Network Failure")) { 318 return; 319 } 320 321 var identificativo = this.generateUUID(); 322 var formattedDate = this.getDate(); 323 324 var errore = { 325 identificativo: identificativo, 326 data_creazione: formattedDate, 327 testo: testo 328 } 329 330 this.addElement("Errori", errore); // Aggiungi l'errore al database 331 } 332 333 aggiungiPaginaSessione(sessione) { 334 335 var refThis = this; 336 337 // Recupera i dati della sessione da DynamoDB 338 this.docClient.get({ 339 TableName: "Sessioni", 340 Key: { 341 "identificativo": sessione // Usa l'ID della sessione per la chiave primaria 342 } 343 }, function (err, data) { 344 if (err) { 345 refThis.scriviErrore("Errore nell'aggiunta della pagina: " + err); 346 } 347 if (data) { 348 if (data.Item) { 349 var u = data.Item; // Dati dell'utente 350 351 var formattedDate = refThis.getDate(); // Ottieni la data di creazione 352 353 if (u.pagine == undefined) { 354 u.pagine = []; // Inizializza la lista delle pagine vuota 355 } 356 357 u.pagine.push({ // Aggiungi la pagina alla sessione 358 url: window.location.href, // URL della pagina 359 data_ingresso: formattedDate, // Data di ingresso 360 tag: refThis.getTagPagina() // Tag della pagina 361 }); 362 } 363 } 364 365 refThis.editElement("Sessioni", u); // Modifica l'elemento nel database 366 367 }); 368 } 369 370 // Modifica un elemento nel database DynamoDB 371 editElement(table, dati) { 372 373 var refThis = this; 374 375 const params = { 376 TableName: table, // Nome della tabella 377 Key: { 378 "identificativo": dati.identificativo // Usa l'ID dell'utente per la chiave primaria 379 }, 380 UpdateExpression: "set click = :c, scrolling = :s, trenta_secondi = :t, pagine = :p", // Espressione di aggiornamento 381 ExpressionAttributeValues: { // Valori delle espressioni 382 ":c": dati.click, 383 ":s": dati.scrolling, 384 ":t": dati.trenta_secondi, 385 ":p": dati.pagine 386 }, 387 ReturnValues: "UPDATED_NEW" // Restituisce i nuovi valori aggiornati 388 }; 389 390 // Esegui l'aggiornamento nella tabella DynamoDB 391 this.docClient.update(params, function (err, data) { 392 if (err) { 393 refThis.scriviErrore("Errore nell'aggiornamento: " + err); 394 } 395 }); 396 397 } 398 399 // Aggiunge un nuovo elemento nella tabella DynamoDB 400 async addElement(table, dati) { 401 402 var refThis = this; 403 404 return new Promise((resolve, reject) => { 405 const params = { 406 TableName: table, // Nome della tabella 407 Item: dati // Dati dell'elemento da inserire 408 }; 409 410 // Inserisci l'elemento nel database 411 this.docClient.put(params, function (err, data) { 412 if (err) { 413 refThis.scriviErrore("Errore nell'aggiunta: " + err); 414 415 if (table == "Utenti_automotive") { 416 // cancella il cookie dell'utente 417 refThis.setCookie(refThis.labelUtente, "", -1); 418 refThis.getUtente(); 419 } 420 421 if (table == "Sessioni") { 422 // cancella il cookie della sessione 423 refThis.setCookie(refThis.labelSession, "", -1); 424 refThis.getSession(refThis.userId); 425 } 426 } 427 resolve(data); // Risolvi la promessa con i dati 428 }); 429 }); 430 } 431 432 // Ottiene o crea l'utente 433 async getUtente() { 434 435 // Se il cookie esiste, aggiorna la durata del cookie 436 if (!this.skipCheck && this.getCookie(this.labelUtente)) { 437 this.setCookie(this.labelUtente, this.getCookie(this.labelUtente), this.tempoUtente); 438 this.userId = this.getCookie(this.labelUtente); 439 } else { 440 // Se non esiste il cookie, crea un nuovo ID utente 441 var user = this.generateUUID(); 442 this.setCookie(this.labelUtente, user, this.tempoUtente); 443 444 // Ottieni la data di creazione 445 var formattedDate = this.getDate(); 446 447 // Crea un oggetto utente 448 var utente = { 449 identificativo: user, 450 data_ora: formattedDate.substring(0, 13), 451 data_creazione: formattedDate, 452 user_agent: navigator.userAgent ?? "", // User agent del browser 453 language: navigator.language ?? "", // Lingua del browser 454 ip: this.getIpPagina() 455 } 456 await this.addElement("Utenti_automotive", utente); // Aggiungi l'utente al database 457 this.userId = user; 458 } 459 460 // Ottieni la sessione dell'utente
461 await this.getSession(this.userId); 462 } 463 464 // Ottiene la sessione dell'utente 465 async getSession(utente) { 466 467 // Ottieni i parametri utm e referrer 468 var utmSource = this.getValoreTracciamento("utm_source"); 469 var utmMedium = this.getValoreTracciamento("utm_medium"); 470 var utmCampaign = this.getValoreTracciamento("utm_campaign"); 471 var gclid = this.getValoreTracciamento("gclid"); 472 var fbclid = this.getValoreTracciamento("fbclid"); 473 474 var referral = document.referrer == "" ? "Diretto" : document.referrer; 475 if (referral != "") { 476 this.setCookie("adhoc-analyst-referral", referral, 365); 477 } else { 478 referral = this.getCookie("adhoc-analyst-referral") ? this.getCookie("adhoc-analyst-referral") : ""; 479 } 480 481 // Controlla se la sessione esiste già nei cookie 482 if (!this.skipCheck && this.getCookie(this.labelSession)) { 483 var sessionJson = this.getCookie(this.labelSession); 484 var sessionArray = JSON.parse(sessionJson); 485 if ( 486 (sessionArray.utm_source == utmSource || utmSource == "") && 487 (sessionArray.utm_medium == utmMedium || utmMedium == "") && 488 (sessionArray.utm_campaign == utmCampaign || utmCampaign == "") && 489 (sessionArray.gclid == gclid || gclid == "") && 490 (sessionArray.fbclid == fbclid || fbclid == "") 491 ) { 492 // Se la sessione è valida, aggiorna il cookie 493 this.setCookie(this.labelSession, JSON.stringify(sessionArray), this.tempoSessione); 494 this.sessionId = sessionArray.id; 495 this.aggiungiPaginaSessione(sessionArray.id); 496 return; 497 } 498 } 499 500 // Se non esiste la sessione, crea una nuova sessione 501 var sessionId = this.generateUUID(); 502 503 // Crea un array di sessione 504 sessionArray = { 505 id: sessionId, 506 utm_source: utmSource, 507 utm_medium: utmMedium, 508 utm_campaign: utmCampaign, 509 referrer: referral, 510 gclid: gclid, 511 fbclid: fbclid 512 }; 513 514 // Imposta il cookie della sessione 515 this.setCookie(this.labelSession, JSON.stringify(sessionArray), this.tempoSessione); 516 517 // Ottieni la data di creazione della sessione 518 var formattedDate = this.getDate(); 519 520 var tagPagina = this.getTagPagina(); 521 522 var cookieWorking = false; 523 var cookieTesting = this.setCookie("adhoc-analyst-test", "test", 1); 524 if (this.getCookie("adhoc-analyst-test") == "test") { 525 cookieWorking = true; 526 } 527 528 // Crea un oggetto sessione 529 var sessione = { 530 identificativo: sessionArray.id, 531 data_ora: formattedDate.substring(0, 13), 532 data_creazione: formattedDate, 533 referral: sessionArray.referrer, 534 click: 0, 535 scrolling: 0, 536 trenta_secondi: 0, 537 tag: tagPagina, 538 ip: this.getIpPagina(), 539 utente: utente, 540 utm_source: sessionArray.utm_source, 541 utm_medium: sessionArray.utm_medium, 542 utm_campaign: sessionArray.utm_campaign, 543 gclid: sessionArray.gclid, 544 fbclid: sessionArray.fbclid, 545 cookie_working: cookieWorking, 546 url_atterraggio: window.location.href, // URL di atterraggio 547 pagine: [ 548 { 549 url: window.location.href, // URL della pagina 550 data_ingresso: formattedDate, // Data di ingresso 551 tag: tagPagina, // Tag della pagina 552 ip: this.getIpPagina(), // IP della pagina 553 } 554 ] 555 } 556 557 // Aggiungi la sessione al database 558 await this.addElement("Sessioni", sessione); 559 560 this.sessionId = sessionArray.id; // Imposta l'ID della sessione 561 return; 562 } 563 564 getTagPagina() { 565 // Se esiste un input con id tag_pagina, restituisci il valore, altrimenti 0 566 var tagPagina = document.getElementById("tag_pagina"); 567 if (tagPagina) { 568 return tagPagina.value; 569 } else { 570 return 0; 571 } 572 } 573 574 getIpPagina() { 575 // Se esiste un input con id ip_pagina, restituisci il valore, altrimenti 0 576 var ipPagina = document.getElementById("ip_pagina"); 577 if (ipPagina) { 578 return ipPagina.value; 579 } else { 580 return ""; 581 } 582 } 583 584 // Funzione per ottenere i parametri URL 585 getUrlParameter(sParam) { 586 var sPageURL = window.location.search.substring(1), 587 sURLVariables = sPageURL.split('&'), 588 sParameterName, 589 i; 590 for (i = 0; i < sURLVariables.length; i++) { 591 sParameterName = sURLVariables[i].split('='); 592 if (sParameterName[0] === sParam) { 593 return typeof sParameterName[1] === undefined ? true : decodeURIComponent(sParameterName[1]); 594 } 595 } 596 return false;
597 }; 598 599 getValoreTracciamento(key) { 600 var valore = this.getUrlParameter(key) ? this.getUrlParameter(key) : ""; 601 if (valore != "") { 602 this.setCookie("adhoc-analyst-" + key, valore, 365); 603 } else { 604 valore = this.getCookie("adhoc-analyst-" + key) ? this.getCookie("adhoc-analyst-" + key) : ""; 605 } 606 return valore; 607 } 608 609 // Funzione per ottenere la data formattata 610 getDate() { 611 var options = { 612 timeZone: 'Europe/Rome', 613 year: 'numeric', 614 month: '2-digit', 615 day: '2-digit', 616 hour: '2-digit', 617 minute: '2-digit', 618 second: '2-digit' 619 }; 620 var formatter = new Intl.DateTimeFormat('it-IT', options); 621 var parts = formatter.formatToParts(new Date()); 622 var dataAdesso = parts.reduce((acc, part) => { 623 if (part.type !== 'literal') { 624 acc[part.type] = part.value; 625 } 626 return acc; 627 }, {}); 628 var formattedDate = `${dataAdesso.year}-${dataAdesso.month}-${dataAdesso.day} ${dataAdesso.hour}:${dataAdesso.minute}:${dataAdesso.second}`; 629 630 return formattedDate; 631 } 632 633 // Funzione per generare un UUID 634 generateUUID() { 635 var d = new Date().getTime(); 636 if (typeof performance !== 'undefined' && typeof performance.now === 'function') { 637 d += performance.now(); 638 } 639 return 'xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx'.replace(/[xy]/g, function (c) { 640 var r = (d + Math.random() * 16) % 16 | 0; 641 d = Math.floor(d / 16); 642 return (c === 'x' ? r : (r & 0x3 | 0x8)).toString(16); 643 }); 644 } 645 646 // Funzione per impostare un cookie 647 setCookie(cname, cvalue, exdays) { 648 var d = new Date(); 649 d.setTime(d.getTime() + (exdays * 24 * 60 * 60 * 1000)); 650 var expires = "expires=" + d.toUTCString(); 651 document.cookie = cname + "=" + cvalue + ";" + expires + ";path=/"; 652 } 653 654 // Funzione per ottenere un cookie 655 getCookie(cname) { 656 var name = cname + "="; 657 var ca = document.cookie.split(';'); 658 for (var i = 0; i < ca.length; i++) { 659 var c = ca[i]; 660 while (c.charAt(0) == ' ') { 661 c = c.substring(1); 662 } 663 if (c.indexOf(name) == 0) { 664 return c.substring(name.length, c.length); 665 } 666 } 667 return false; 668 } 669 670} 671 672// Crea e avvia l'istanza di AdHocAnalyst 673const adHocAnalyst = new AdHocAnalyst(); 674adHocAnalyst.render();
Line numbers count LF bytes from the start of the resource, as the search results do. Vendor segments are library code the classifier recognised; they are stored but not indexed. Bytes are shown as Latin1 characters, one per byte.