1const styleOptions = { 2 botAvatarInitials: 'BT', 3 accent: '#00809d', 4 botAvatarBackgroundColor: "#FFFFFF", 5 botAvatarImage: '/images/default-source/branding/chatbot/avatar-chatbot-saly.webp', 6 userAvatarImage: '/images/default-source/branding/chatbot/user.svg', 7 hideUploadButton: true, 8 backgroundColor: 'white' 9}; 10 11const theURL = "https://default61f73345a0ab4f70b0d5f83b509b73.f2.environment.api.powerplatform.com/powervirtualagents/botsbyschema/cr90e_swissSalaryBot/directline/token?api-version=2022-03-01-preview"; 12const environmentEndPoint = theURL.slice(0, theURL.indexOf('/powervirtualagents')); 13const apiVersion = theURL.slice(theURL.indexOf('api-version')).split('=')[1]; 14const regionalChannelSettingsURL = `${environmentEndPoint}/powervirtualagents/regionalchannelsettings?api-version=${apiVersion}`; 15 16let directline; 17let webchatScriptLoaded = false; 18let webchatCssLoaded = false; 19// Get the Language from the lang Attr in the html tags 20function getSwissLocaleFromHtmlLang() { 21 // Get e.g. "fr-CH" 22 const raw = (document.documentElement.getAttribute('lang') || '').toLowerCase(); 23 24 // If there is another format then map it to one of the four Bot-Locales 25 switch (raw) { 26 case 'de-ch': 27 case 'de': 28 return 'de-CH'; 29 case 'fr-ch': 30 case 'fr': 31 return 'fr-CH'; 32 case 'it-ch': 33 case 'it': 34 return 'it-CH'; 35 case 'en-ch': 36 case 'en': 37 case 'en-us': 38 case 'en-gb': 39 return 'en-CH'; 40 default: 41 return 'de-CH'; // useful fallback 42 } 43} 44 45// Load webchat script and CSS only when needed 46function loadWebchatResources() { 47 return new Promise((resolve, reject) => { 48 if (webchatScriptLoaded && webchatCssLoaded) { 49 resolve(); 50 return; 51 } 52 53 let resourcesLoaded = 0; 54 const totalResources = 2; 55 56 function checkAllLoaded() { 57 resourcesLoaded++; 58 if (resourcesLoaded === totalResources) { 59 resolve(); 60 } 61 } 62 63 // Load CSS FIRST 64 if (!webchatCssLoaded) { 65 const link = document.createElement('link'); 66 link.rel = 'stylesheet'; 67 link.href = '/styles/chatbot.css'; 68 link.onload = () => { 69 webchatCssLoaded = true; 70 checkAllLoaded(); 71 }; 72 link.onerror = () => { 73 console.error('Failed to load chatbot.css'); 74 reject(new Error('Failed to load chatbot CSS')); 75 }; 76 document.head.appendChild(link); 77 } else { 78 checkAllLoaded(); 79 } 80 81 // Load webchat.js - USE SPECIFIC VERSION, NOT /latest/ 82 if (!webchatScriptLoaded) { 83 const script = document.createElement('script'); 84 // Replace 'latest' with specific version for better caching 85 script.src = 'https://cdn.botframework.com/botframework-webchat/4.16.0/webchat.js'; 86 script.async = true; 87 script.onload = () => { 88 webchatScriptLoaded = true; 89 checkAllLoaded(); 90 }; 91 script.onerror = () => { 92 console.error('Failed to load webchat.js'); 93 reject(new Error('Failed to load webchat.js')); 94 }; 95 document.head.appendChild(script); 96 } else { 97 checkAllLoaded(); 98 } 99 }); 100} 101 102// Initialize the bot after resources are loaded 103function initializeBot() { 104 fetch(regionalChannelSettingsURL) 105 .then(response => response.json()) 106 .then(data => { 107 directline = data.channelUrlsById.directline; 108 109 const store = window.WebChat.createStore({}, ({ dispatch }) => next => action => { 110 if (action.type === "DIRECT_LINE/CONNECT_FULFILLED") { 111 dispatch({ 112 meta: { method: "keyboard" }, 113 payload: { 114 activity: { 115 channelData: { postBack: true }, 116 name: 'startConversation', 117 type: "event" 118 } 119 }, 120 type: "DIRECT_LINE/POST_ACTIVITY" 121 }); 122 } 123 return next(action); 124 }); 125 126 return fetch(theURL) 127 .then(response => response.json()) 128 .then(conversationInfo => { 129 // Clear loading message 130 const webchatContainer = document.getElementById('webchat'); 131 if (webchatContainer) { 132 webchatContainer.innerHTML = ''; 133 } 134 135 window.WebChat.renderWebChat({ 136 directLine: window.WebChat.createDirectLine({ 137 domain: `${directline}v3/directline`, 138 token: conversationInfo.token, 139 }), 140 store: store, 141 styleOptions, 142 locale: getSwissLocaleFromHtmlLang() 143 }, document.getElementById('webchat')); 144 }); 145 }) 146 .catch(err => { 147 console.error("An error occurred: " + err); 148 const webchatContainer = document.getElementById('webchat'); 149 if (webchatContainer) { 150 webchatContainer.innerHTML = '<div style="padding: 20px; color: red;">Error loading chatbot. Please try again.</div>'; 151 } 152 }); 153} 154 155// Load bot only when user clicks the chatbot button 156function loadBot() { 157 if (window.botLoaded) return; // Prevent multiple loads 158 window.botLoaded = true; 159 160 // Show loading indicator 161 const webchatContainer = document.getElementById('webchat'); 162 if (webchatContainer) { 163 webchatContainer.innerHTML = '<div style="padding: 20px; text-align: center;">Loading chatbot...</div>'; 164 } 165 166 // Load resources first, THEN initialize bot 167 loadWebchatResources() 168 .then(() => { 169 // Small delay to ensure CSS is fully applied 170 setTimeout(() => { 171 initializeBot(); 172 }, 100); 173 }) 174 .catch(err => { 175 console.error("Failed to load webchat resources: " + err); 176 const webchatContainer = document.getElementById('webchat'); 177 if (webchatContainer) { 178 webchatContainer.innerHTML = '<div style="padding: 20px; color: red;">Error loading chatbot. Please try again.</div>'; 179 } 180 }); 181} 182 183$(document).ready(function () { 184 $('.webchat-close').click(function () { 185 $('.webchat-container').hide(); 186 $('.chatbot-btn').show(); 187 });
188 189 $('.chatbot-btn').click(function () { 190 $('.webchat-container').show(); 191 $('.chatbot-btn').hide(); 192 loadBot(); // Load bot only on click 193 }); 194 195 $('[data-bs-target="#offcanvasSearch"]').on('click', function () { 196 if (!$(".chatbot-btn").is(":visible")) { 197 $('.webchat-container').hide(); 198 $('.chatbot-btn').show(); 199 } 200 if ($('#offcanvasSearch').hasClass('show')) { 201 $('#gsc-i-id1').focus(); 202 } 203 }); 204 205 $('[data-bs-target="#offcanvasMenu"]').on('click', function () { 206 if (!$(".chatbot-btn").is(":visible")) { 207 $('.webchat-container').hide(); 208 $('.chatbot-btn').show(); 209 } 210 }); 211});
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.