From cd7b11263eff974ec1c12ad6c7143753e4049ce0 Mon Sep 17 00:00:00 2001 From: Brandon Tyler Date: Fri, 11 Aug 2023 16:45:40 -0500 Subject: [PATCH] persistent live chat changes if you hit refresh the previous connection to amazon connect is made --- lex-web-ui/src/components/LexWeb.vue | 26 ++++++++++++-- lex-web-ui/src/store/actions.js | 41 ++++++++++++++++++++-- lex-web-ui/src/store/live-chat-handlers.js | 32 +++++++++++++++++ lex-web-ui/src/store/mutations.js | 39 ++++++++++++++++++++ lex-web-ui/src/store/state.js | 5 +++ templates/codebuild-deploy.yaml | 2 +- 6 files changed, 139 insertions(+), 6 deletions(-) diff --git a/lex-web-ui/src/components/LexWeb.vue b/lex-web-ui/src/components/LexWeb.vue index 64c76ada..e06bad54 100644 --- a/lex-web-ui/src/components/LexWeb.vue +++ b/lex-web-ui/src/components/LexWeb.vue @@ -250,7 +250,11 @@ export default { Promise.resolve() )) .then(() => { - if (this.$store.state.config.ui.saveHistory === true) { + if (this.$store.state.config.ui.saveHistory === true) { + var oldState = JSON.parse(sessionStorage.getItem('store')); + if (oldState) { + this.$store.replaceState(JSON.parse(sessionStorage.getItem('store'))); + } this.$store.subscribe((mutation, state) => { sessionStorage.setItem('store', JSON.stringify(state)); }); @@ -261,9 +265,25 @@ export default { 'successfully initialized lex web ui version: ', this.$store.state.version, ); - // after slight delay, send in initial utterance if it is defined. + //See if the liveChat was previously established + //console.info('liveChatStatus.ESTABLISHED: ', liveChatStatus.ESTABLISHED) THIS IS UNDEFINED + //TODO: I need to add the logic here to see if we need to re-establish chat + if (this.$store.state.liveChat.status === 'established') { + console.info('Previous liveChat connection was found. Reconnecting...'); + + //Because of logic in action.js chatMode has to be bot + //context.state.chatMode to chatMode.BOT or bot + //TODO: figure out why importing chatMode.BOT doesn't work + this.$store.commit('setChatMode', 'bot'); + + // after slight delay, send in live chat utterance. + // waiting for credentials to settle down a bit. + setTimeout(() => this.$store.dispatch('sendLiveChatUtterance'), 500); + this.$store.commit('setLiveChatUtteranceSent', true); + } + // Else after slight delay, send in initial utterance if it is defined. // waiting for credentials to settle down a bit. - if (!this.$store.state.config.iframe.shouldLoadIframeMinimized) { + else if (!this.$store.state.config.iframe.shouldLoadIframeMinimized) { setTimeout(() => this.$store.dispatch('sendInitialUtterance'), 500); this.$store.commit('setInitialUtteranceSent', true); } diff --git a/lex-web-ui/src/store/actions.js b/lex-web-ui/src/store/actions.js index 29e8e081..54f2f4d0 100644 --- a/lex-web-ui/src/store/actions.js +++ b/lex-web-ui/src/store/actions.js @@ -89,6 +89,15 @@ export default { context.dispatch('postTextMessage', message); } }, + sendLiveChatUtterance(context) { + console.info('sendLiveChatUtterance'); + const message = { + type: context.state.config.ui.hideButtonMessageBubble ? 'button' : 'human', + text: 'live chat', //TODO: pick the first live chat term and put it here + }; + context.dispatch('postTextMessage', message); + console.info('postTextMessage', message); + }, initMessageList(context) { context.commit('reloadMessages'); if (context.state.messages && @@ -490,18 +499,26 @@ export default { }) .then(() => { const liveChatTerms = context.state.config.connect.liveChatTerms ? context.state.config.connect.liveChatTerms.toLowerCase().split(',').map(str => str.trim()) : []; + console.info('context.state.chatMode: ', context.state.chatMode); + console.info('context.state.liveChat.status: ', context.state.liveChat.status); + console.info('message.text: ', message.text); if (context.state.config.ui.enableLiveChat && liveChatTerms.find(el => el === message.text.toLowerCase()) && context.state.chatMode === chatMode.BOT) { - return context.dispatch('requestLiveChat'); + console.info('HERE 1: dispatch requestLiveChat'); + return context.dispatch('requestLiveChat'); } else if (context.state.liveChat.status === liveChatStatus.REQUEST_USERNAME) { context.commit('setLiveChatUserName', message.text); + console.info('HERE 2: commit setLiveChatUserName dispatch requestLiveChat'); return context.dispatch('requestLiveChat'); } else if (context.state.chatMode === chatMode.LIVECHAT) { + console.info('HERE 3: Check liveChat.status') if (context.state.liveChat.status === liveChatStatus.ESTABLISHED) { + console.info('HERE 4: dispatch sendChatMessage') return context.dispatch('sendChatMessage', message.text); } } + console.info('HERE 5') return Promise.resolve(context.commit('pushUtterance', message.text)) }) .then(() => { @@ -865,6 +882,7 @@ export default { .then(json => json.data) .then((result) => { console.info('Live Chat Config Success:', result); + console.info('ParticipantToken: ', result.startChatResult.ParticipantToken) context.commit('setLiveChatStatus', liveChatStatus.CONNECTING); function waitMessage(context, type, message) { context.commit('pushLiveChatMessage', { @@ -881,6 +899,22 @@ export default { console.info(`interval now set: ${intervalID}`); context.commit('setLiveChatIntervalId', intervalID); } + //Determine if we need to overwrite the result.startChatResult.ParticipantToken + //before passing it to createLiveChatSession + console.info('context.state.liveChat.participantToken: ', context.state.liveChat.participantToken) + if (!context.state.liveChat.participantToken){ + console.info('First Connection save the participant token'); + context.commit('setParticipantToken', result.startChatResult.ParticipantToken); + context.commit('setParticipantId', result.startChatResult.ParticipantId); + context.commit('setContactId', result.startChatResult.ContactId); + context.commit('setReconnectToActiveChat', false); + } else{ + console.info('Reconnecting to Connect LiveChat use the previous participant token'); + result.startChatResult.ParticipantToken = context.state.liveChat.participantToken; + result.startChatResult.ParticipantId = context.state.liveChat.participantId; + result.startChatResult.ContactId = context.state.liveChat.contactId; + context.commit('setReconnectToActiveChat', true); + } liveChatSession = createLiveChatSession(result); console.info('Live Chat Session Created:', liveChatSession); initLiveChatHandlers(context, liveChatSession); @@ -902,7 +936,10 @@ export default { }, requestLiveChat(context) { - console.info('requestLiveChat'); + const loggedInUserEmail = context.state.lex.sessionAttributes['connect_loggedInUserEmail']; + if (loggedInUserEmail){ + context.commit('setLiveChatUserName', loggedInUserEmail); + } if (!context.getters.liveChatUserName()) { context.commit('setLiveChatStatus', liveChatStatus.REQUEST_USERNAME); context.commit( diff --git a/lex-web-ui/src/store/live-chat-handlers.js b/lex-web-ui/src/store/live-chat-handlers.js index d6d3f60a..9f30d707 100644 --- a/lex-web-ui/src/store/live-chat-handlers.js +++ b/lex-web-ui/src/store/live-chat-handlers.js @@ -42,6 +42,10 @@ export const initLiveChatHandlers = (context, session) => { // type: 'agent', // text: 'Live Chat Connection Established', // }); + if (context.state.liveChat.reconnectToActiveChat){ + context.commit('setIsLiveChatProcessing', false); + context.dispatch('liveChatAgentJoined'); + } }); session.onMessage((event) => { @@ -144,17 +148,45 @@ export const initLiveChatHandlers = (context, session) => { }); session.onTyping((typingEvent) => { + console.info('typingEvent: ', typingEvent); if (typingEvent.data.ParticipantRole === 'AGENT') { console.info('Agent is typing '); context.dispatch('agentIsTyping'); } }); + /* session.onConnectionBroken((data) => { console.info('Connection broken', data); context.dispatch('liveChatSessionReconnectRequest'); }); + + session.onEnded(event => { + const { chatDetails, data } = event; + console.info('Connection has ended.', event); + }); + + session.onParticipantIdle(event => { + const { chatDetails, data } = event; + console.info('participant.idle event', event); + }); + + session.onParticipantReturned(event => { + const { chatDetails, data } = event; + console.info('onParticipantReturned event', event); + }); + session.onAutoDisconnection(event => { + const { chatDetails, data } = event; + console.info('onAutoDisconnection event', event); + }); + + session.onConnectionLost(event => { + const { chatDetails, data } = event; + console.info('onConnectionLost event', event); + }); + */ + /* NOT WORKING session.onEnded((data) => { diff --git a/lex-web-ui/src/store/mutations.js b/lex-web-ui/src/store/mutations.js index dc8befe9..7f82f686 100644 --- a/lex-web-ui/src/store/mutations.js +++ b/lex-web-ui/src/store/mutations.js @@ -405,6 +405,45 @@ export default { state.liveChat.isProcessing = bool; }, + setLiveChatUtteranceSent(state) { + state.liveChatUtteranceSent = true; + }, + + setParticipantToken(state, participantToken) { + if (typeof participantToken !== 'string') { + console.error('setParticipantToken is not valid', participantToken); + return; + } + state.liveChat.participantToken = participantToken; + }, + + setParticipantId(state, participantId) { + if (typeof participantId !== 'string') { + console.error('setParticipantId is not valid', participantId); + return; + } + state.liveChat.participantId = participantId; + }, + + setContactId(state, contactId) { + if (typeof contactId !== 'string') { + console.error('setContactId is not valid', contactId); + return; + } + state.liveChat.contactId = contactId; + }, + + + + + setReconnectToActiveChat(state, bool) { + if (typeof bool !== 'boolean'){ + console.error('setReconnectToActiveChat status not boolean', bool); + return; + } + state.liveChat.reconnectToActiveChat = bool; + }, + setLiveChatUserName(state, name) { if (typeof name !== 'string') { console.error('setLiveChatUserName is not vaild', name); diff --git a/lex-web-ui/src/store/state.js b/lex-web-ui/src/store/state.js index 5ce09489..fb0208d7 100644 --- a/lex-web-ui/src/store/state.js +++ b/lex-web-ui/src/store/state.js @@ -60,6 +60,10 @@ export default { isProcessing: false, status: liveChatStatus.DISCONNECTED, message: '', + participantToken: '', + participantId: '', + contactId: '', + reconnectToActiveChat: false, }, messages: [], utteranceStack: [], @@ -95,6 +99,7 @@ export default { !!config.ui.messageSentSFX && !!config.ui.messageReceivedSFX) : false, isUiMinimized: false, // when running embedded, is the iframe minimized? initialUtteranceSent: false, // has the initial utterance already been sent + liveChatUtteranceSent: false, // has the live chat utterance already been sent isEnableLogin: false, // true when a login/logout menu should be displayed isForceLogin: false, // true when a login/logout menu should be displayed isLoggedIn: false, // when running with login/logout enabled diff --git a/templates/codebuild-deploy.yaml b/templates/codebuild-deploy.yaml index 33c64145..d1a586f4 100644 --- a/templates/codebuild-deploy.yaml +++ b/templates/codebuild-deploy.yaml @@ -363,7 +363,7 @@ Parameters: SaveHistory: Type: String - Default: false + Default: true AllowedValues: - true - false