1/** 2 * Closes the whole chat window. 3 */ 4function closeChatWindow(delay = 0) { 5 setTimeout(function () { 6 window.webchat.close(); 7 }, delay); 8} 9 10/** 11 * Opens the rating dialog for the user. 12 */ 13function openRatingScreen() { 14 window.webchat.store.dispatch({ type: "SHOW_RATING_SCREEN", show: true }); 15 setTimeout(customizeRatingScreen, 500); 16} 17 18/** 19 * Removes the engagement bubble popup besides the toggle button. 20 */ 21function removeUnreadMessageBubble() { 22 var preview = document.querySelector(".webchat-teaser-message-root"); 23 preview && (preview.style.display = "none"); 24} 25 26/** 27 * Update the name of the bot displayed in the title bar. 28 * @param {string} newName The new name for the bot. 29 */ 30function updateBotName(newName) { 31 var title = document.querySelector(".webchat-header-title"); 32 title && (title.textContent = newName); 33} 34 35/** 36 * Update the avatar of the bot displayed in the title bar. 37 * @param {string} newAvatarUrl The new avatar url (pointing to the new avatar image) for the bot. 38 */ 39function updateBotAvatar(newAvatarUrl) { 40 var logo = document.querySelector(".webchat-header-logo"); 41 logo && (logo.src = newAvatarUrl); 42 delete window.webchat.customSettings.inputPlaceholderDisabled; 43} 44 45/** 46 * Customizes the chats close button: 47 * Makes it open the rating dialog instead of closing the chat window. 48 */ 49function customizeChatCloseButton() { 50 var button = document.querySelector(".webchat-header-close-button"); 51 button.replaceWith(button.cloneNode(true)); 52 document.querySelector(".webchat-header-close-button").onclick = function () { 53 if (isRatingShown()) { 54 var button = document.querySelector(".webchat-header-back-button"); 55 if (button) { 56 button.click(); 57 } 58 closeChatWindow(0); 59 } else if (isDatenschutzShown()) { 60 closeChatWindow(0); 61 } else { 62 openRatingScreen(); 63 } 64 }; 65} 66 67/** 68 * Customizes the rating screen: 69 * Makes it customize the chat again after returning to it with the back button. 70 */ 71function customizeRatingScreen() { 72 var button = document.querySelector(".webchat-header-back-button"); 73 button.onclick = function () { 74 setTimeout(onOpen, 250); 75 }; 76} 77 78/** 79 * Customizes the privacy hint, because the widget does not do it although configured. 80 */ 81function customizePrivacy() { 82 var link = document.querySelector("#cognigyBrandingLink"); 83 if (link) { 84 /* if (webchat.customSettings.layout.watermarkUrl) { 85 link.setAttribute("href", webchat.customSettings.layout.watermarkUrl); 86 }*/ 87 if (webchat.customSettings.layout.watermarkText) { 88 link.setAttribute("aria-label", webchat.customSettings.layout.watermarkText); 89 } 90 if (link.firstChild) { 91 link.firstChild.style = "font-size: 12px;"; 92 } 93 if (!document.getElementById("datenschutzSeperator")) { 94 var line = document.createElement("hr"); 95 line.setAttribute("id", "datenschutzSeperator"); 96 link.parentElement.insertBefore(line, link); 97 } 98 } 99} 100 101/** 102 * Enables the field for user input and changes the placeholder to the text of the custom settings. 103 */ 104function enableInputField() { 105 var container = document.querySelector(".webchat-input-message-container"); 106 if (container) { 107 container.querySelector("textarea").disabled = false; 108 container.querySelector("label").innerText = window.webchat.customSettings.behavior.inputPlaceholder; 109 } 110} 111 112/** 113 * Disables the field for user input and changes the placeholder to the text of the custom settings. 114 */ 115function disableInputField() { 116 var container = document.querySelector(".webchat-input-message-container"); 117 if (container) { 118 container.querySelector("textarea").disabled = true; 119 container.querySelector("label").innerText = window.webchat.customSettings.inputPlaceholderDisabled; 120 } 121} 122 123/** 124 * Dis- or enables the user input according to the current title of the chat window (Disabled if the title end with an asterisk). 125 */ 126function handleInputField() { 127 var title = document.querySelector(".webchat-header-title"); 128 if (title) { 129 title = title.textContent; 130 if (window.webchat.customSettings.inputPlaceholderDisabled && !title.
130includes("|")) { 131 disableInputField(); 132 } else { 133 enableInputField(); 134 } 135 } 136} 137 138/** 139 * Checks if the rating screen is shown. 140 * @returns true if shown, false otherwise. 141 */ 142function isRatingShown() { 143 var ratingMessage = document.querySelector(".webchat-rating-widget-comment-input-field"); 144 if (ratingMessage) { 145 return true; 146 } else { 147 return false; 148 } 149} 150 151/** 152 * Checks if the datenschutz screen is shown. 153 * @returns true if shown, false otherwise. 154 */ 155function isDatenschutzShown() { 156 var title = document.querySelector(".webchat-header-title"); 157 if (title.textContent == "Datenschutzerklärung") { 158 return true; 159 } else { 160 return false; 161 } 162} 163 164/** 165 * Checks if the messages are shown. 166 * @returns true if there is a least on message, false otherwise. 167 */ 168function isNothingShown() { 169 return document.getElementsByClassName("webchat-message-row").length == 0; 170} 171 172/** 173 * Hides the minimize button besides the close button. 174 */ 175function hideMinimizeButton() { 176 var minimizeButton = document.querySelector(".webchat-header-minimize-button"); 177 minimizeButton.style.display = "none"; 178} 179 180/** 181 * Hides the back button. 182 */ 183function hideBackButton() { 184 var backButton = document.querySelector(".webchat-header-back-button"); 185 if (backButton) { 186 backButton.parentElement.style.display = "none"; 187 } 188} 189 190/** 191 * Shows the back button. 192 */ 193function showBackButton() { 194 var backButton = document.querySelector(".webchat-header-back-button"); 195 if (backButton) { 196 backButton.parentElement.style.display = "flex"; 197 } 198} 199 200/** 201 * Hides all headers above user and bot messages. 202 */ 203function hideAllMessageHeaders() { 204 var nameTags = document.getElementsByClassName("message-header"); 205 for (var i = 0; i < nameTags.length; i++) { 206 nameTags[i].style.display = "none"; 207 } 208} 209 210/** 211 * Displays a greeting message from the bot so that the chat 212 * is not empty when the user has not clicked the start conversation 213 * button yet. 214 */ 215function addGreetingMessage() { 216 var history = document.querySelector("#webchatChatHistoryWrapperLiveLogPanel"); 217 if (history) { 218 var article = document.createElement("article"); 219 article.setAttribute("class", "webchat-message-row bot _message_19l6s_1"); 220 var bubble = document.createElement("div"); 221 bubble.setAttribute("class", "_bubble_1v5xk_1 chat-bubble _incoming_1v5xk_47"); 222 var div = document.createElement("div"); 223 div.setAttribute("class", "_markdown_fm2u2_16"); 224 var p = document.createElement("p"); 225 var span = document.createElement("span"); 226 span.setAttribute("stype", "display: contents;"); 227 if (webchat.customSettings.greetingMessage) { 228 span.innerHTML = webchat.customSettings.greetingMessage; 229 } else { 230 span.innerHTML = "Hallo"; 231 } 232 article.appendChild(bubble); 233 bubble.appendChild(div); 234 div.appendChild(p); 235 p.appendChild(span); 236 237 if (history.firstChild && history.firstChild.childElementCount > 0) { 238 history.firstChild.insertBefore(article, history.firstChild.children[1]); 239 } 240 } 241} 242 243/** 244 * When the chat window is opened. 245 * @param {*} event The event provided by the engine. 246 */ 247function onOpen(event) { 248 if (isRatingShown()) { 249 customizeRatingScreen(); 250 } else { 251 if(isDatenschutzShown()) { 252 hideBackButton(); 253 } else { 254 showBackButton(); 255 } 256 customizeChatCloseButton(); 257 window.webchat.botName && updateBotName(window.webchat.botName); 258 window.webchat.botAvatarUrl && updateBotAvatar(window.webchat.botAvatarUrl); 259 handleInputField(); 260 hideAllMessageHeaders(); 261 customizePrivacy(); 262 addGreetingMessage(); 263 } 264 hideMinimizeButton(); 265} 266 267/** 268 * When a bot sends a message to the user. 269 * @param {*} event The event provided by the engine. 270 */ 271function onOutgoingMessage(event) { 272 if (event.payload) { 273 if (event.payload.data && event.payload.data._cognigy && event.payload.data._cognigy.controlCommands && event.payload.data._cognigy.controlCommands[0]) { 274 // If the user user accepted the terms.
275 if (event.payload.data._cognigy.controlCommands[0].type == "acceptPrivacyPolicy") { 276 customizeChatCloseButton(true); 277 addGreetingMessage(); 278 handleInputField(); 279 } 280 // If the user actually provided a rating. 281 if (event.payload.data._cognigy.controlCommands[0].type == "setRating") { 282 closeChatWindow(500); 283 } 284 } 285 hideAllMessageHeaders(); 286 } 287} 288 289/** 290 * When a bot sends a message to the user. 291 * @param {*} event The event provided by the engine. 292 */ 293function onIncomingMessage(event) { 294 if (event.payload) { 295 // If the initial engagement bubble popped up besides the toggle button. 296 if (event.payload.source == "engagement") { 297 setTimeout(removeUnreadMessageBubble, 5000); 298 } 299 if (event.payload.data) { 300 // If a new bot name was provided. 301 if (event.payload.data.overrideBotName) { 302 window.webchat.botName = event.payload.data.overrideBotName; 303 updateBotName(event.payload.data.overrideBotName); 304 handleInputField(); 305 } 306 // If a new bot avatar was provided. 307 if (event.payload.data._webchat && event.payload.data._webchat.botAvatarOverrideUrl) { 308 window.webchat.botAvatarUrl = event.payload.data._webchat.botAvatarOverrideUrl; 309 updateBotAvatar(event.payload.data._webchat.botAvatarOverrideUrl); 310 handleInputField(); 311 } 312 } 313 handleInputField(); 314 hideAllMessageHeaders(); 315 customizePrivacy(); 316 } 317} 318 319const endpointUrl = document.getElementById("init-chatbot").getAttribute("data-endpoint"); 320const settings = { 321 forceWebsockets: true, 322 settings: { 323 disableBranding: true, 324 disablePersistentHistory: true, 325 engagementMessageDelay: 2000, 326 }, 327}; 328 329/** 330 * Initializes the webchat component and responds to events for customizations. 331 * @param {*} customSettings The custom settings from the bots endpoint. 332 */ 333function init(customSettings) { 334 // Call the initialize method for the bot before customization. 335 initWebchat(endpointUrl, settings).then(function (webchat) { 336 window.webchat = webchat; 337 window.webchat.customSettings = customSettings; 338 // hard coded to be more secure 339 window.webchat.customSettings.layout.disableHtmlContentSanitization = false; 340 // hard coded to be more secure 341 window.webchat.customSettings.layout.disableUrlButtonSanitization = false; 342 webchat.registerAnalyticsService(function (event) { 343 switch (event.type) { 344 case "webchat/open": // When the chat window is opened. 345 setTimeout(function () { 346 onOpen(event); 347 }, 100); 348 break; 349 case "webchat/outgoing-message": // When a bot sends a message to the user. 350 setTimeout(function () { 351 onOutgoingMessage(event); 352 }, 100); 353 break; 354 case "webchat/incoming-message": // When a user sends a message to the bot. 355 setTimeout(function () { 356 onIncomingMessage(event); 357 }, 100); 358 break; 359 } 360 }); 361 // Remove the original webchat button 362 removeOriginalToggleButton(); 363 // To open the bot when open-chatbot is a parameter in the url 364 new URLSearchParams(window.location.search).has("open-chatbot") && webchat.open(); 365 }); 366} 367 368function removeOriginalToggleButton() { 369 var button = document.querySelector(".webchat-toggle-button:not([onClick])"); 370 if (button) { 371 button.style.visibility = "hidden"; 372 return true; 373 } else { 374 setTimeout(removeOriginalToggleButton, 10); 375 return false; 376 } 377} 378 379// Wait for the whole page to load before starting to customize the chat bot. 380window.addEventListener( 381 "DOMContentLoaded", 382 // Fetching the response from the endpoint is needed to gain access to the customSettings. 383 fetch(endpointUrl).then(function (response) { 384 response.json().then(function (json) { 385 // Delay the initialization until the cookie consent banner is gone. 386 var checkForCookieBanner = function () { 387 if (document.querySelector(".consent-banner") && document.querySelector(".consent-banner").offsetParent != null) { 388 setTimeout(checkForCookieBanner, 1000); 389 } else { 390 init(json.settings); 391 } 392 }; 393 checkForCookieBanner(); 394 });
395 }) 396);
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.