diff --git a/packages/botonic-react/src/experimental/dev-app.jsx b/packages/botonic-react/src/experimental/dev-app.jsx
index 5b7ec22341..f71cf09fec 100644
--- a/packages/botonic-react/src/experimental/dev-app.jsx
+++ b/packages/botonic-react/src/experimental/dev-app.jsx
@@ -99,8 +99,10 @@ export class DevApp extends WebchatApp {
enableAnimations={enableAnimations}
storage={storage}
storageKey={storageKey}
- getString={(stringId, session) => this.bot.getString(stringId, session)}
- setLocale={(locale, session) => this.bot.setLocale(locale, session)}
+ getString={(stringId, botState) =>
+ this.bot.getString(stringId, botState)
+ }
+ setLocale={(locale, botState) => this.bot.setLocale(locale, botState)}
onInit={(...args) => this.onInitWebchat(...args)}
onOpen={(...args) => this.onOpenWebchat(...args)}
onClose={(...args) => this.onCloseWebchat(...args)}
diff --git a/packages/botonic-react/src/experimental/index.js b/packages/botonic-react/src/experimental/index.js
index 04ac998e1e..e2ea640cc3 100644
--- a/packages/botonic-react/src/experimental/index.js
+++ b/packages/botonic-react/src/experimental/index.js
@@ -38,9 +38,9 @@ class WebsocketBackendService {
// On Event Received...
this.wsClient.addEventListener('message', event => {
console.log(event, this.onEvent)
- const message = JSON.parse(decode(event.data))
+ const eventData = JSON.parse(decode(event.data))
if (this.onEvent && typeof this.onEvent === 'function')
- this.onEvent({ message })
+ this.onEvent(eventData)
})
}
async doAuthAndUpdateJwt() {
@@ -72,7 +72,7 @@ class WebsocketBackendService {
`${REST_API_URL}events/`,
{
message,
- sender: user,
+ sender: user, // TODO: Really needed or we should pass user information through JWT?
},
{ headers: { Authorization: 'Bearer ' + this.jwt } } // Note: Do not use string template as it will convert the token with commas, which will be invalid
)
@@ -85,14 +85,14 @@ class WebsocketBackendService {
if (hasErrors) {
// TODO: Handle rest of errors
await this.doAuthAndUpdateJwt()
- await this.postMessage(user, message)
+ // await this.postMessage(user, message) // Temporary, avoid infinite events loop
}
}
}
export class FullstackProdApp extends WebchatApp {
- async onUserInput({ user, input }) {
- this.onMessage && this.onMessage(this, { from: 'user', message: input })
+ async onUserInput({ user, input, session, botState }) {
+ this.onMessage && this.onMessage(this, { from: input.from, message: input })
this.backendService.postMessage(user, input)
}
@@ -100,7 +100,7 @@ export class FullstackProdApp extends WebchatApp {
return await this.backendService.doAuth({ userId })
}
- onStateChange({ session: { user }, messagesJSON, jwt, updateJwt }) {
+ onStateChange({ user, messagesJSON, jwt, updateJwt }) {
if (!this.backendService && user) {
const lastMessage = messagesJSON[messagesJSON.length - 1]
this.backendService = new WebsocketBackendService({
@@ -121,8 +121,8 @@ export class FullstackDevApp extends DevApp {
console.log('FullstackDevApp ', args.playgroundCode)
}
- async onUserInput({ user, input }) {
- this.onMessage && this.onMessage(this, { from: 'user', message: input })
+ async onUserInput({ user, input, session, botState }) {
+ this.onMessage && this.onMessage(this, { from: input.from, message: input })
this.backendService && this.backendService.postMessage(user, input)
}
@@ -176,8 +176,10 @@ export class FullstackDevApp extends DevApp {
storageKey={storageKey}
playgroundCode={this.playgroundCode}
onStateChange={webchatState => this.onStateChange(webchatState)}
- getString={(stringId, session) => this.bot.getString(stringId, session)}
- setLocale={(locale, session) => this.bot.setLocale(locale, session)}
+ getString={(stringId, botState) =>
+ this.bot.getString(stringId, botState)
+ }
+ setLocale={(locale, botState) => this.bot.setLocale(locale, botState)}
onInit={(...args) => this.onInitWebchat(...args)}
onOpen={(...args) => this.onOpenWebchat(...args)}
onClose={(...args) => this.onCloseWebchat(...args)}
@@ -191,7 +193,7 @@ export class FullstackDevApp extends DevApp {
return await this.backendService.doAuth({ userId })
}
- onStateChange({ session: { user }, messagesJSON, jwt, updateJwt }) {
+ onStateChange({ user, messagesJSON, jwt, updateJwt }) {
if (!this.backendService && user) {
const lastMessage = messagesJSON[messagesJSON.length - 1]
this.backendService = new WebsocketBackendService({
@@ -257,6 +259,7 @@ export class BrowserProdApp extends WebchatApp {
...botOptions,
})
}
+ // TODO: Review how this be done for only browser versions
async onUserInput({ input, session, lastRoutePath }) {
this.onMessage && this.onMessage(this, { from: 'user', message: input })
const resp = await this.bot.input({ input, session, lastRoutePath })
@@ -277,10 +280,10 @@ export { ShareButton } from '../components/share-button'
export { Subtitle } from '../components/subtitle'
export { Title } from '../components/title'
export { WebchatSettings } from '../components/webchat-settings'
-export { RequestContext, WebchatContext } from '../contexts'
export { staticAsset } from '../util/environment'
export { getBotonicApp } from '../webchat'
export { WebviewApp } from '../webview'
+export { RequestContext, WebchatContext } from './contexts'
// Experimental
export { Audio } from './components/audio'
export { Carousel } from './components/carousel'
diff --git a/packages/botonic-react/src/experimental/util/webchat.js b/packages/botonic-react/src/experimental/util/webchat.js
index 217f38da15..806aa4339f 100644
--- a/packages/botonic-react/src/experimental/util/webchat.js
+++ b/packages/botonic-react/src/experimental/util/webchat.js
@@ -1,3 +1,4 @@
+import { PROVIDER } from '@botonic/core'
import merge from 'lodash.merge'
import UAParser from 'ua-parser-js'
import { v4 as uuidv4 } from 'uuid'
@@ -34,14 +35,14 @@ export const createUser = () => {
return {
id: uuidv4(),
name,
+ channel: PROVIDER.DEV,
}
}
-export const initSession = session => {
- if (!session) session = {}
- const hasUserId = session.user && session.user.id !== undefined
- if (!session.user || Object.keys(session.user).length === 0 || !hasUserId)
- session.user = !hasUserId ? merge(session.user, createUser()) : createUser()
- return session
+
+export const initUser = user => {
+ if (!user) return createUser()
+ if (user && !user.id) return merge(user, createUser())
+ return user
}
export const shouldKeepSessionOnReload = ({
diff --git a/packages/botonic-react/src/experimental/webchat-app.jsx b/packages/botonic-react/src/experimental/webchat-app.jsx
index c8356af188..7fbec07bec 100644
--- a/packages/botonic-react/src/experimental/webchat-app.jsx
+++ b/packages/botonic-react/src/experimental/webchat-app.jsx
@@ -139,22 +139,27 @@ export class WebchatApp {
}
onServiceEvent(event) {
- if (event.action === 'connectionChange')
+ const { action, ...eventData } = event
+ if (action === 'connectionChange')
this.webchatRef.current.setOnline(event.online)
- // TODO: Temporary solution, decide how we will send these events in next iterations
- else if (event.message.action === 'update_message_info') {
- const { message } = event.message
- this.updateMessageInfo(message.id, message)
- } else if (event.action === 'update_message_info')
- this.updateMessageInfo(event.message.id, event.message)
- else if (event.message.type === 'update_webchat_settings')
- this.updateWebchatSettings(event.message.data)
- else if (event.message.type === 'sender_action')
- this.setTyping(event.message.data === 'typing_on')
- else {
+ else if (action === 'update_message_info') {
+ this.updateMessageInfo(eventData.id, eventData)
+ } else if (action === 'update_user') {
+ this.updateUser(eventData)
+ } else if (action === 'update_session') {
+ this.updateSession(eventData)
+ } else if (action === 'update_bot_state') {
+ this.updateBotState(eventData)
+ }
+ // TODO: Discuss how this updates to be done
+ else if (eventData.type === 'update_webchat_settings')
+ this.updateWebchatSettings(event.data)
+ else if (eventData.type === 'sender_action')
+ this.setTyping(event.data === 'typing_on')
+ else if (eventData.eventType === 'message') {
this.onMessage &&
- this.onMessage(this, { from: SENDERS.bot, message: event.message })
- this.addBotMessage(event.message)
+ this.onMessage(this, { from: SENDERS.bot, message: eventData })
+ this.addBotMessage(eventData)
}
}
@@ -162,6 +167,14 @@ export class WebchatApp {
this.webchatRef.current.updateUser(user)
}
+ updateSession(session) {
+ this.webchatRef.current.updateSession(session)
+ }
+
+ updateBotState(botState) {
+ this.webchatRef.current.updateBotState(botState)
+ }
+
addBotMessage(message) {
this.webchatRef.current.addBotResponse({
response: msgToBotonic(
diff --git a/packages/botonic-react/src/experimental/webchat/actions.jsx b/packages/botonic-react/src/experimental/webchat/actions.jsx
index 2c11e7acc9..c2dad111b3 100644
--- a/packages/botonic-react/src/experimental/webchat/actions.jsx
+++ b/packages/botonic-react/src/experimental/webchat/actions.jsx
@@ -20,3 +20,5 @@ export const UPDATE_LAST_MESSAGE_DATE = 'updateLastMessageDate'
export const SET_CURRENT_ATTACHMENT = 'setCurrentAttachment'
export const SET_ONLINE = 'setOnline'
export const UPDATE_JWT = 'updateJwt'
+export const UPDATE_USER = 'updateUser'
+export const UPDATE_BOT_STATE = 'updateBotState'
diff --git a/packages/botonic-react/src/experimental/webchat/hooks.js b/packages/botonic-react/src/experimental/webchat/hooks.js
index ea0d5067d8..740f69fef8 100644
--- a/packages/botonic-react/src/experimental/webchat/hooks.js
+++ b/packages/botonic-react/src/experimental/webchat/hooks.js
@@ -13,6 +13,7 @@ import {
TOGGLE_EMOJI_PICKER,
TOGGLE_PERSISTENT_MENU,
TOGGLE_WEBCHAT,
+ UPDATE_BOT_STATE,
UPDATE_DEV_SETTINGS,
UPDATE_HANDOFF,
UPDATE_JWT,
@@ -24,10 +25,32 @@ import {
UPDATE_SESSION,
UPDATE_THEME,
UPDATE_TYPING,
+ UPDATE_USER,
UPDATE_WEBVIEW,
} from './actions'
import { webchatReducer } from './webchat-reducer'
+export const initialUser = {
+ id: undefined,
+ name: undefined,
+ userName: undefined,
+ channel: undefined,
+ idFromChannel: undefined,
+ isOnline: true,
+}
+
+const initialBotState = {
+ botId: undefined,
+ lastRoutePath: null,
+ isFirstInteraction: true,
+ retries: 0,
+ locale: undefined,
+ isHandoff: false,
+ isShadowing: false,
+}
+
+const initialSession = {}
+
export const webchatInitialState = {
width: WEBCHAT.DEFAULTS.WIDTH,
height: WEBCHAT.DEFAULTS.HEIGHT,
@@ -38,9 +61,9 @@ export const webchatInitialState = {
typing: false,
webview: null,
webviewParams: null,
- session: { user: null },
- lastRoutePath: null,
- handoff: false,
+ // session: { user: null },
+ // lastRoutePath: null,
+ // handoff: false,
theme: {
headerTitle: WEBCHAT.DEFAULTS.TITLE,
brandColor: COLORS.BOTONIC_BLUE,
@@ -53,7 +76,7 @@ export const webchatInitialState = {
},
themeUpdates: {},
error: {},
- online: true,
+ isWebchatOnline: true,
devSettings: { keepSessionOnReload: false },
isWebchatOpen: false,
isEmojiPickerOpen: false,
@@ -62,6 +85,9 @@ export const webchatInitialState = {
lastMessageUpdate: undefined,
currentAttachment: undefined,
jwt: null,
+ user: initialUser,
+ session: initialSession,
+ botState: initialBotState,
}
export function useWebchat() {
@@ -87,12 +113,23 @@ export function useWebchat() {
type: UPDATE_WEBVIEW,
payload: { webview, webviewParams: params },
})
- const updateSession = session => {
+ const updateSession = session =>
webchatDispatch({
type: UPDATE_SESSION,
payload: session,
})
- }
+
+ const updateUser = user =>
+ webchatDispatch({
+ type: UPDATE_USER,
+ payload: user,
+ })
+
+ const updateBotState = botState =>
+ webchatDispatch({
+ type: UPDATE_BOT_STATE,
+ payload: botState,
+ })
const updateLastRoutePath = path =>
webchatDispatch({
@@ -198,6 +235,8 @@ export function useWebchat() {
updateLastMessageDate,
setCurrentAttachment,
updateJwt,
+ updateBotState,
+ updateUser,
}
}
diff --git a/packages/botonic-react/src/experimental/webchat/session-view.jsx b/packages/botonic-react/src/experimental/webchat/session-view.jsx
index 85d254b703..cbf8d2a7b5 100644
--- a/packages/botonic-react/src/experimental/webchat/session-view.jsx
+++ b/packages/botonic-react/src/experimental/webchat/session-view.jsx
@@ -100,7 +100,9 @@ const KeepSessionContainer = styled.div`
export const SessionView = props => {
// eslint-disable-next-line react-hooks/rules-of-hooks
const { webchatState, updateDevSettings } = props.webchatHooks || useWebchat()
- const { latestInput: input, session, lastRoutePath } = webchatState
+ const { latestInput: input, session, botState } = webchatState
+ const { type, id, ...latestInputData } = input
+
const toggleSessionView = () =>
updateDevSettings({
...webchatState.devSettings,
@@ -122,7 +124,7 @@ export const SessionView = props => {
label='INPUT:'
value={
input && Object.keys(input).length
- ? `[${input.type}] ${input.data || ''}`
+ ? `[${type}] ${JSON.stringify(latestInputData) || ''}`
: ''
}
/>
@@ -137,8 +139,12 @@ export const SessionView = props => {
/>
+
+
+
+
diff --git a/packages/botonic-react/src/experimental/webchat/webchat-dev.jsx b/packages/botonic-react/src/experimental/webchat/webchat-dev.jsx
index 57c4b20d37..738705f577 100644
--- a/packages/botonic-react/src/experimental/webchat/webchat-dev.jsx
+++ b/packages/botonic-react/src/experimental/webchat/webchat-dev.jsx
@@ -5,7 +5,6 @@ import React, { forwardRef, useEffect, useState } from 'react'
import { createPortal } from 'react-dom'
import styled from 'styled-components'
-import { SessionView } from '../../webchat/session-view'
import MessengerLogo from './assets/messenger.svg'
import Open from './assets/open.svg'
import OpenNewWindow from './assets/open-new-window.svg'
@@ -13,6 +12,7 @@ import TelegramLogo from './assets/telegram.svg'
import WebchatLogo from './assets/webchat.svg'
import WhatsappLogo from './assets/whatsapp.svg'
import { useWebchat } from './hooks'
+import { SessionView } from './session-view'
import { Webchat } from './webchat'
export const DebugTab = styled.div`
@@ -341,22 +341,25 @@ export const PlaygroundPortal = props =>
document.body
)
-const initialSession = {
- is_first_interaction: true,
- last_session: {},
- user: {
- id: '000001',
- username: 'johndoe',
- name: 'John Doe',
- provider: PROVIDER.DEV,
- provider_id: '0000000',
- extra_data: {},
- },
- organization: '',
- bot: {
- id: '0000000',
- name: 'botName',
- },
+const initialUser = {
+ id: '000001',
+ name: 'John Doe',
+ username: 'johndoe',
+ channel: PROVIDER.DEV,
+ idFromChannel: '0000000',
+ details: {},
+}
+
+const initialSession = {}
+
+const initialBotState = {
+ botId: '0000000',
+ isFirstInteraction: true,
+ retries: 0,
+ locale: undefined,
+ lastRoutePath: null,
+ isHandoff: false,
+ isShadowing: false,
}
// eslint-disable-next-line react/display-name
@@ -377,7 +380,9 @@ export const WebchatDev = forwardRef((props, ref) => {
{...props}
ref={ref}
webchatHooks={webchatHooks}
+ initialUser={initialUser}
initialSession={initialSession}
+ initialBotState={initialBotState}
initialDevSettings={{
keepSessionOnReload: webchatState.devSettings.keepSessionOnReload,
showSessionView: webchatState.devSettings.showSessionView,
diff --git a/packages/botonic-react/src/experimental/webchat/webchat-reducer.js b/packages/botonic-react/src/experimental/webchat/webchat-reducer.js
index 06e9a0e4d4..c42ed9f5ea 100644
--- a/packages/botonic-react/src/experimental/webchat/webchat-reducer.js
+++ b/packages/botonic-react/src/experimental/webchat/webchat-reducer.js
@@ -6,6 +6,7 @@ import {
TOGGLE_EMOJI_PICKER,
TOGGLE_PERSISTENT_MENU,
TOGGLE_WEBCHAT,
+ UPDATE_BOT_STATE,
UPDATE_DEV_SETTINGS,
UPDATE_HANDOFF,
UPDATE_JWT,
@@ -14,16 +15,16 @@ import {
UPDATE_SESSION,
UPDATE_THEME,
UPDATE_TYPING,
+ UPDATE_USER,
UPDATE_WEBVIEW,
} from './actions'
import { messagesReducer } from './messages-reducer'
+// eslint-disable-next-line complexity
export function webchatReducer(state, action) {
switch (action.type) {
case UPDATE_WEBVIEW:
return { ...state, ...action.payload }
- case UPDATE_SESSION:
- return { ...state, session: { ...action.payload } }
case UPDATE_TYPING:
return { ...state, typing: action.payload }
case UPDATE_THEME:
@@ -55,6 +56,12 @@ export function webchatReducer(state, action) {
return { ...state, currentAttachment: action.payload }
case UPDATE_JWT:
return { ...state, jwt: action.payload }
+ case UPDATE_USER:
+ return { ...state, user: action.payload }
+ case UPDATE_SESSION:
+ return { ...state, session: action.payload }
+ case UPDATE_BOT_STATE:
+ return { ...state, botState: action.payload }
default:
return messagesReducer(state, action)
}
diff --git a/packages/botonic-react/src/experimental/webchat/webchat.jsx b/packages/botonic-react/src/experimental/webchat/webchat.jsx
index 9694184206..881b965a31 100644
--- a/packages/botonic-react/src/experimental/webchat/webchat.jsx
+++ b/packages/botonic-react/src/experimental/webchat/webchat.jsx
@@ -44,12 +44,6 @@ import { scrollToBottom } from '../../util/dom'
import { isDev, resolveImage } from '../../util/environment'
import { ConditionalWrapper } from '../../util/react'
import { deserializeRegex, stringifyWithRegexs } from '../../util/regexs'
-import {
- _getThemeProperty,
- getServerErrorMessage,
- initSession,
- shouldKeepSessionOnReload,
-} from '../../util/webchat'
import { Attachment } from '../../webchat/components/attachment'
import {
EmojiPicker,
@@ -63,12 +57,6 @@ import { SendButton } from '../../webchat/components/send-button'
import { TypingIndicator } from '../../webchat/components/typing-indicator'
import { DeviceAdapter } from '../../webchat/devices/device-adapter'
import { StyledWebchatHeader } from '../../webchat/header'
-import {
- useComponentWillMount,
- usePrevious,
- useTyping,
- useWebchat,
-} from '../../webchat/hooks'
import { WebchatMessageList } from '../../webchat/message-list'
import { WebchatReplies } from '../../webchat/replies'
import { useStorageState } from '../../webchat/use-storage-state-hook'
@@ -76,6 +64,18 @@ import { WebviewContainer } from '../../webchat/webview'
import { Audio, Document, Image, Video } from '../components'
import { Text } from '../components/text'
import { msgToBotonic } from '../msg-to-botonic'
+import {
+ _getThemeProperty,
+ getServerErrorMessage,
+ initUser,
+ shouldKeepSessionOnReload,
+} from '../util/webchat'
+import {
+ useComponentWillMount,
+ usePrevious,
+ useTyping,
+ useWebchat,
+} from '../webchat/hooks'
export const getParsedAction = botonicAction => {
const splittedAction = botonicAction.split('create_case:')
if (splittedAction.length <= 1) return undefined
@@ -183,7 +183,6 @@ export const Webchat = forwardRef((props, ref) => {
updateLatestInput,
updateTyping,
updateWebview,
- updateSession,
updateLastRoutePath,
updateHandoff,
updateTheme,
@@ -200,14 +199,23 @@ export const Webchat = forwardRef((props, ref) => {
updateLastMessageDate,
setCurrentAttachment,
updateJwt,
+ updateUser,
+ updateSession,
+ updateBotState,
// eslint-disable-next-line react-hooks/rules-of-hooks
} = props.webchatHooks || useWebchat()
const firstUpdate = useRef(true)
- const isOnline = () => webchatState.online
+ const isOnline = () => webchatState.isWebchatOnline
const currentDateString = () => new Date().toISOString()
const theme = merge(webchatState.theme, props.theme)
- const { initialSession, initialDevSettings, onStateChange } = props
+ const {
+ initialUser,
+ initialSession,
+ initialBotState,
+ initialDevSettings,
+ onStateChange,
+ } = props
const getThemeProperty = _getThemeProperty(theme)
const storage = props.storage === undefined ? localStorage : props.storage
@@ -229,14 +237,13 @@ export const Webchat = forwardRef((props, ref) => {
JSON.parse(
stringifyWithRegexs({
messages: webchatState.messagesJSON,
- session: webchatState.session,
- botState: webchatState.botState,
- user: webchatState.user,
- lastRoutePath: webchatState.lastRoutePath,
devSettings: webchatState.devSettings,
lastMessageUpdate: webchatState.lastMessageUpdate,
themeUpdates: webchatState.themeUpdates,
jwt: webchatState.jwt,
+ user: webchatState.user,
+ session: webchatState.session,
+ botState: webchatState.botState,
})
)
)
@@ -263,16 +270,16 @@ export const Webchat = forwardRef((props, ref) => {
const sendUserInput = async input => {
input = {
- ...input,
ack: MessageEventAck.DRAFT,
from: MessageEventFrom.USER,
+ ...input,
}
props.onUserInput &&
props.onUserInput({
- user: webchatState.session.user,
+ user: webchatState.user,
input,
session: webchatState.session,
- lastRoutePath: webchatState.lastRoutePath,
+ botState: webchatState.botState,
})
}
@@ -306,16 +313,18 @@ export const Webchat = forwardRef((props, ref) => {
// Load initial state from storage
useEffect(() => {
- let {
+ const {
messages,
- session,
lastRoutePath,
devSettings,
lastMessageUpdate,
themeUpdates,
+ user,
+ session,
+ botState,
} = botonicState || {}
- session = initSession(session)
- updateSession(session)
+ updateUser({ ...initialUser, ...initUser(user) })
+
if (shouldKeepSessionOnReload({ initialDevSettings, devSettings })) {
if (messages) {
messages.forEach(m => {
@@ -328,12 +337,15 @@ export const Webchat = forwardRef((props, ref) => {
if (newComponent) addMessageComponent(newComponent)
})
}
- if (initialSession) updateSession(merge(initialSession, session))
- if (lastRoutePath) updateLastRoutePath(lastRoutePath)
+ if (initialSession) {
+ updateSession(merge(initialSession, session))
+ }
+ if (initialBotState) {
+ updateBotState({ ...initialBotState, ...botState })
+ }
} else {
- session.__retries = 0
- session.is_first_interaction = true
updateSession(merge(initialSession, session))
+ updateBotState({ ...initialBotState, ...botState })
}
if (devSettings) updateDevSettings(devSettings)
else if (initialDevSettings) updateDevSettings(initialDevSettings)
@@ -350,21 +362,26 @@ export const Webchat = forwardRef((props, ref) => {
}, [webchatState.isWebchatOpen])
useEffect(() => {
- if (onStateChange && typeof onStateChange === 'function') {
+ if (
+ onStateChange &&
+ typeof onStateChange === 'function' &&
+ webchatState.user.id
+ ) {
onStateChange({ ...webchatState, updateJwt })
}
saveWebchatState(webchatState)
}, [
webchatState.messagesJSON,
- webchatState.session,
- webchatState.lastRoutePath,
webchatState.devSettings,
webchatState.lastMessageUpdate,
webchatState.jwt,
+ webchatState.user,
+ webchatState.session,
+ webchatState.botState,
])
useAsyncEffect(async () => {
- if (!webchatState.online) {
+ if (!webchatState.isWebchatOnline) {
setError({
message: getServerErrorMessage(props.server),
})
@@ -373,7 +390,7 @@ export const Webchat = forwardRef((props, ref) => {
setError(undefined)
}
}
- }, [webchatState.online])
+ }, [webchatState.isWebchatOnline])
useTyping({ webchatState, updateTyping, updateMessage, host })
@@ -557,27 +574,28 @@ export const Webchat = forwardRef((props, ref) => {
https://stackoverflow.com/questions/37949981/call-child-method-from-parent
*/
- const updateSessionWithUser = userToUpdate =>
- updateSession(merge(webchatState.session, { user: userToUpdate }))
+ const mergeAndUpdateUser = userToUpdate =>
+ updateUser(merge(webchatState.user, userToUpdate))
useImperativeHandle(ref, () => ({
addBotResponse: ({ response, session, lastRoutePath }) => {
updateTyping(false)
if (Array.isArray(response)) response.map(r => addMessageComponent(r))
else if (response) addMessageComponent(response)
- if (session) {
- updateSession(merge(session, { user: webchatState.session.user }))
- const action = session._botonic_action || ''
- const handoff = action.startsWith('create_case')
- if (handoff && isDev) addMessageComponent()
- updateHandoff(handoff)
- }
- if (lastRoutePath) updateLastRoutePath(lastRoutePath)
updateLastMessageDate(currentDateString())
},
setTyping: typing => updateTyping(typing),
addUserMessage: message => sendInput(message),
- updateUser: updateSessionWithUser,
+ updateUser: mergeAndUpdateUser,
+ updateBotState: botState => {
+ // TODO: Review handoff logic for 1.0
+ // const action = botState.botonicAction || ''
+ // // const isHandoff = action.startsWith('create_case')
+ if (botState.isHandoff && isDev) addMessageComponent()
+ updateBotState(botState)
+ // updateHandoff(botState.isHandoff)
+ },
+ updateSession: updateSession,
openWebchat: () => toggleWebchat(true),
closeWebchat: () => toggleWebchat(false),
toggleWebchat: () => toggleWebchat(!webchatState.isWebchatOpen),
@@ -610,22 +628,26 @@ export const Webchat = forwardRef((props, ref) => {
}))
const resolveCase = () => {
- updateHandoff(false)
- updateSession({ ...webchatState.session, _botonic_action: null })
+ // updateHandoff(false)
+ updateBotState({
+ ...webchatState.botState,
+ isHandoff: false,
+ botonicAction: null,
+ })
}
- const prevSession = usePrevious(webchatState.session)
+ const previousBotState = usePrevious(webchatState.botState)
useEffect(() => {
// Resume conversation after handoff
if (
- prevSession &&
- prevSession._botonic_action &&
- !webchatState.session._botonic_action
+ previousBotState &&
+ previousBotState.botonicAction &&
+ !webchatState.botState.botonicAction
) {
- const action = getParsedAction(prevSession._botonic_action)
+ const action = getParsedAction(previousBotState.botonicAction)
if (action && action.on_finish) sendPayload(action.on_finish)
}
- }, [webchatState.session._botonic_action])
+ }, [webchatState.botState.botonicAction])
const sendText = async (text, payload) => {
if (!text) return
@@ -665,8 +687,8 @@ export const Webchat = forwardRef((props, ref) => {
}
const webviewRequestContext = {
- getString: stringId => props.getString(stringId, webchatState.session),
- setLocale: locale => props.getString(locale, webchatState.session),
+ getString: stringId => props.getString(stringId, webchatState.botState),
+ setLocale: locale => props.getString(locale, webchatState.botState),
session: webchatState.session || {},
params: webchatState.webviewParams || {},
closeWebview: closeWebview,
@@ -926,7 +948,7 @@ export const Webchat = forwardRef((props, ref) => {
updateMessage,
updateReplies,
updateLatestInput,
- updateUser: updateSessionWithUser,
+ updateUser: mergeAndUpdateUser,
updateWebchatDevSettings: updateWebchatDevSettings,
}}
>