
"+chatType);
if(chatType == "validation" || chatType=="tech") {
var durationSecs = _chatStartTime ? Math.floor((Date.now() - _chatStartTime) / 1000) : 0;
console.log('[Survey] Chat closed — messageCount:', _messageCount, '| durationSecs:', durationSecs);
if (_messageCount >= MIN_MESSAGE_COUNT && durationSecs >= MIN_DURATION_SECS) {
console.log('[Survey] Trigger conditions met — showing survey');
showSurveyIframe();
} else {
console.log('[Survey] Trigger conditions NOT met — skipping survey');
}
}
else{
handleChatClose("conversationClosed");
}
}, listenerOpts);
window.addEventListener("onEmbeddedMessagingWindowClosed", () => {
if(chatType=="validation" || chatType=="tech") {
// ── Hide survey when chat window is closed (permanently) ─────────────────
_surveyDismissed = true;
var overlay = document.getElementById('dc-survey-overlay');
if (overlay) {
overlay.style.display = 'none';
console.log('[Survey] Chat window closed — hiding survey permanently');
}
}
handleChatClose("windowClosed");
}, listenerOpts);
window.addEventListener("onEmbeddedMessagingBusinessHoursEnded", () => {
console.log("Business hours ended event fired");
hideChatButton(chatType);
}, listenerOpts);
window.addEventListener("onEmbeddedMessagingBusinessHoursStarted", () => {
console.log("Business hours started event fired");
}, listenerOpts);
embeddedservice_bootstrap.init(orgId,deploymentId,deploymentUrl,{scrt2URL:scrtURL});
isChatLoaded = true;
}catch(err){
console.error("Error loading Embedded Messaging:", err);
}
}
function loadSFDCChat(chatType, language,initManually) {
const config = CHAT_CONFIG[chatType];
if (!config) {
console.error("Invalid chatType:", chatType);
return;
}
if(isChatLoaded) cleanupChat(); // clean already open chat before intializing
if(language =="cn") language="zh_CN";
if(language =="tw") language="zh_TW";
if(language =="nl" && chatType =="validation") language="en_US";
currentChatScript = document.createElement("script");
currentChatScript.src = CHAT_CONFIG[chatType].baseUrl+"/assets/js/bootstrap.min.js";
currentChatScript.onload = () =>
initEmbeddedMessaging(
chatType,
language,
config.deploymentId,
config.baseUrl,
initManually
);
document.body.appendChild(currentChatScript);
console.log("Loading script ...", currentChatScript.src);
}
function launchChat(chatType, language) {
minimizeAdaChat(); // If ADA chat is open, minimize it
disableChatTextButton(true,"all",null);// Disable chat buttons to prevent multiple clicks
toggleInfo(chatType, true);
if(chatLoadedFor === chatType && window.embeddedservice_bootstrap){
console.log("[launchChat] Warning: Chat already loaded.");
embeddedservice_bootstrap.utilAPI.launchChat();
toggleInfo(chatType, false);
return;
}
chatLoadedFor = chatType;
document.body.style.cursor = "wait";
loadSFDCChat(chatType,language,false);
}
function disableChatTextButton(disable,txtbtns,chatType) {
document.querySelectorAll('.openChatLink').forEach(btn => {
const type = btn.dataset.chat;
if (!type) return; // Skip if no chat type
const shouldToggle = txtbtns === "all" || (txtbtns === "single" && type === chatType);
if (!shouldToggle) return;
const parent = btn.parentElement;
if (!parent) return;
parent.classList.toggle('disabled', disable);
parent.classList.toggle('text--color-dc-light-blue', !disable);
});
}
function toggleInfo(chatType, show) {
var elements = document.querySelectorAll("#" + chatType + "__info");
elements.forEach(el => {
el.style.display = show ? "block" : "none";
});
}
document.addEventListener("click", function (e) {
if (e.target.classList.contains('openChatLink')) {
let chatType = e.target.dataset.chat;
let chatLang = e.target.dataset.lang || lang || 'en-US';
if (chatType) {
switch (chatType) {
case "ADA": loadBot(); break;
default: launchChat(chatType,chatLang);
}
}
}
});
let path = window.location.pathname.replace(/\/$/, '');
const excluded = ['/support', '/contact-us'];
const isExcluded = excluded.some(p => path.endsWith(p));
if (isExcluded) {
document.addEventListener("DOMContentLoaded", function () {
let pollingTimer = null;
let currentXhr = null;
let generation = 0; // Incremented on every start/stop to invalidate stale callbacks
function checkAgentAvailability() {
const myGeneration = generation; // Capture current generation for this call
currentXhr = new XMLHttpRequest();
currentXhr.open('POST', '/bin/digicert/checkSFDCAgentIsAvailable', true);
currentXhr.setRequestHeader('Content-Type', 'application/x-www-form-urlencoded');
currentXhr.onload = function () {
// Discard if this belongs to a stale polling loop
if (myGeneration !== generation) return;
if (currentXhr.status === 200) {
var data = currentXhr.responseText;
let parts = data.split(';');
parts.forEach(part => {
let [key, value] = part.split('=');
value = Number(value);
toggleAvailability(key, value);
});
}
else{
console.log("SFDC ChatAgent API Error");
}
// Schedule next call only if tab is still active and generation matches
if (!document.hidden && myGeneration === generation) {
pollingTimer = setTimeout(checkAgentAvailability, 30000);
}
};
currentXhr.onerror = function () {
if (!document.hidden && myGeneration === generation) {
pollingTimer = setTimeout(checkAgentAvailability, 30000);
}
};
currentXhr.send("lang=" + encodeURIComponent(lang || ""));
}
function startPolling() {
generation++; // Invalidate any in-flight or pending callbacks from previous loop
clearTimeout(pollingTimer);
pollingTimer = null;
checkAgentAvailability();
}
function stopPolling() {
generation++; // Invalidate any in-flight or pending callbacks
clearTimeout(pollingTimer);
pollingTimer = null;
// Abort any in-flight XHR so it doesn't fire onload/onerror
if (currentXhr) {
currentXhr.abort();
currentXhr = null;
}
}
// Listen for tab visibility changes
document.addEventListener("visibilitychange", function () {
if (document.hidden) {
stopPolling(); // Tab is inactive — stop
} else {
startPolling(); // Tab is active again — resume immediately
}
});
// Start on page load
startPolling();
});
loadSFDCChat(chatLoadedFor,lang,true);
}