diff --git a/api/src/extensions/channels/web/base-web-channel.ts b/api/src/extensions/channels/web/base-web-channel.ts index 7dd143a8..33244db3 100644 --- a/api/src/extensions/channels/web/base-web-channel.ts +++ b/api/src/extensions/channels/web/base-web-channel.ts @@ -126,7 +126,12 @@ export default abstract class BaseWebChannelHandler< try { const menu = await this.menuService.getTree(); - client.emit('settings', { menu, ...settings }); + const hasSession = !!client.data.session?.web?.profile; + client.emit('settings', { + menu, + hasSession, + ...settings, + }); } catch (err) { this.logger.warn('Unable to retrieve menu ', err); client.emit('settings', settings); diff --git a/widget/src/components/UserSubscription.tsx b/widget/src/components/UserSubscription.tsx index c1066d7c..16dae7fc 100644 --- a/widget/src/components/UserSubscription.tsx +++ b/widget/src/components/UserSubscription.tsx @@ -43,20 +43,46 @@ const UserSubscription: React.FC = () => { participants, setParticipants, setSuggestions, + hasSession, } = useChat(); const [firstName, setFirstName] = useState(""); const [lastName, setLastName] = useState(""); const isInitialized = useRef(false); + const getLocalStorageProfile = (): ISubscriber | null => { + const profile = localStorage.getItem("profile"); + + if (profile) { + return JSON.parse(profile); + } + + return null; + }; + const getBody = async (first_name: string = "", last_name: string = "") => { + const { body } = await socket.get<{ + messages: TMessage[]; + profile: ISubscriber; + }>( + `/webhook/${config.channel}/?first_name=${first_name}&last_name=${last_name}`, + ); + + return body; + }; const handleSubmit = useCallback( - async (event?: React.FormEvent) => { + async ({ + event, + first_name = "", + last_name = "", + }: { + event?: React.FormEvent; + first_name?: string; + last_name?: string; + }) => { event?.preventDefault(); try { setConnectionState(2); - const { body } = await socket.get<{ - messages: TMessage[]; - profile: ISubscriber; - }>( - `/webhook/${config.channel}/?first_name=${firstName}&last_name=${lastName}`, + const body = await getBody( + first_name || firstName, + last_name || lastName, ); const { messages, profile } = body; const quickReplies = getQuickReplies(body.messages.at(-1)); @@ -127,21 +153,22 @@ const UserSubscription: React.FC = () => { // User already subscribed ? (example : refreshed the page) if (!isInitialized.current) { isInitialized.current = true; - const profile = localStorage.getItem("profile"); + const localStorageProfile = getLocalStorageProfile(); - if (profile) { - const parsedProfile = JSON.parse(profile); - - setFirstName(parsedProfile.first_name); - setLastName(parsedProfile.last_name); - handleSubmit(); - } + if (localStorageProfile || hasSession) + handleSubmit({ + first_name: localStorageProfile?.first_name, + last_name: localStorageProfile?.last_name, + }); } - }, [handleSubmit, setScreen]); + }, [handleSubmit, hasSession, setScreen]); return (
-
+ handleSubmit({ event })} + >
{settings.greetingMessage}
diff --git a/widget/src/providers/ChatProvider.tsx b/widget/src/providers/ChatProvider.tsx index 358736b7..d52c8420 100644 --- a/widget/src/providers/ChatProvider.tsx +++ b/widget/src/providers/ChatProvider.tsx @@ -15,6 +15,7 @@ import React, { useEffect, useState, } from "react"; +import { Packet, PacketType } from "socket.io-parser"; import { useSubscribeBroadcastChannel } from "../hooks/useSubscribeBroadcastChannel"; import { StdEventType } from "../types/chat-io-messages.types"; @@ -157,6 +158,7 @@ interface ChatContextType { * @param lastName */ handleSubscription: (firstName?: string, lastName?: string) => void; + hasSession: boolean; } const defaultCtx: ChatContextType = { @@ -193,6 +195,7 @@ const defaultCtx: ChatContextType = { setFile: () => {}, send: () => {}, handleSubscription: () => {}, + hasSession: false, }; const ChatContext = createContext(defaultCtx); const ChatProvider: React.FC<{ @@ -230,6 +233,7 @@ const ChatProvider: React.FC<{ const [payload, setPayload] = useState(defaultCtx.payload); const [file, setFile] = useState(defaultCtx.file); const [webviewUrl, setWebviewUrl] = useState(defaultCtx.webviewUrl); + const [hasSession, setHasSession] = useState(false); const updateConnectionState = (state: ConnectionState) => { setConnectionState(state); state === ConnectionState.wantToConnect && wantToConnect && wantToConnect(); @@ -415,13 +419,20 @@ const ChatProvider: React.FC<{ const endConnection = () => { setConnectionState(0); }; + const resetProfile = ({ type, data }: Packet) => { + if (type === PacketType.EVENT && data[0] === "settings") { + setHasSession(!!data[1]?.hasSession); + } + }; + socketCtx.socket.io.on("packet", resetProfile); socketCtx.socket.io.on("reconnect", reSubscribe); socketCtx.socket.io.on("close", endConnection); socketCtx.socket.io.on("reconnect_error", endConnection); socketCtx.socket.io.on("reconnect_failed", endConnection); return () => { + socketCtx.socket.io.off("packet", resetProfile); socketCtx.socket.io.off("reconnect", reSubscribe); socketCtx.socket.io.off("close", endConnection); socketCtx.socket.io.off("reconnect_error", endConnection); @@ -471,6 +482,7 @@ const ChatProvider: React.FC<{ message, setMessage, handleSubscription, + hasSession, }; return (