diff --git a/IVA-Wakeup/UI/After.js b/IVA-Wakeup/UI/After.js new file mode 100644 index 0000000..303b080 --- /dev/null +++ b/IVA-Wakeup/UI/After.js @@ -0,0 +1,17 @@ +store.snippets.get('disabler').toggle(payload?.metadata?.outputs?.disableMessengerInput, payload?.metadata?.outputs?.messengerInputPlaceholder || 'Enter question here'); +console.log('disable?'); +console.log(payload?.metadata?.outputs?.disableMessengerInput); + +if (payload?.metadata?.outputs?.hideMessenger == true) { + store.main.hideMessenger(); +}; + +if (payload?.metadata?.outputs?.minimizeAfterFiveSeconds == true) { + setTimeout(() => { store.main.isMessengerVisible = false }, 5000); +}; + +if (payload?.metadata?.outputs?.disableMessengerInput === true) { + store.main.disableMessengerInput(); +} + +callback(payload); \ No newline at end of file diff --git a/IVA-Wakeup/UI/Before.js b/IVA-Wakeup/UI/Before.js new file mode 100644 index 0000000..612ee17 --- /dev/null +++ b/IVA-Wakeup/UI/Before.js @@ -0,0 +1,60 @@ +console.log("inside before addd"); +console.log(payload); +let pramstudioConvoId = ""; +if (payload?.conversationId) { + console.log('inside'); + console.log(payload?.conversationId); + pramstudioConvoId = payload?.conversationId; +} +store.isAuthenticated = checkCookieExists("PGXREGSITE_LOGIN") || (window.location.href.includes('ivastudio.ai') && window.location.href.includes('testAuth=1')); + +payload.metadata = { + channel: "WEB", + companyName: "Lexington Law", + companyWebsite: "lexingtonlaw.com", + agentType: store.isAuthenticated ? "Paralegal" : "Credit Representative", + callerType: "client", + serviceType: "case", + tenantName: "lexingtonLaw", + location: window.location, + isAuthenticated: store.isAuthenticated, + isSaleCompleted: sessionStorage.getItem("signupComplete") || "", //Conversion tracking snippet, string + //studioConvoId = pramstudioConvoId +}; + +payload.metadata.studioConvoId = pramstudioConvoId; + +try { + const customerData = JSON.parse(sessionStorage.getItem("customerData") || "{}"); + const userDetails = JSON.parse(sessionStorage.getItem("userDetails") || "{}"); + const ucidSession = sessionStorage.getItem("ucid"); + + // --- UCID priority: userDetails > customerData > sessionStorage --- + payload.metadata.ucid = + userDetails?.ucid ?? + customerData?.ucid ?? + (ucidSession ? ucidSession.replace(/^"|"$/g, "") : undefined) ?? + payload.metadata.ucid; + + // --- First pass: customerData --- + payload.metadata.firstName = customerData?.firstName ?? payload.metadata.firstName; + payload.metadata.lastName = customerData?.lastName ?? payload.metadata.lastName; + payload.metadata.email = customerData?.email ?? payload.metadata.email; + + // --- Second pass: userDetails (overrides customerData if present) --- + payload.metadata.firstName = userDetails?.firstName ?? payload.metadata.firstName; + payload.metadata.lastName = userDetails?.lastName ?? payload.metadata.lastName; + payload.metadata.email = userDetails?.email ?? payload.metadata.email; + + // --- ClientID only if authenticated --- + if (store.isAuthenticated) { + payload.metadata.clientID = userDetails?.clientID ?? payload.metadata.clientID; + } + + // const data1 = JSON.parse(sessionStorage.getItem("XSRF-TOKEN")); + // payload.metadata.xsrf_token = data1; +} catch (e) { + //payload.metadata.isAuthenticated = false; +} + +callback(payload); diff --git a/IVA-Wakeup/UI/OnLoad.js b/IVA-Wakeup/UI/OnLoad.js new file mode 100644 index 0000000..67cea40 --- /dev/null +++ b/IVA-Wakeup/UI/OnLoad.js @@ -0,0 +1,685 @@ +// START TEMPLATING + +window.store = store; + +window.checkCookieExists = (cookieName) => { + return document.cookie.includes(`${cookieName}=`); +} + +function isMobile() { + return /Mobi|Android/i.test(navigator.userAgent); +} + +window.mobileRedirectionCheck = () => { + if (isMobile()) { + store.main.hideMessenger(); + } +} + +function renderTemplate(template, data) { + // Replace variables like {{variable}} with their corresponding values in data + template = template.replace(/{{\s*(\w+)\s*}}/g, (_, key) => { + return data[key] || ''; + }); + + // Handle v-if directives + template = template.replace(/<(\w+)\s*v-if="([^"]+)"\s*>([\s\S]*?)<\/\1>/g, (_, tag, condition, truePart) => { + // Evaluate the condition in the context of data + const conditionValue = eval(condition.replace(/\b(\w+)\b/g, (match) => data[match] !== undefined ? data[match] : match)); // Replace variables with their values + + if (conditionValue) { + // If the condition is true, render the v-if block + return `<${tag}>${truePart}`; + } + + return ''; // If the condition is false, render nothing + }); + + return template; +} + +// store.isAuthenticated = checkCookieExists("PGXREGSITE_LOGIN"); +// allows user to test authentication if they add &testAuth=1 onto the end of the url and refresh +store.isAuthenticated = checkCookieExists("PGXREGSITE_LOGIN") || (window.location.href.includes('ivastudio.ai') && window.location.href.includes('testAuth=1')); + +const template = `${payload.settings.newConversationPlaceholder.code.html}`; +payload.settings.newConversationPlaceholder.code.html = renderTemplate(template, { + isAuthenticated: store.isAuthenticated +}); +store.main.setSettings(payload.settings); + +(() => { + let lastData = checkCookieExists("PGXREGSITE_LOGIN"); + setInterval(() => { + let currentData = store.isAuthenticated = checkCookieExists("PGXREGSITE_LOGIN") || store.isAuthenticated; + payload.settings.newConversationPlaceholder.code.html = renderTemplate(template, { + isAuthenticated: store.isAuthenticated + }); + if (store.isAuthenticated && !isLiveChat()) { + // disable + store.main.disableMessengerInput(); // 2-26-2025 commented out so Travis can test user inputs in Dev only + } + if (currentData !== lastData) { + lastData = currentData; + store.main.setSettings(payload.settings); + store.conversation.$reset(); + store.conversationEvent.$reset(); + store.main.setView("main"); + } + }, 1000); +})(); + +// END TEMPLATING + +//VERSION 1.1 +store.random = true; +//console.log("payload", payload); +const liveChatOnLaunch = payload.settings.chatOnlyMode == true; +const closeBtns = payload.settings.desktopCloseBtn == true; +if (closeBtns) { + delete store.main.isCloseButtonVisible; + payload.settings.desktopCloseBtn = false; +} +store.main.setSettings(payload.settings); + +const getCloseSVG = () => { + return ``; +}; +const getMinimizeSVG = () => { + return ' '; +}; +const getCloseLiveChatSVG = () => { + return ``; +}; + +const addScript = (url, root, callback) => { + const script = document.createElement("script"); + script.type = "text/javascript"; + script.src = url; + script.onload = callback; + root.appendChild(script); +}; + +const addLink = (url, root) => { + const link = document.createElement("link"); + link.type = "text/css"; + link.href = url; + link.rel = "stylesheet"; + root.appendChild(link); +}; + +const waitForElm = function (selector) { + return new Promise((resolve) => { + const root = document.querySelector("body ivas-messenger-ui").shadowRoot; + if (root.querySelector(selector)) return resolve(root.querySelector(selector)); + const observer = new MutationObserver((mutations) => { + if (root.querySelector(selector)) { + resolve(root.querySelector(selector)); + observer.disconnect(); + } + }); + observer.observe(root, { + childList: true, + subtree: true, + }); + }); +}; + +const injectStyle = () => { + waitForElm("div.app").then((elem) => { + elem.insertAdjacentHTML( + "afterbegin", + `` + ); + }); +}; + +const sendLiveChatOnOff = (on) => { + let input = on ? "Connecting to live chat" : "Live chat ended"; + if (on && !store.main.conversationId) { + store.conversationEvent.sendMessage({ + input: input, + metadata: { liveChat: on, nluSupressDefaultAnswer: true }, + }); + } else if (store.main.conversationId) { + for (const webhook of payload.webhooks) { + if (webhook.enabled) { + axios({ + method: 'post', + url: webhook.url, + data: { + event: { + conversationId: store.main.conversationId, + input, + external: true, + metadata: { liveChat: on } + } + } + }); + } + } + } +}; + +const delayLiveChatOnOff = (on, msDelay) => { + setTimeout(() => { + console.log("livechat startup"); + sendLiveChatOnOff(on); + }, msDelay); +}; + + +let typingTimeout; +const TYPING_DELAY_MS = 500; + +const handleTyping = () => { + clearTimeout(typingTimeout); + + typingTimeout = setTimeout(() => { + + console.log("TYPING"); + console.log("store.main.conversationId"); + console.log(store.main.conversationId); + + try { + fetch("https://router.usw.ivastudio.ai/ProxyScript/run/66ce521b47ec88c50fb8adf4/current/userTyping", { + method: 'POST', + headers: { + 'Content-Type': 'application/json', + }, + body: JSON.stringify({ + "event": "TYPING", + "sessionId": store.main.conversationId + }), + }); + } + catch (error) { + console.log("something errored when sending typing event"); + } + }, TYPING_DELAY_MS); +} + +const showHideLiveChat = (livechat) => { + const root = document.querySelector("body ivas-messenger-ui").shadowRoot; + const el = root.getElementById("livechat"); + if (livechat === true) { + waitForElm(".footer").then(() => { + let textArea = root.querySelector(".footer textarea"); + textArea.addEventListener("input", handleTyping); + }); + if (!el) { + //store.main.enableMessengerInput(); + // COMMENTING OUT THE FOLLOWING LINES TO HIDE END LIVE CHAT BUTTON PER CREDITS REQUEST + // waitForElm(".footer").then((el) => { + // const div = document.createElement("button"); + // div.id = "livechat"; + // div.setAttribute("aria-label", "End Live Chat"); + // div.title = "End Live Chat"; + // div.style.color = payload.settings.actionColor; + // div.innerHTML = getCloseLiveChatSVG(); + // div.style.paddingRight = "10px"; + // div.onclick = () => { + // sendLiveChatOnOff(false); + // if (store.isAuthenticated) { + // store.main.disableMessengerInput(); + // } + // store.conversationEvent.sendMessage("Live Chat Session ended. Can I help you with anything else?"); + // //Add a chip titled "Live Chat" + // div.remove(); + // }; + // el.appendChild(div); + // }); + } + } else if (el) { + // livechat == false + el.remove(); + } +}; + +const isLiveChat = () => { + let livechat = false; + for (const [id, participant] of Object.entries(store.conversationEvent.participants)) { + if (participant.type == "agent") livechat = true; + } + return livechat; +}; + +const debugButtons = (liveChatOn) => { + waitForElm(".footer").then((el) => { + const div = document.createElement("button"); + div.id = "debug"; + div.setAttribute("aria-label", "Start Live Chat"); + div.innerHTML = "Connect to live chat"; + div.title = "Connect to live chat"; + div.onclick = () => { + store.conversationEvent.sendMessage({ + input: "Connect to live chat", + metadata: { liveChat: true }, + }); + }; + el.parentNode.insertBefore(div, el.nextSibling); + }); +}; + +// state variables: connecting to live chat automatically in the messenger visibility event has a sequencing problem. It will get called before axios is loaded and error out. +// This delays the live chat connect until after axios is loaded. +let isAxiosLoaded = false; +let awaitingConnect = false; +addScript("https://cdn.jsdelivr.net/npm/axios/dist/axios.min.js", document.head, () => { + if (awaitingConnect) { + awaitingConnect = false; + delayLiveChatOnOff(true, 1500); + } + isAxiosLoaded = true; +}); + +window.addEventListener("beforeunload", (event) => { + // doesn't work + if (liveChatOnLaunch && isLiveChat()) { + sendLiveChatOnOff(false); + } +}); + +// update the state of livechat based on the participants. If there is an "agent" participant type, it's a live chat. +vm.$watch( + () => store.conversationEvent.participants, + async (participants) => { + try { + showHideLiveChat(isLiveChat()); + } catch (e) { + console.error(e); + } + } +); + + +vm.$watch( + () => store.main.isMessengerVisible, + async (isVisible) => { + try { + console.log("messenger visible =", isVisible, store.main.conversationId); + if (isVisible == true) { + const livechat = isLiveChat(); + injectStyle(); + showHideLiveChat(livechat); + //debugButtons(livechat); + if (closeBtns) { + waitForElm(".app").then((el) => { + const div = document.createElement("button"); + div.id = "minimize"; + div.title = "Minimize"; + div.innerHTML = getMinimizeSVG(); + div.onclick = () => { + store.main.hideMessenger(); + }; + el.appendChild(div); + }); + waitForElm(".app").then((el) => { + const div = document.createElement("button"); + div.id = "close"; + div.title = "Close"; + div.innerHTML = getCloseSVG(); + div.onclick = () => { + //Added the following line and commented out the proceeding if statement at credit's request in order to ONLY minimize the UI when in live chat instead of closing the session + store.main.hideMessenger(); + // if (!isLiveChat() || window.confirm("Live Chat is running. Are you sure you want to close?")) { + // store.main.hideMessenger(); + // if (isLiveChat()) { + // sendLiveChatOnOff(false); + // } + // //store.main.setNewUserSession(); + // store.conversation.$reset(); + // store.conversationEvent.$reset(); + // store.main.setView("chat"); + // store.main.setNewConversation(true); + // } + }; + el.appendChild(div); + }); + } + if (liveChatOnLaunch) { + if (!livechat) { + if (isAxiosLoaded === true) { + delayLiveChatOnOff(true, 1500); + } else { + awaitingConnect = true; + } + } + } + } + } catch (e) { + console.error(e); + } + }, + { + deep: true, + immediate: true + } +); + +window.vm = vm; +window.store = store; + +addScript("https://router.usw.ivastudio.ai/ProxyScript/run/66ce521b47ec88c50fb8adf4/current/adaptiveCardImplementation_64dbc87628bd839f69b0c962", document.head, () => { + // Uncomment the following line to load the optional host config script + // addScript('https://router.usw.ivastudio.ai/ProxyScript/run/66ce521b47ec88c50fb8adf4/current/adaptiveCardHostConfig_64dbc87628bd839f69b0c962', document.head); +}); + +//supplemental code for feedback functionality including waitForElm lines + +// const waitForElm = function (selector) { +// return new Promise((resolve) => { +// const root = document.querySelector('body ivas-messenger-ui').shadowRoot; +// if (root.querySelector(selector)) return resolve(root.querySelector(selector)); +// const observer = new MutationObserver((mutations) => { +// if (root.querySelector(selector)) { +// resolve(root.querySelector(selector)); +// observer.disconnect(); +// } +// }); +// observer.observe(root, { +// childList: true, +// subtree: true +// }); +// }); +// }; + +//END GENERAL ON ENGAGEMENT LOAD CODE + +//BEGIN FEEDBACK SPECIFIC CODE + +vm.$watch(() => store.conversationEvent.messages, async (value) => { + value.forEach((message, index) => { + if (message.sentBy.hasOwnProperty('type')) { + if (localStorage.getItem(`feedback-${message._id}`) || message?.metadata?.feedbackable != true) { + } else { + window.showFeedback(message._id, message.conversationId, message?.metadata?.transactionId); + } + } + }); +}, { + deep: true +}); + +window.showFeedback = (id, conversationId, transactionId) => { + waitForElm(`div#message-${id}`).then((wrap) => { + try { + // const wrap = document.querySelector("body > se-messenger").shadowRoot.querySelector("#se-messenger-app > div.se-messenger-frame > div > div.se-messenger-body > div"); + const scrollToTop = () => { + wrap.scrollTop = wrap.scrollHeight; + }; + let devWrap = wrap.querySelector(`div.feedback-wrap`); + if (!devWrap) { + devWrap = document.createElement('div'); + devWrap.classList.add('feedback-wrap'); + devWrap.innerHTML = `
👍👎
`; + wrap.parentElement.querySelector(`div#message-${id} > div`).after(devWrap); + } + devWrap.querySelector(`a#se-messenger-feedback-like-${id}`).onclick = (e) => { + e.preventDefault(); + console.log("like!"); + devWrap.parentElement.removeChild(devWrap); + send("LIKE"); + } + devWrap.querySelector(`a#se-messenger-feedback-dislike-${id}`).onclick = (e) => { + e.preventDefault(); + console.log("dislike!"); + devWrap.parentElement.removeChild(devWrap); + send("DISLIKE"); + } + wrap.parentElement.parentElement.parentElement.scrollTop = + wrap.parentElement.parentElement.parentElement.scrollHeight; + const send = (event) => { + localStorage.setItem(`feedback-${id}`, true); + + //update DQ_URL with the URL of the LTS version of your feedback query + fetch('https://router.usw.ivastudio.ai/DynamicQuery/run/66ce521b47ec88c50fb8adf4/current/Feedback_6529ac38d8f54e4b61bc0a99', { + method: 'POST', + headers: { + 'Content-Type': 'application/json', + }, + body: JSON.stringify({ + "event": event, + "_id": transactionId + }), + }); + }; + } catch (e) { + console.log(e); + } + }); +}; +//END FEEDBACK CODE + +//Watcher to keep IVA Open When in LIVE CHAT +vm.$watch(() => store.conversationEvent.messages, async (value) => { + try { + console.log("Msg received"); + const livechat = isLiveChat(); + if (livechat) { + if (!store.main.isMessengerVisible) { + store.main.showMessenger(); + } + } + console.log(livechat); + } catch (e) { + console.error(e); + } +}, { + deep: true +}); + +window.askIVA = + window.askSky = + window.askSkyWithData = + (input, postBack, configuration, isNew) => { + store.main.showMessenger(); + if (isNew) { + store.conversation.$reset(); + store.conversationEvent.$reset(); + store.main.setView("chat"); + store.main.setNewConversation(true); + } else { + store.main.setView("chat"); + } + store.conversationEvent.sendMessage({ + input, + postBack, + configuration + }); + }; + +window.openChat = () => { + store.main.showMessenger(); + // start new + store.conversation.$reset(); + store.conversationEvent.$reset(); + // start new + store.main.setView("chat"); + // start new + store.main.setNewConversation(true); +}; + +window.closeChat = () => { + store.main.hideMessenger(); +}; + +//BEGIN MASKING +const debounce = (func, timeout = 300) => { + let timer; + return (...args) => { + clearTimeout(timer); + timer = setTimeout(() => { func.apply(this, args); }, timeout); + }; +}; + +const de = debounce((value) => { + value.forEach((message, index) => { + if (message.sentBy.hasOwnProperty('type')) { + if (localStorage.getItem(`feedback-${message._id}`) || message?.metadata?.feedbackable != true) { + } else { + window.showFeedback(message._id, message.conversationId, message?.metadata?.transactionId); + } + } else { + if (message.input) { + let matchRes = window.isMask(message.input); + if (matchRes.includes("####") || matchRes.includes("#%*!")) { + message.input = matchRes; + } + } + } + }); +}, 1000); +vm.$watch(() => store.conversationEvent.messages, de, { + deep: true +}); + +// sendMessage(input, metadata, conversationId) { +// try { +// debugLogging(`Sending message ${input} and metadata: ${JSON.stringify(metadata)}`); + +// window.liveChat.sendLiveChatMessage(input); + +// const proxyEndpoint = `${store.main.settings.liveChat.apiBaseUrl}/recordUserMessage`; +// const id = window.liveChat.convoId; +// input = window.isMask(input); +// } +// }//abbreviated + +// #region Masking +window.isMask = (message) => { + const ssnRegex = /\b(\d{3}[-. ]?\d{2}[-. ]?\d{4}|\d{2}[-. ]\d{4}|\d{9}|\d{3}-\d{2}-\d{4})\b/g; + const ssnRegex2 = /\b(\d{2}(.)\d{4}|\d{3}([- .])\d{3}\3\d{3})\b/g; + const ccRegex = /\b(\d{4}[-. ]?\d{6}[-. ]?\d{4,5}|\d{4}[-. ]?\d{4}[-. ]?\d{4}[-. ]?\d{4})\b/g; + const acctNoRegex = /\b(\d{4}[-.\s]?\d{4}[-.\s]?\d{4}[-.\s]?\d{4})\b/g; + const emailRegex = /\b[a-z0-9._%\+\-—|]+@[a-z0-9.\-—|]+\.[a-z|]{2,6}\b/g; + const birthDateRegex = /\b^(3[01]|[12][0-9]|0?[1-9])(\/|-)(1[0-2]|0?[1-9])\2([0-9]{2})?[0-9]{2}$\b/g; + const phoneNumberRegex = /^(\+\d{1,2}\s)?\(?\d{3}\)?[\s.-]\d{3}[\s.-]\d{4}$\b/g; + + let regexArr = []; + //regexArr.push(acctNoRegex); + regexArr.push(ccRegex); + regexArr.push(ssnRegex); + regexArr.push(ssnRegex2); + //regexArr.push(emailRegex); + //regexArr.push(birthDateRegex); + //regexArr.push(phoneNumberRegex); + + regexArr.forEach((element) => { + message = message.replace(element, "####"); + }) + + let badWords = [ + "anal", + "anus", + "arse", + "ass", + "ballsack", + "bastard", + "bitch", + "biatch", + "blowjob", + "bollock", + "bollok", + "buttplug", + "clitoris", + "cock", + "coon", + "cunt", + "damn", + "dick", + "Dildo", + "dyke", + "fag", + "faggot", + "feck", + "fellate", + "fellatio", + "fuck", + "fucking", + "fucks", + "f u c k", + "Goddamn", + "God damn", + "hell", + "homo", + "jerk", + "jizz", + "knobend", + "knob end", + "labia", + "lmao", + "lmfao", + "nigger", + "nigga", + "prick", + "pube", + "pussy", + "queer", + "retard", + "sex", + "bullshit", + "shit", + "slut", + "tit", + "turd", + "twat", + "whore", + "wtf" + ]; + + const regexbadWords = new RegExp(`\\b(?:${badWords.join('|')})\\b`, 'gi'); + message = message.replace(regexbadWords, '#%*!'); + return message; +}; + +//END Masking + +// #region Response Link Click Handling +store.conversationEvent.chipOnClick = (data) => { + console.log(JSON.stringify(data)); + if (data.url) { + window.open(data.url, '_blank'); + } else if (data.action) { + switch (data.action) { + case "hideMessenger": + console.log('Got to hide messenger'); + store.main.hideMessenger(); + break; + } + } + else { + store.conversationEvent.sendMessage(data); + } +} +// endregion \ No newline at end of file diff --git a/IVA-Wakeup/global/gvf_ConversationHistory.js b/IVA-Wakeup/global/gvf_ConversationHistory.js new file mode 100644 index 0000000..199bc5c --- /dev/null +++ b/IVA-Wakeup/global/gvf_ConversationHistory.js @@ -0,0 +1,68 @@ +return { + async fetchConversationHistory(conversationId, limit) { + + let datahistory = await db.collection("analytics_transactions").aggregate([ + { + $match: { + $and: [ + { "conversationId": conversationId }, + { "outputs.datacollect": true } + ] + } + } + ]).toArray(); + + console.log('10 line'); + let lastElement = datahistory[datahistory.length - 1]; + console.log(lastElement?.metadata?.actionType); + let messages = []; + const tx_msg = (direction, text, sentTime) => { + return { + conversationId: conversationId, + direction, + text, + dateSent: new Date(sentTime).toISOString(), + }; + }; + let counts = { agent: 0, ivas: 0 }; + let agentName; + let is_async = null; + for (let msg of datahistory) { + if (msg?.answers.length) { + if (msg?.input !== "") { + messages.push(tx_msg("ToAgent", msg?.input, (msg?.metadata?.createdAt ?? Date.now()))); + } + counts.ivas++; + for (let i = 0; i < msg?.answers.length; i++) { + let answer = msg.answers[i]; + if (typeof answer !== "string") { + answer = JSON.stringify(answer ?? null); + } + messages.push(tx_msg("ToCustomer", answer, (msg?.metadata?.createdAt ?? Date.now()) + 50 + i)); + counts.ivas++; + } + } + if (limit > 0 && messages.length >= limit) break; + } + + const summary = { + conversationId: conversationId, + steps: [] + }; + + + messages.forEach(msg => { + summary.steps.push({ + who: msg.direction === "ToAgent" ? "Customer" : "System", + text: msg.text, + time: new Date(msg.dateSent).toLocaleString() + }); + }); + let history = ``; + summary.steps.forEach((step, index) => { + history += `${step.who}: ${step.text}
`; + }); + history+= `ActionType: ${lastElement?.metadata?.actionType}` + return history; + } +}; \ No newline at end of file diff --git a/IVA-Wakeup/global/gvf_handleIVAWakeupEvent.js b/IVA-Wakeup/global/gvf_handleIVAWakeupEvent.js new file mode 100644 index 0000000..f963bdf --- /dev/null +++ b/IVA-Wakeup/global/gvf_handleIVAWakeupEvent.js @@ -0,0 +1,39 @@ +return { + async handleIVAWakeupEvent(event, req, session, settings, redis, smStr, channel, eventPayload) { + try { + const ivaWakeupText = `



IVA-Wakeup

`; + + if (event.text === ivaWakeupText) { + const nluSettings = settings.nlu; + + const result = await axios.post( + `${nluSettings.apiBaseURL}Model/run/${req.params.workspaceId}/${req.params.branch}/${nluSettings.modelName}`, + { + input: "CaseSetup", + conversationId: session.conversationId, + settings: nluSettings.settings, + sessionId: event.sessionId + } + ); + + eventPayload.options = result?.data?.options; + eventPayload.metadata = { + outputs: result.data?.outputs, + channel: channel + }; + eventPayload.input = result.data.answers[0]; + eventPayload.metadata.outputs.disableMessengerInput = true; + eventPayload.metadata.outputs.datacollect = true; + + await redis.hSet(smStr, { + formFlow: "true", + datacollect: "true", + sentdata: "false" + }); + } + } catch (e) { + console.info("Error with IVA-Wakeup"); + console.error(e); + } + } +}; \ No newline at end of file diff --git a/IVA-Wakeup/proxy/CAInterface_Chat.js b/IVA-Wakeup/proxy/CAInterface_Chat.js new file mode 100644 index 0000000..11fbfe7 --- /dev/null +++ b/IVA-Wakeup/proxy/CAInterface_Chat.js @@ -0,0 +1,420 @@ +console.info("===== Live Chat Proxy Entry - v16.3 ====="); + +const casettings = CAInterface_settings; +const CA = CAInterface(); +const msgrSettings = eval(`settings${casettings.hubSuffixMessenger}`); +let nlu = msgrSettings?.nlu; + +const _SELF = `${nlu.apiBaseURL}ProxyScript/run/${req.params.workspaceId}/${req.params.branch}/CAInterface_chat${casettings.hubSuffix}`; + +// API Specific +const headers = { + Authorization: `Basic ${buffer.Buffer.from(casettings.token.basicAuth).toString("base64")}`, + "Accept-Language": "en-US,en;q=0.5", +}; + +const studioToken = msgrSettings ? { Authorization: `Bearer ${msgrSettings.messenger.token}` } : {}; + +console.info({ + "Express Request": { + body: req.body, + }, +}); + +const agentAltId = "G3YxOTO1LO_1NlJXEIfk"; + +// gather fields from request body +const { conversationId, event, input, location, logged, options, queryParams, request, transcript } = req.body || {}; + +const channel = req?.body?.event?.metadata?.channel ?? req?.body?.channel ?? "web"; +const metadata = req.body.event?.metadata; + +const connectedWithAgent = (session) => session?.liveChatRequest && session?.agent?.userId; + +const loopScale = 3; +const smStr = `session-map-${conversationId}`; + +(async () => { + const session = await redis.hGetAll(smStr); + + // parse session from string to object + Object.keys(session).forEach((key) => { + try { + session[key] = JSON.parse(session[key]); + } catch (e) {} + }); + + const elapsed = (Date.now() - session?.lastActivity) / 1000; + const qelapsed = (Date.now() - session?.lastQueueStatus) / 1000; + + console.info(`Time since last user activity: ${elapsed}s`); + session.warned ||= false; + + if (!session?.discoveryUrls) { + const { urls } = await CA.restUrls(); + session.discoveryUrls = urls; + + await redis.hSet(smStr, { + discoveryUrls: JSON.stringify(urls), + }); + } + + if (event != "FETCH") { + console.info({ Session: session }); + } + + const delayCallFetch = async (delay) => { + const id = uuidv4(); + await redis.hSet(smStr, { fetchid: id }); + + let numSeconds = typeof delay === "number" ? delay : loopScale; + + setTimeout(async (smStr, id) => { + const session = await redis.hGetAll(smStr); + if (session.fetchid == id) { + axios({ + method: "post", + url: _SELF, + headers: { "Content-Type": "application/json" }, + data: { channel, conversationId, event: "FETCH" }, + }); + } else { + console.info("Fetch: loop stopped (old id)"); + } + }, 1000 * numSeconds, smStr, id); + }; + + switch (event) { + case "JOIN": { + console.info("Joining live chat session"); + const chatRequestDefaults = { + customerFirstName: "", + customerLastName: "", + customerEmail: "", + chatLaunchMode: "CHAT_ONLY", + refererURL: "example.com", + launchIdentifier: casettings.liveChat.launchIdentifier, + launchCode: "TextChatCustomerDataED", + transcript, + }; + + const customFieldsDefaults = { company: "Verint" }; + const chatRequest = { ...chatRequestDefaults, ...(request ?? {}) }; + chatRequest.customFields = { ...customFieldsDefaults, ...(request?.customFields ?? {}) }; + + const data = await CA.axios(`Posting data to "${session.discoveryUrls.client}"`, { + method: "post", + url: session.discoveryUrls.client, + headers, + data: chatRequest, + }); + + // Clean up _links + const links = {}; + Object.keys(data._links).forEach((key) => { + links[key] = data._links[key].href; + }); + data._links = links; + + console.info(data); + + await redis.hSet(smStr, { + liveChatRequest: "true", + chatDetails: JSON.stringify(data), + lastActivity: JSON.stringify(Date.now()), + lastQueueStatus: JSON.stringify(Date.now()), + }); + + const queueStatus = await CA.axios(`Getting queue status from "${data._links.queuedstatus}"`, + { method: "get", url: data._links.queuedstatus, headers }, + async () => { + await CA.postEvent(channel, conversationId, { input: casettings.liveChat.queueDisconnectMessage }); + } + ); + + if (queueStatus.message) { + await CA.postEvent(channel, conversationId, { input: queueStatus.message }); + } + + delayCallFetch(); + break; + } + + case "LEAVE": { + console.info("Leaving live chat session"); + try { + const { data } = await axios({ + method: "post", + url: session.chatDetails._links.logout, + headers, + }); + console.info({ "Logout Response": data }); + + if (connectedWithAgent(session)) { + await CA.postConversationLeave( + channel, + conversationId, + session.agent.userId || casettings.liveChat.participantId || agentAltId, + "liveChatEnded" + ); + } + } catch (e) { + console.error(e); + } + + console.info("reset session map"); + await redis.hSet(smStr, { liveChatRequest: "false", agent: "{}" }); + break; + } + + case "FETCH": { + const State = { waiting: 0, leaving: 1, offline: 2 }; + let state = State.waiting; + + if (session.liveChatRequest == false) { + console.info("Live Chat is off"); + state = State.offline; + } else if (session && session.chatDetails) { + // queue status check + if (!connectedWithAgent(session) && qelapsed > 30) { + const queueStatus = await CA.axios( + `Getting queue status from "${session.chatDetails._links.queuedstatus}"`, + { method: "get", url: session.chatDetails._links.queuedstatus, headers }, + async () => { + await CA.postEvent(channel, conversationId, { input: casettings.liveChat.queueDisconnectMessage }); + } + ); + + if (queueStatus.message && queueStatus.message != session.lastQueueMessage) { + await CA.postEvent(channel, conversationId, { input: queueStatus.message }); + await redis.hSet(smStr, { + lastQueueStatus: JSON.stringify(Date.now()), + lastQueueMessage: queueStatus.message + }); + } + } + + const data = await CA.axios( + `Getting Events from "${session.chatDetails._links.event}"`, + { method: "get", url: session.chatDetails._links.event, headers } + ); + + data.events = data.events.map((event) => JSON.parse(event)); + + if (data.events.length > 0) console.info(data.events); + + const sagent = session.agent || {}; + const au_default = { + userId: casettings.liveChat.participantId || agentAltId, + avatar: casettings.liveChat.avatar, + type: "agent", + }; + let agent_user = { ...au_default, ...sagent }; + + for (const event of data.events) { + const agentUser = { ...agent_user, name: event.userDisplayName }; + + if (event.userType === "GUEST") { + console.info(event); + switch (event.type) { + case "MessageReceived": { + console.info(`Guest said "${event.text}"`); + await CA.postEvent(channel, conversationId, { + conversationId, + input: event.text, + sentBy: agentUser, + ping: nanoid(), + sentAt: Date.now(), + }); + CA.addTransaction(session.conversationId, event.text, + { type: "agent", name: event.userDisplayName, userId: event.userId }, + { liveChat: true } + ); + break; + } + } + } else if (event.userType === "AGENT") { + console.info(event); + switch (event.type) { + case "UserTyping": + await CA.postTyping(channel, conversationId); + break; + + case "AttachmentMessageReceived": { + let url = `${casettings.liveChat.attachment.endpoint}/ProxyScript/run/${req.params.workspaceId}/${req.params.branch}/CA_attachments${casettings.hubSuffix}`; + url += `?url=${encodeURIComponent(event.url)}&sessionId=${event.sessionId}&fileName=${encodeURIComponent(event.fileName)}`; + const response = await CA.downloadFile(event.url, event.sessionId); + + if (CA.channelIsExternal(channel) && response.headers['content-type']) { + const attachment = { url, mimeType: response.headers['content-type'], fileName: event.fileName }; + CA.postEvent(channel, conversationId, { metadata: { channel, attachments: [attachment] } }); + } + break; + } + + case "MessageReceived": { + console.info(`Agent ${event.userDisplayName} said "${event.text}"`); + agent_user.name = event.userDisplayName; + + let eventPayload = { + conversationId, + input: event.text, + sentBy: agentUser, + ping: nanoid(), + sentAt: Date.now(), + }; + + if (data.events.some((x) => x.type == "UserExited")) { + console.info("Setting liveChat to false"); + eventPayload.metadata = { outputs: { liveChat: false } }; + } + + await gvf_handleIVAWakeupEvent().handleIVAWakeupEvent( + event, req, session, settings_66a1322d44405adda4fe9f53, redis, smStr, channel, eventPayload + ); + + if (session.formFlow !== true) { + await CA.postEvent(channel, conversationId, eventPayload); + } + + CA.addTransaction( + session.conversationId, + event.text, + { type: "agent", name: event.userDisplayName, userId: event.userID }, + eventPayload?.metadata?.outputs || { liveChat: true } + ); + break; + } + + case "UserEntered": + console.info(`Agent ${event.userDisplayName} joined`); + agent_user.name = event.userDisplayName; + await redis.hSet(smStr, { agent: JSON.stringify(agent_user) }); + await CA.postConversationJoin(channel, conversationId, agent_user); + await CA.postEvent(channel, conversationId, { + conversationId, + input: `You are now connected with ${event.userDisplayName}`, + sentBy: { ...agentUser, type: "host" }, + ping: nanoid(), + sentAt: Date.now(), + }); + break; + + case "UserExited": + state = State.leaving; + console.info(`Agent ${event.userDisplayName} left`); + break; + } + } + } + } else { + console.info("Session does not exist!"); + break; + } + + // State handling + switch (state) { + case State.waiting: { + const idle = casettings.liveChat.idle; + + if (elapsed > idle.disconnect.seconds && session.warned) { + CA.addTransaction(session.conversationId, "Live Chat Timeout", { type: "host" }, { liveChat: false }); + await CA.postEvent(channel, conversationId, { input: idle.disconnect.message }); + state = State.leaving; + + await axios({ + method: "post", + url: _SELF, + headers: studioToken, + data: { channel, conversationId, event: "LEAVE", session }, + }); + break; + } else if (elapsed > idle.warning.seconds && !session.warned) { + await CA.postEvent(channel, conversationId, { input: idle.warning.message }); + await redis.hSet(smStr, { warned: "true" }); + } + + delayCallFetch(); + break; + } + + case State.leaving: + console.info("Leaving session"); + await axios({ + method: "post", + url: _SELF, + headers: studioToken, + data: { channel, conversationId, event: "LEAVE", session }, + }); + break; + + default: + state = State.offline; + break; + } + + break; + } + + default: { + console.info("Live chat ongoing"); + + if (input && session && session.chatDetails) { + console.info(session.chatDetails); + console.info(`Sending "${input}" to live chat`); + + await axios({ + method: "post", + url: session.chatDetails._links.event, + headers, + data: [{ type: "MessageSent", text: input }], + }); + + await redis.hSet(smStr, { + lastActivity: JSON.stringify(Date.now()), + warned: "false", + lastQueueMessage: "", + lastQueueStatus: 0, + }); + + delayCallFetch(); + } + } + } +})() + .catch(async (error) => { + console.error(`Caught error: ${error}`); + if (error.response) console.error(`Caught error: ${error.response.data}`); + + const session = await redis.hGetAll(smStr); + + if (session) { + await redis.hSet(smStr, { liveChatRequest: "false", agent: "{}" }); + + if (session && session.agent && session.chatDetails) { + session.agent = JSON.parse(session.agent); + session.chatDetails = JSON.parse(session.chatDetails); + + if (connectedWithAgent(session)) { + CA.postConversationLeave( + channel, + conversationId, + session.agent.userId || casettings.liveChat.participantId || agentAltId, + "AgentExited" + ); + } + + axios({ method: "post", url: session.chatDetails._links.logout, headers }); + } + } + + if (conversationId && session.conversationId) { + CA.addTransaction(session.conversationId, "Live Chat Error", { type: "host" }, { liveChat: false }); + await CA.postEvent(channel, conversationId, { + input: "There was a connection issue with the Live Chat, and you were disconnected.", + }); + } + }) + .finally(() => { + res.send(200); + }); diff --git a/IVA-Wakeup/proxy/CAInterface_Messenger.js b/IVA-Wakeup/proxy/CAInterface_Messenger.js new file mode 100644 index 0000000..e0038a1 --- /dev/null +++ b/IVA-Wakeup/proxy/CAInterface_Messenger.js @@ -0,0 +1,132 @@ +console.log("===== Main Messenger Proxy - v17.9 ====="); +const casettings = CAInterface_settings; +console.log(req); +const external = req.body.event?.external; +const sessionId = req.body.event?.conversationId; +const metadata = req.body.event?.metadata; +const msgrSettings = eval(`settings${casettings.hubSuffixMessenger}`); +let nlu = msgrSettings?.nlu; +if (!nlu) { + console.log("Install Basic Messenger Webhook."); + console.log("Validate the value of hubSuffixMessenger in CAInterface_settings"); +} + +const messengerUrl = `${nlu.apiBaseURL}ProxyScript/run/${req.params.workspaceId}/${req.params.branch}/messenger${casettings.hubSuffixMessenger}`; +const CA = CAInterface(); +const channel = req?.body?.event?.metadata?.channel ?? req?.body?.channel; +const attachments = req?.body?.event?.metadata?.attachments; + +const validEventInput = (event) => { + console.log(20); + console.log(event); + return event?.input && event.input.length != 0; +}; + +const getGatewayHeaders = async () => { + const header = {}; + if (channel == "whatsapp") { + const notify = casettings.notifications ?? []; + const handler = notify.find(v => v.name === "VMGateway_eventHandler"); + if (handler) { + const suffix = handler.hubSuffix || ""; + const gatewaySettings = eval("VMGateway_settings" + suffix); + const { refreshGatewayKey } = eval("VMGateway_support" + suffix); + if (gatewaySettings?.gateway) { + header["x-auth-apiKey"] = await refreshGatewayKey(gatewaySettings.gateway); + } + } + } + return header; +} + +(async () => { + try { + const smStr = `session-map-${sessionId}`; + //await redis.set("sentdata", "false"); + const sessionMap = await redis.hGetAll(smStr); + console.log(sessionMap); + console.log(`47 line`); + console.log(smStr); + console.log({ + "Session Map": sessionMap, + }); + if (sessionMap.chatDetails) { + sessionMap.chatDetails = JSON.parse(sessionMap.chatDetails); + } + if (attachments?.length && sessionMap.liveChatRequest !== "true") { + res.send({ + conversationId: sessionId, workspaceId: req.params.workspaceId, + answers: [casettings.liveChat.attachment.noLiveChat] + }); + } else if (sessionMap.liveChatRequest == "true" && sessionMap.formFlow !== "true") { + if (attachments && attachments.length && sessionMap?.chatDetails?.userId) { + const headers = await getGatewayHeaders(); + for (let attachment of attachments) { + CA.sendAttachmentToAgent(sessionMap.chatDetails.userId, attachment, headers); + console.log({ attachment }); + } + } + if (metadata?.liveChat === false) { + await CA.leaveLiveChat(sessionId, sessionMap.conversationId, channel, + req.body.event?.input, req.body.event?.sentBy?.userId); + } else if (validEventInput(req.body.event)) { + await CA.sendToLiveChat(sessionId, sessionMap.conversationId, channel, + req.body.event?.input, req.body.event?.sentBy?.userId); + } + res.send({ + conversationId: sessionId, workspaceId: req.params.workspaceId, + input: req.body.event?.input, answers: [], + classificationResults: [] + }); + // } + } + else if (validEventInput(req.body.event)) { + console.log(79); + console.log(metadata); + // call the webhook + const { data: recognizedData } = await axios({ + url: messengerUrl, + method: "post", + data: req.body, + }); + if (recognizedData?.formFlowEnd) { + let sentdata = sessionMap?.sentdata; + if (sessionMap?.datacollect === "true" && sentdata === "false") { + let history = await gvf_ConversationHistory().fetchConversationHistory(sessionMap?.conversationId, 0); + if (metadata?.liveChat === false) { + await CA.leaveLiveChat(sessionId, sessionMap.conversationId, channel, + history, req.body.event?.sentBy?.userId); + } else if (validEventInput(req.body.event)) { + await CA.sendToLiveChat(sessionId, sessionMap.conversationId, channel, + history, req.body.event?.sentBy?.userId); + } + await redis.hSet(smStr, { + datacollect: "false", + sentdata: "true" + }); + } + } + if (recognizedData?.outputs?.liveChat === true || metadata?.liveChat == true) { + if (external && metadata?.liveChat == true) { + // need to log invisible chat messages + CA.addTransaction(recognizedData.conversationId, "Start Live Chat", "user", { + liveChat: true, + }); + } + CA.joinLiveChat( + channel, + sessionId, + recognizedData.conversationId, + recognizedData?.outputs?.liveChatRequest + ); + } + res.send(recognizedData); + } + } catch (error) { + console.log(error.message); + res.send({ + answers: ["Something went wrong. Please try again."], + outputs: {}, + }); + } +})(); \ No newline at end of file diff --git a/IVA-Wakeup/proxy/messenger.js b/IVA-Wakeup/proxy/messenger.js new file mode 100644 index 0000000..bd94787 --- /dev/null +++ b/IVA-Wakeup/proxy/messenger.js @@ -0,0 +1,197 @@ +// console.log(req.params); +// console.log(req.query); +console.log(req.body); +const external = req.body.event?.external; +const sessionId = req.body.event?.conversationId; +const input = req.body.event?.input; +const params = req.body.event?.params || {}; +const modelName = params?.modelName || settings_66a1322d44405adda4fe9f53.nlu.modelName; +const env = params?.env; +const postBack = req.body.event?.postBack; +const metadata = { + ...req.body.event?.metadata, + userId: req.body.event?.sentBy?.userId +}; +switch (metadata?.tenantName) { + case 'lexingtonLaw': + settings_66a1322d44405adda4fe9f53.messenger.avatar = 'data:image/png;base64,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'; + break;sessionId + case 'credit': + settings_66a1322d44405adda4fe9f53.messenger.avatar = 'data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAJYAAACWCAYAAAA8AXHiAAAAGXRFWHRTb2Z0d2FyZQBBZG9iZSBJbWFnZVJlYWR5ccllPAAAAydpVFh0WE1MOmNvbS5hZG9iZS54bXAAAAAAADw/eHBhY2tldCBiZWdpbj0i77u/IiBpZD0iVzVNME1wQ2VoaUh6cmVTek5UY3prYzlkIj8+IDx4OnhtcG1ldGEgeG1sbnM6eD0iYWRvYmU6bnM6bWV0YS8iIHg6eG1wdGs9IkFkb2JlIFhNUCBDb3JlIDkuMS1jMDAyIDc5LmE2YTYzOTY4YSwgMjAyNC8wMy8wNi0xMTo1MjowNSAgICAgICAgIj4gPHJkZjpSREYgeG1sbnM6cmRmPSJodHRwOi8vd3d3LnczLm9yZy8xOTk5LzAyLzIyLXJkZi1zeW50YXgtbnMjIj4gPHJkZjpEZXNjcmlwdGlvbiByZGY6YWJvdXQ9IiIgeG1sbnM6eG1wPSJodHRwOi8vbnMuYWRvYmUuY29tL3hhcC8xLjAvIiB4bWxuczp4bXBNTT0iaHR0cDovL25zLmFkb2JlLmNvbS94YXAvMS4wL21tLyIgeG1sbnM6c3RSZWY9Imh0dHA6Ly9ucy5hZG9iZS5jb20veGFwLzEuMC9zVHlwZS9SZXNvdXJjZVJlZiMiIHhtcDpDcmVhdG9yVG9vbD0iQWRvYmUgUGhvdG9zaG9wIDI1LjEyIChXaW5kb3dzKSIgeG1wTU06SW5zdGFuY2VJRD0ieG1wLmlpZDoxNDg4QjNENzgwRTAxMUVGQjAyN0QwRDk5RkZBODk5RSIgeG1wTU06RG9jdW1lbnRJRD0ieG1wLmRpZDoxNDg4QjNEODgwRTAxMUVGQjAyN0QwRDk5RkZBODk5RSI+IDx4bXBNTTpEZXJpdmVkRnJvbSBzdFJlZjppbnN0YW5jZUlEPSJ4bXAuaWlkOjE0ODhCM0Q1ODBFMDExRUZCMDI3RDBEOTlGRkE4OTlFIiBzdFJlZjpkb2N1bWVudElEPSJ4bXAuZGlkOjE0ODhCM0Q2ODBFMDExRUZCMDI3RDBEOTlGRkE4OTlFIi8+IDwvcmRmOkRlc2NyaXB0aW9uPiA8L3JkZjpSREY+IDwveDp4bXBtZXRhPiA8P3hwYWNrZXQgZW5kPSJyIj8+nSTq8QAAJMVJREFUeNrs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'; + break; + case 'creditRepair': + settings_66a1322d44405adda4fe9f53.messenger.avatar = 'data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAJYAAACWCAYAAAA8AXHiAAAAGXRFWHRTb2Z0d2FyZQBBZG9iZSBJbWFnZVJlYWR5ccllPAAAAydpVFh0WE1MOmNvbS5hZG9iZS54bXAAAAAAADw/eHBhY2tldCBiZWdpbj0i77u/IiBpZD0iVzVNME1wQ2VoaUh6cmVTek5UY3prYzlkIj8+IDx4OnhtcG1ldGEgeG1sbnM6eD0iYWRvYmU6bnM6bWV0YS8iIHg6eG1wdGs9IkFkb2JlIFhNUCBDb3JlIDkuMS1jMDAyIDc5LmE2YTYzOTY4YSwgMjAyNC8wMy8wNi0xMTo1MjowNSAgICAgICAgIj4gPHJkZjpSREYgeG1sbnM6cmRmPSJodHRwOi8vd3d3LnczLm9yZy8xOTk5LzAyLzIyLXJkZi1zeW50YXgtbnMjIj4gPHJkZjpEZXNjcmlwdGlvbiByZGY6YWJvdXQ9IiIgeG1sbnM6eG1wPSJodHRwOi8vbnMuYWRvYmUuY29tL3hhcC8xLjAvIiB4bWxuczp4bXBNTT0iaHR0cDovL25zLmFkb2JlLmNvbS94YXAvMS4wL21tLyIgeG1sbnM6c3RSZWY9Imh0dHA6Ly9ucy5hZG9iZS5jb20veGFwLzEuMC9zVHlwZS9SZXNvdXJjZVJlZiMiIHhtcDpDcmVhdG9yVG9vbD0iQWRvYmUgUGhvdG9zaG9wIDI1LjEyIChXaW5kb3dzKSIgeG1wTU06SW5zdGFuY2VJRD0ieG1wLmlpZDpENDFBMDBBNzdCNTExMUVGQjEyNEE3NUQ0QjBEMjc4MyIgeG1wTU06RG9jdW1lbnRJRD0ieG1wLmRpZDpENDFBMDBBODdCNTExMUVGQjEyNEE3NUQ0QjBEMjc4MyI+IDx4bXBNTTpEZXJpdmVkRnJvbSBzdFJlZjppbnN0YW5jZUlEPSJ4bXAuaWlkOkQ0MUEwMEE1N0I1MTExRUZCMTI0QTc1RDRCMEQyNzgzIiBzdFJlZjpkb2N1bWVudElEPSJ4bXAuZGlkOkQ0MUEwMEE2N0I1MTExRUZCMTI0QTc1RDRCMEQyNzgzIi8+IDwvcmRmOkRlc2NyaXB0aW9uPiA8L3JkZjpSREY+IDwveDp4bXBtZXRhPiA8P3hwYWNrZXQgZW5kPSJyIj8+y75tGwAAH95JREFUeNrs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'; + break; +} +const configuration = req.body.event?.configuration; +(async () => { + try { + const smStr = `session-map-${sessionId}`; + console.log('line 30'); + console.log(smStr); + if (external) { } else { + await axios.post(`${settings_66a1322d44405adda4fe9f53.messenger.apiBaseURL}Conversation/join`, { + _id: sessionId, + participant: { + userId: settings_66a1322d44405adda4fe9f53.messenger.participantId, + type: 'bot', + name: settings_66a1322d44405adda4fe9f53.messenger.name, + avatar: settings_66a1322d44405adda4fe9f53.messenger.avatar + } + }, { + headers: { + Authorization: `Bearer ${settings_66a1322d44405adda4fe9f53.messenger.token}` + } + }).then(response => { + if (response?.data?._id) { } else throw new Error(); + }); + axios.post(`${settings_66a1322d44405adda4fe9f53.messenger.apiBaseURL}Event/isTyping`, { + workspaceId: req.params.workspaceId, + conversationId: sessionId, + userId: settings_66a1322d44405adda4fe9f53.messenger.participantId, + typing: true + }, { + headers: { + Authorization: `Bearer ${settings_66a1322d44405adda4fe9f53.messenger.token}` + } + }); + } + const sessionMap = await redis.hGetAll(smStr); + // console.log(sessionMap); + const recognizedData = await axios.post(`${settings_66a1322d44405adda4fe9f53.nlu.apiBaseURL}Model/run/${req.params.workspaceId}/${req.params.branch}/${modelName}`, { + input: input, + conversationId: sessionMap.conversationId, + settings: settings_66a1322d44405adda4fe9f53.nlu.settings, + metadata: metadata, + postBack: postBack, + configuration: configuration + }).then(response => { + return response.data; + }).catch(error => { + //If we have error handling turned off, don't record the error + if (settings_66a1322d44405adda4fe9f53.errorHandling === false) { + throw error; + } else { + // Conversation ID is generated by the NLU + // Must make sure Conversation ID is created properly for an error transaction + // Get it from session map if it exists, or generate it if we got the error at the very first transaction. + const conversationId = sessionMap.conversationId || uuidv4(); + let errorPayload = { + id: uuidv4(), + workspaceId: req.params.workspaceId, + errorInfo: { + name: error.name, + message: error.message, + stack: error.stack + }, + conversationId, + input, + answers: [settings_66a1322d44405adda4fe9f53.responses.modelError], + req: { + params: req.params, + query: req.query, + body: req.body, + headers: req.headers + }, + metadata, + classificationResults: [{ + label: "Model Error", + value: 0.0 + }], + nerResults: { + entities: [], + sourceEntities: [] + }, + // Reporting tags to match GlobalSupport function reporting + tag: "ERROR", + reporting: { + tag: "ERROR", + modelResponse: "ERROR" + } + }; + + // Add model name + errorPayload.req.params.route = modelName; + + //add any other details you wish to see in transaction data + + return errorPayload; + } + }); + let formFlowEnd = recognizedData.formFlowEnd; + if (formFlowEnd) { + await redis.hSet(smStr, { + formFlow: "false", + }); + } + if (recognizedData.conversationId) { + await redis.hSet(smStr, 'conversationId', recognizedData.conversationId); + await redis.expire(smStr, 3600); + if (sessionMap.conversationId) { } else { + db.analytics.addConversation({ + id: recognizedData.conversationId + }); + } + } + // NOTE: Additonal logic could be used to provide answer from alternative sources + // recognizedData.answers = API_RESPONSE || ['Example']; + if (recognizedData.tag === "ERROR") { } else if (recognizedData.classificationResults.length === 0 && recognizedData.answers.length === 0) { + recognizedData.answers = [settings_66a1322d44405adda4fe9f53.responses.unrecognized]; + } else if (recognizedData.answers.length === 0) { + recognizedData.answers = [settings_66a1322d44405adda4fe9f53.responses.unanswered]; + } + recognizedData._id = (await db.analytics.addTransaction(recognizedData)).insertedId; + console.log({ recognizedData }); + //edh_gvf_664f9ce8a46543d70da1ed74(recognizedData); //added for EDH hookup based on documentations + if (external) { } else { + new Promise(async resolve => { + for (const [index, answer] of recognizedData.answers.entries()) { + console.log(recognizedData.tag) + try { + console.log(151); + console.log(sessionId); + await axios.post(`${settings_66a1322d44405adda4fe9f53.messenger.apiBaseURL}Event/create`, { + conversationId: sessionId, + input: answer, + sentBy: { + userId: settings_66a1322d44405adda4fe9f53.messenger.participantId, + name: settings_66a1322d44405adda4fe9f53.messenger.name, + avatar: settings_66a1322d44405adda4fe9f53.messenger.avatar + }, + ping: nanoid(), + sentAt: Date.now(), + options: recognizedData?.options, + metadata: { + outputs: recognizedData.answers.length == index + 1 ? recognizedData?.outputs : {}, + transactionId: recognizedData._id, + feedbackable: ['seaiSelfServiceComplete', 'seaiSelfServiceInformational', 'LLM'].includes(recognizedData.tag) + } + }, { + headers: { + Authorization: `Bearer ${settings_66a1322d44405adda4fe9f53.messenger.token}` + } + }); + } catch (e) { } + } + resolve(true); + }); + axios.post(`${settings_66a1322d44405adda4fe9f53.messenger.apiBaseURL}Event/isTyping`, { + workspaceId: req.params.workspaceId, + conversationId: sessionId, + userId: settings_66a1322d44405adda4fe9f53.messenger.participantId, + typing: false + }, { + headers: { + Authorization: `Bearer ${settings_66a1322d44405adda4fe9f53.messenger.token}` + } + }); + } + res.send(recognizedData); + } catch (error) { + console.log(error.message); + res.send({ + answers: ['Something went wrong. Please try again.'], + outputs: {} + }); + } +})(); \ No newline at end of file