PageSourceSearch

https://www.accademiamoda.it/wp-content/themes/iuad-theme/src/js/chat/botpress.js?ver=1.0.0

js accademiamoda.it collected 2026-10-04 13:24:00 UTC 19,034 bytes, 562 lines download raw bytes

1let restarted = false;
2let __iuadLastLeadKey = null;
3
4function iuadGetCrmEndpoint() {
5  if (window.iuadChat && typeof window.iuadChat.endpoint === 'string' && window.iuadChat.endpoint) {
6    return window.iuadChat.endpoint
7  }
8  return null
9}
10
11function iuadGetLangFallback() {
12  const htmlLang = (document && document.documentElement && document.documentElement.lang) ? document.documentElement.lang : ''
13  return (typeof htmlLang === 'string' && htmlLang.toLowerCase().startsWith('en')) ? 'en' : 'it'
14}
15
16function iuadNormalizeLang(lang) {
17  if (!lang || typeof lang !== 'string') return null
18  const s = lang.trim().toLowerCase()
19  if (!s) return null
20  const base = s.split(/[_-]/)[0]
21  if (base === 'en' || base === 'it') return base
22  return null
23}
24
25function iuadGetCookie(name) {
26  try {
27    const cookieStr = (typeof document !== 'undefined' && typeof document.cookie === 'string') ? document.cookie : ''
28    if (!cookieStr) return null
29    const parts = cookieStr.split(';')
30    for (let i = 0; i < parts.length; i++) {
31      const p = parts[i].trim()
32      if (!p) continue
33      if (p.startsWith(name + '=')) {
34        return decodeURIComponent(p.substring(name.length + 1))
35      }
36    }
37  } catch (e) {}
38  return null
39}
40
41function iuadGetWpmlCurrentLang() {
42  // 1) Alcune installazioni espongono un oggetto globale WPML
43  const fromWpmlGlobal =
44    iuadNormalizeLang(window?.wpml?.current_language) ||
45    iuadNormalizeLang(window?.wpml?.language) ||
46    iuadNormalizeLang(window?.WPML?.current_language) ||
47    iuadNormalizeLang(window?.WPML?.language)
48  if (fromWpmlGlobal) return fromWpmlGlobal
49
50  // 2) Cookie WPML (tipicamente: wp-wpml_current_language)
51  const fromCookie =
52    iuadNormalizeLang(iuadGetCookie('wp-wpml_current_language')) ||
53    iuadNormalizeLang(iuadGetCookie('wpml_current_language'))
54  if (fromCookie) return fromCookie
55
56  // 3) Classi sul body (es. lang-it / lang-en)
57  try {
58    const cls = (document && document.body && document.body.classList) ? Array.from(document.body.classList) : []
59    for (let i = 0; i < cls.length; i++) {
60      const m = /^lang-([a-z]{2})(?:[_-][a-z]{2})?$/.exec(String(cls[i]).toLowerCase())
61      if (m && m[1]) {
62        const normalized = iuadNormalizeLang(m[1])
63        if (normalized) return normalized
64      }
65    }
66  } catch (e) {}
67
68  return null
69}
70
71function iuadGetCurrentLang() {
72  return (
73    iuadNormalizeLang(window?.iuadChat?.lang) ||
74    iuadGetWpmlCurrentLang() ||
75    iuadNormalizeLang(document?.documentElement?.lang) ||
76    iuadGetLangFallback()
77  )
78}
79
80function iuadNormalizeCorsiToLabels(corsi) {
81  if (typeof corsi === 'string') {
82    const t = corsi.trim()
83    return t ? [t] : []
84  }
85  if (Array.isArray(corsi)) {
86    return corsi.map((item) => String(item == null ? '' : item).trim()).filter(Boolean)
87  }
88  if (corsi != null) {
89    return [String(corsi).trim()].filter(Boolean)
90  }
91  return []
92}
93
94// Helper per mappare il testo del corso nello slug atteso dal CRM (stessa logica di chat.js)
95function iuadMapCourseLabelToSlug(courseLabel) {
96  const label = String(courseLabel == null ? '' : courseLabel).trim()
97  if (!label) {
98    return '';
99  }
100
101  switch (label) {
102    case 'Regia per il Cinema e la Pubblicità':
103      return 'regia per il cinema e la pubblicità';
104    case 'Design e Architettura degli Interni':
105      return 'design e architettura degli interni';
106    case 'Game Design':
107      return 'game design';
108    case 'Design della Comunicazione':
109      return 'design della comunicazione';
110    case 'Design della Moda':
111      return 'design della moda';
112    case 'Design della moda indirizzo Business & Management':
113      return 'corso triennale di i livello in design della moda indirizzo fashion business & management';
114    case 'Art direction & Copywriting':
115      return 'art direction & copywriting';
116    case 'Design dell\'Accessorio':
117      return 'design accessorio';
118    case 'Disegno Tecnico per la Moda 2D - 3D':
119      return 'master in disegno tecnico per la moda';
120    case 'Borse e Pelletteria':
121      return 'master in borse e pelletteria';
122    case 'Design di Calzature':
123      return 'design di calzature';
124    case 'Interior designer 2D/3D':
125      return 'arredatore d\'interni e operatore cad 2d e 3d';
126    case 'Visual Merchandiser':
127      return 'visual merchandiser';
128    case '3D Virtual Fashion':
129      return 'virtual fashion 3d';
130    case 'Modellista Industriale Tessile Abbigliamento T.U.':
131      return 'modellista industriale tessile abbigliamento t.u.';
132    case 'Modellista Tecnico CAD':
133      return 'modellista operatore cad';
134    case 'Modellista Borse':
135      return 'modellista borse';
136    case 'Modellista Borse CAD':
137      return 'modellista borse cad';
138    case 'Fashion Illustrator':
139      return 'fashion illustrator';
140    case 'Fashion Designer Tecnico CAD':
141      return 'fashion designer operatore cad';
142    case 'Modellista Calzature':
143      return 'modellista per calzature';
144    case 'Modellista Calzature CAD':
145      return 'modellista calzature cad';
146    case 'Content Creator, Storytelling e Produzione Digitale':
147      return 'content creation storytelling e produzione digitale';
148
149    // ENGLISH
150    case 'Cinema and Advertising Direction':
151      return 'regia per il cinema e la pubblicità';
152    case 'Design and Interior Architecture':
153      return 'design e architettura degli interni';
154    case 'Game Design':
155      return 'game design';
156    case 'Communication Design':
157      return 'design della comunicazione';
158    case 'Fashion Design':
159      return 'design della moda';
160    case 'Fashion Design Business & Management':
161      return 'corso triennale di i livello in design della moda indirizzo fashion business & management';
162    case 'Fashion Illustrator':
163      return 'fashion illustrator';
164    case 'Art Direction & Copywriting':
165      return 'art direction & copywriting';
166    case 'Accessory Design':
167      return 'design accessorio';
168    case 'Technical Drawing for fashion 2D-3D':
169      return 'master in disegno tecnico per la moda';
170    case 'Handbags and Leather Goods Design':
171      return 'master in borse e pelletteria';
172    case 'Footwear Design':
173      return 'design di calzature';
174    case '2D/3D Interior Designer':
175      return 'arredatore d\'interni e operatore cad 2d e 3d';
176    case 'Visual Merchandiser':
177      return 'visual merchandiser';
178    case '3D Virtual Fashion':
179      return 'virtual fashion 3d';
180    case 'Industrial Patternmaker for Textiles and Clothing (T.U.)':
181      return 'modellista industriale tessile abbigliamento t.u.';
182    case 'Industrial Patternmaker':
183      return 'modellista industriale tessile abbigliamento t.u.';
184    case 'Industrial Patternmaker CAD Operator':
185      return 'modellista operatore cad';
186    case 'Bag Patternmaker':
187      return 'modellista borse';
188    case 'Bag Patternmaker CAD Operator':
189      return 'modellista borse cad';
190    case 'Fashion Designer CAD Operator':
191      return 'fashion designer operatore cad';
192    case 'Footwear Patternmaker':
193      return 'modellista per calzature';
194    case 'Footwear Patternmaker CAD':
195      return 'modellista calzature cad';
196    case 'Content Creator, Storytelling and Digital Production':
197      return 'content creation storytelling e produzione digitale';
198    default:
199      console.warn('[IUAD Botpress] Valore corso non riconosciuto:', label);
200      return 'design della moda';
201  }
202}
203
204let userUpdated = false
205const translations = {
206  it: {
207    botName: 'IUAD',
208    botDescription: 'Benvenuto! Se sei già uno studente IUAD, puoi contattare direttamente la Segreteria di pertinenza. Se invece vuoi informazioni per una nuova iscrizione siamo qui per aiutarti!',
209    composerPlaceholder: 'Scrivi qui...',
210    restartConversation: 'Riavvia la conversazione',
211    newConversation: 'Nuova conversazione',
212    modalTitle: 'Crea una nuova conversazione',
213    modalConfirm: 'Nuova conversazione',
214    modalCancel: 'Annulla',
215    modalDescription: 'Questo cancellerà la conversazione corrente e ne avvierà una nuova.',
216  },
217  en: {
218    botName: 'IUAD',
219    botDescription: 'Welcome! If you are already an IUAD student, you can contact your office directly. If you need information for a new enrollment, we are here to help!',
220    composerPlaceholder: 'Write here...',
221    restartConversation: 'Restart the conversation',
222    newConversation: 'New conversation',
223    modalTitle: 'Create New Conversation',
224    modalConfirm: 'New Conversation',
225    modalCancel: 'Cancel',
226    modalDescription: 'This will clear the current conversation and start a new one.'
227  }
228}
229
230window.botpress.on('webchat:initialized', async () => {
231  const currentLang = (iuadGetCurrentLang() || 'it').toLowerCase()
232  const t = translations[currentLang] || translations.it
233
234  console.log('currentLang:', currentLang)
235
236  window.botpress.config({
237    configuration: {
238      botName: t.botName,
239      botDescription: t.botDescription,
240      composerPlaceholder: t.composerPlaceholder,
241      color: '#000000',
242      footer: '',
243      additionalStylesheet: `
244      .bpFabWrapper {
245        z-index: 1000 !important;
246      }
247        @media (max-width: 768px) {
248          .bpFabWrapper {
249            bottom: 100px !important;
250            right: 10px !important;
251            z-index: 1000 !important;
252          }
253          .bpFab{
254            box-shadow: none !important;
255          }
256          /* Container chat */
257          .bpChat, 
258          .bpContainer, 
259          .bpFab, 
260          .bpMessageList {
261            border-radius: 0px !important;
262          }
263        }
264          /* Modal title */
265        .bpModalTitle {
266          visibility: hidden;
267          position: relative;
268        }
269
270        .bpModalTitle::after {
271          visibility: visible;
272          position: absolute;
273          inset: 0;
274          content: "${t.modalTitle}";
275          text-align: center;
276        }
277
278        /* Modal description */
279        .bpModalDescription {
280          visibility: hidden;
281          position: relative;
282        }
283
284        .bpModalDescription::after {
285          visibility: visible;
286          position: absolute;
287          inset: 0;
288          content: "${t.modalDescription}";
289          white-space: pre-wrap;
290        }
291
292        /* Confirm button */
293        .bpModalButtonConfirm {
294          position: relative;
295          color: transparent !important;
296        }
297
298        .bpModalButtonConfirm::after {
299          content: "${t.modalConfirm}";
300          position: absolute;
301          top: 50%;
302          left: 50%;
303          transform: translate(-50%, -50%);
304          color: white;
305          white-space: nowrap;
306        }
307
308        /* Cancel button */
309        .bpModalButtonCancel {
310          visibility: hidden;
311          position: relative;
312        }
313
314        .bpModalButtonCancel::after {
315          visibility: visible;
316          position: absolute;
317          top: 50%;
318          left: 50%;
319          transform: translate(-50%, -50%);
320          content: "${t.modalCancel}";
321          white-space: nowrap;
322        }
323      `,
324      translations: {
325        restartConversation: t.restartConversation,
326        newConversation: t.newConversation
327      }
328    }
329  })
330
331  await window.botpress.updateUser({
332    data: {
333      language: currentLang
334    }
335  })
336
337  userUpdated = true
338  console.log('Botpress user language updated:', currentLang)
339}
339)
340
341
342
343window.botpress.on('customEvent', async (event) => {
344    let payload = event
345  
346    if (typeof event === 'string') {
347      try {
348        payload = JSON.parse(event)
349      } catch {}
350    }
351
352    try {
353      //console.log('[IUAD Botpress] customEvent ricevuto, type:', payload?.type, 'data keys:', payload?.data ? Object.keys(payload.data) : null)
354    } catch (e) {}
355  
356    if (payload?.type === 'debug') {
357      console.log('DATI DAL BOT:', payload.data)
358
359      // Se il bot manda i dati finali solo come "debug", inviamo comunque la lead.
360      try {
361        const d = payload?.data || {}
362        const email = (d.email || '').trim()
363        const nome = (d.nome || '').trim()
364        const cognome = (d.cognome || '').trim()
365        const telefono = (d.telefono || d.phone || '').trim()
366        const sede = (d.sede || '').trim()
367        const corsi = d.corsi
368
369        if (!email) {
370          console.warn('[IUAD Botpress] debug: email mancante, skip invio lead')
371          return
372        }
373
374        const leadKey = email + '|' + nome + '|' + cognome + '|' + telefono + '|' + JSON.stringify(corsi || null) + '|' + sede
375        if (__iuadLastLeadKey === leadKey) {
376          console.log('[IUAD Botpress] debug: lead già inviata (dedupe), skip')
377          return
378        }
379
380        const rawCourseItems = iuadNormalizeCorsiToLabels(corsi)
381
382        const courses_array = []
383        rawCourseItems.forEach((courseLabel) => {
384          const slug = iuadMapCourseLabelToSlug(courseLabel)
385          if (slug && courses_array.indexOf(slug) === -1) {
386            courses_array.push(slug)
387          }
388        })
389
390        const currentLang = iuadGetCurrentLang()
391        const location_value = sede || (typeof window.iuadChatLocation !== 'undefined' ? window.iuadChatLocation : '')
392        const how_to_know_value = 7 // "Altro"
393
394        const userData = {
395          first_name: nome,
396          last_name: cognome,
397          email: email,
398          phone_number: telefono,
399          course: courses_array,
400          lang: currentLang,
401          origin: ['chatbot'],
402          how_you_knows: how_to_know_value,
403          location: location_value,
404          request_description: 'Richiesta da Chatbot'
405        }
406
407        //console.log('[IUAD Botpress] debug: userData pronto:', userData)
408
409        const endpoint = iuadGetCrmEndpoint()
410        if (!endpoint) {
411          console.error('[IUAD Botpress] debug: Endpoint CRM non configurato (window.iuadChat.endpoint mancante).', window.iuadChat)
412          return
413        }
414
415        __iuadLastLeadKey = leadKey
416        //console.log('[IUAD Botpress] debug: Invio dati al proxy CRM', endpoint, userData)
417        fetch(endpoint, {
418          method: 'POST',
419          headers: { 'Content-Type': 'application/json' },
420          body: JSON.stringify(userData)
421        })
422          .then(response => {
423            console.log('[IUAD Botpress] debug: Response status (proxy):', response.status)
424            return response.json()
425          })
426          .then(responseData => {
427            console.log('[IUAD Botpress] debug: Response data (proxy):', responseData)
428          })
429          .catch(error => {
430            console.error('[IUAD Botpress] debug: Errore nella chiamata API:', error)
431          })
432      } catch (err) {
433        console.error('[IUAD Botpress] debug: Errore costruzione/invio payload CRM:', err)
434      }
435    }
436    //Aggiorna profilo con domanda di ricontatto
437    if (payload?.type === 'update_lead_with_question') {
438      //console.log('DATI DAL BOT:', payload.data)
439
440      // Se il bot manda i dati finali solo come "debug", inviamo comunque la lead.
441      try {
442        const d = payload?.data || {}
443        const email = (d.email || '').trim()
444        const nome = (d.nome || '').trim()
445        const cognome = (d.cognome || '').trim()
446        const telefono = (d.telefono || d.phone || '').trim()
447        const sede = (d.sede || '').trim()
448        const corsi = d.corsi
449
450        const lastQuestion = d.domanda_selezionata[d.domanda_selezionata.length - 1]
451
452        const question = lastQuestion.token ? lastQuestion.token : lastQuestion.text
453
454        if (!email) {
455          console.warn('[IUAD Botpress] debug: email mancante, skip invio lead')
456          return
457        }
458
459        const rawCourseItems = iuadNormalizeCorsiToLabels(corsi)
460
461        const courses_array = []
462        rawCourseItems.forEach((courseLabel) => {
463          const slug = iuadMapCourseLabelToSlug(courseLabel)
464          if (slug && courses_array.indexOf(slug) === -1) {
465            courses_array.push(slug)
466          }
467        })
468
469        const currentLang = iuadGetCurrentLang()
470        const location_value = sede || (typeof window.iuadChatLocation !== 'undefined' ? window.iuadChatLocation : '')
471        const how_to_know_value = 7 // "Altro"
472
473        const userData = {
474          first_name: nome,
475          last_name: cognome,
476          email: email,
477          phone_number: telefono,
478          course: courses_array,
479          lang: currentLang,
480          origin: ['chatbot'],
481          how_you_knows: how_to_know_value,
482          location: location_value,
483          request_description: question
484        }
485
486        //console.log('[IUAD Botpress] debug: userData pronto:', userData)
487
488        const endpoint = iuadGetCrmEndpoint()
489        if (!endpoint) {
490          console.error('[IUAD Botpress] debug: Endpoint CRM non configurato (window.iuadChat.endpoint mancante).', window.iuadChat)
491          return
492        }
493
494        //console.log('[IUAD Botpress] debug: Invio dati al proxy CRM', endpoint, userData)
495        fetch(endpoint, {
496          method: 'POST',
497          headers: { 'Content-Type': 'application/json' },
498          body: JSON.stringify(userData)
499        })
500          .then(response => {
501            console.log('[IUAD Botpress] debug: Response status (proxy):', response.status)
502            return response.json()
503          })
504          .then(responseData => {
505            console.log('[IUAD Botpress] debug: Response data (proxy):', responseData)
506          })
507          .catch(error => {
508            console.error('[IUAD Botpress] debug: Errore nella chiamata API:', error)
509          })
510      } catch (err) {
511        console.error('[IUAD Botpress] debug: Errore costruzione/invio payload CRM:', err)
512      }
513    }
514
515    if (typeof event === 'string') {
516        try {
517          payload = JSON.parse(event)
518        } catch (e) {}
519      }
520    
521      if (payload?.type === 'set-user-profile') {
522        console.log('[IUAD Botpress] set-user-profile ricevuto:', payload?.data)
523        const email = (payload?.data?.email || '').trim()
524        const nome = (payload?.data?.nome || '').trim()
525        const cognome = (payload?.data?.cognome || '').trim()
526        const telefono = (payload?.data?.telefono || payload?.data?.phone || '').trim()
527        const fullName = (payload?.data?.name || '').trim()
528        const sede = (payload?.data?.sede || '').trim()
529        const corsi = payload?.data?.corsi
530    
531        if (!email) {
532          console.warn('Profilo utente non aggiornato: email mancante')
533          return
534        }
535    
536        try { 
537          await window.botpress.updateUser({
538            name: fullName || undefined,
539            userKey: email,
540            data: {
541              email,
542              firstName: nome,
543              lastName: cognome,
544              phone: telefono
545            }
546          })
547    
548          console.log('Profilo Webchat aggiornato via email:', {
549            name: fullName,
550            userKey: email,
551            email,
552            phone: telefono
553          })
554        } catch (err) {
555          console.error('Errore aggiornamento profilo Webchat:', err)
556        }
557      }
558})
559
560window.botpress.on('customEvent', (event) => {
561    console.log('EVENT RAW:', event)
562})

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.