diff --git a/packages/odie-client/src/components/message/messages-cluster/messages-cluster.tsx b/packages/odie-client/src/components/message/messages-cluster/messages-cluster.tsx index 90d71e8f592c..2ea33b638940 100644 --- a/packages/odie-client/src/components/message/messages-cluster/messages-cluster.tsx +++ b/packages/odie-client/src/components/message/messages-cluster/messages-cluster.tsx @@ -7,7 +7,7 @@ import { isCSATMessage } from '../../../utils'; import { hasFeedbackForm, isAttachment, - isTransitionToSupportMessage, + isZendeskChatStartedMessage, isZendeskIntroMessage, } from '../../../utils/csat'; import ChatWithSupportLabel from '../../chat-with-support'; @@ -112,7 +112,7 @@ export function MessagesClusterizer( { messages }: { messages: Message[] } ) { const { currentUser } = useOdieAssistantContext(); return groups.map( ( group ) => { - const startingHumanSupport = group.messages.some( isTransitionToSupportMessage ); + const startingHumanSupport = group.messages.some( isZendeskChatStartedMessage ); const endingHumanSupport = group.messages.some( isCSATMessage ); const messageHeader = () => { diff --git a/packages/odie-client/src/components/message/messages-cluster/style.scss b/packages/odie-client/src/components/message/messages-cluster/style.scss index 93395cb87a4c..289413a33701 100644 --- a/packages/odie-client/src/components/message/messages-cluster/style.scss +++ b/packages/odie-client/src/components/message/messages-cluster/style.scss @@ -40,6 +40,10 @@ .odie-chatbox-message { margin-bottom: 16px; } + + .odie-chatbox-message-meta { + margin-bottom: 0; + } } &.role-business { diff --git a/packages/odie-client/src/components/message/messages-container.tsx b/packages/odie-client/src/components/message/messages-container.tsx index c09d84106f39..0c07d79b2ade 100644 --- a/packages/odie-client/src/components/message/messages-container.tsx +++ b/packages/odie-client/src/components/message/messages-container.tsx @@ -1,4 +1,6 @@ +import { isTestModeEnvironment } from '@automattic/zendesk-client'; import { Spinner } from '@wordpress/components'; +import { __ } from '@wordpress/i18n'; import clx from 'classnames'; import { useEffect, useRef, useState } from 'react'; import { NavigationType, useNavigate, useNavigationType, useSearchParams } from 'react-router-dom'; @@ -27,6 +29,7 @@ interface ChatMessagesProps { export const MessagesContainer = ( { currentUser }: ChatMessagesProps ) => { const { chat, isChatLoaded, isUserEligibleForPaidSupport, forceEmailSupport } = useOdieAssistantContext(); + const isTestMode = isTestModeEnvironment(); const createZendeskConversation = useCreateZendeskConversation(); const [ searchParams, setSearchParams ] = useSearchParams(); const navigate = useNavigate(); @@ -143,13 +146,14 @@ export const MessagesContainer = ( { currentUser }: ChatMessagesProps ) => { { chat.messages?.length > 0 && } - { chat.provider === 'odie' && chat.status === 'sending' && ( -
div?.scrollIntoView( { behavior: 'smooth', block: 'end' } ) } - > - -
+ { chat.provider === 'odie' && chat.status === 'sending' && } + { chat.provider === 'odie' && chat.status === 'transfer' && ( + ) } { chat.provider.startsWith( 'zendesk' ) && ( diff --git a/packages/odie-client/src/components/message/style.scss b/packages/odie-client/src/components/message/style.scss index 42ad4a9fde12..446a48e0c87d 100644 --- a/packages/odie-client/src/components/message/style.scss +++ b/packages/odie-client/src/components/message/style.scss @@ -54,6 +54,10 @@ $blueberry-color: #3858e9; display: none; } } + + .odie-chatbox-thinking-placeholder { + align-items: center; + } } .odie-chatbox-message { diff --git a/packages/odie-client/src/components/message/thinking-placeholder.tsx b/packages/odie-client/src/components/message/thinking-placeholder.tsx index 5c454a4c0440..364ad19d5ff2 100644 --- a/packages/odie-client/src/components/message/thinking-placeholder.tsx +++ b/packages/odie-client/src/components/message/thinking-placeholder.tsx @@ -1,9 +1,14 @@ import { ThinkingMessage } from '@automattic/agenttic-ui'; -export const ThinkingPlaceholder = () => { +export const ThinkingPlaceholder = ( { content }: { content?: string } ) => { return ( -
- +
div?.scrollIntoView( { behavior: 'smooth', block: 'end' } ) } + > +
+ +
); }; diff --git a/packages/odie-client/src/components/message/user-message.tsx b/packages/odie-client/src/components/message/user-message.tsx index 826eb8ac76f3..d7db99132e53 100644 --- a/packages/odie-client/src/components/message/user-message.tsx +++ b/packages/odie-client/src/components/message/user-message.tsx @@ -87,25 +87,31 @@ export const UserMessage = ( { const showGetSupport = isLastBotMessage && ( isRequestingHumanSupport || isErrorMessage ); const showActionButtons = ! isRequestingHumanSupport && ! isErrorMessage; - const shouldOverrideWithForwardMessage = isRequestingHumanSupport && chat.provider !== 'zendesk'; + const messageContent = () => { + if ( ! isRequestingHumanSupport ) { + return message.content; + } - const messageContent = shouldOverrideWithForwardMessage - ? getDisplayMessage( - !! hasRecentOpenConversation, - isUserEligibleForPaidSupport, - canConnectToZendesk, - forceEmailSupport, - isChatRestricted, - message?.context?.flags?.is_error_message, - isChatLoaded - ) - : message.content; + if ( chat.provider === 'zendesk' ) { + return ''; + } + + return getDisplayMessage( + !! hasRecentOpenConversation, + isUserEligibleForPaidSupport, + canConnectToZendesk, + forceEmailSupport, + isChatRestricted, + message?.context?.flags?.is_error_message, + isChatLoaded + ); + }; return ( <>
) => , } } diff --git a/packages/odie-client/src/constants.tsx b/packages/odie-client/src/constants.tsx index d15bd67163d2..7cb5108ffeb4 100644 --- a/packages/odie-client/src/constants.tsx +++ b/packages/odie-client/src/constants.tsx @@ -54,7 +54,7 @@ export function getFlowFromBotSlug( botSlug?: OdieAllBotSlugs ): string { return 'wpcom'; } -export const getOdieTransferMessage = ( botSlug?: OdieAllBotSlugs ): Message[] => { +export const getOdieTransferMessages = ( botSlug?: OdieAllBotSlugs ): Message[] => { const isTestMode = isTestModeEnvironment(); const flow = getFlowFromBotSlug( botSlug ); @@ -73,7 +73,6 @@ export const getOdieTransferMessage = ( botSlug?: OdieAllBotSlugs ): Message[] = context: { flags: { hide_disclaimer_content: true, - show_contact_support_msg: true, show_ai_avatar: false, }, site_id: null, @@ -91,7 +90,6 @@ export const getOdieTransferMessage = ( botSlug?: OdieAllBotSlugs ): Message[] = context: { flags: { hide_disclaimer_content: true, - show_contact_support_msg: false, show_ai_avatar: false, }, site_id: null, @@ -111,7 +109,6 @@ export const getOdieTransferMessage = ( botSlug?: OdieAllBotSlugs ): Message[] = context: { flags: { hide_disclaimer_content: true, - show_contact_support_msg: true, show_ai_avatar: false, }, site_id: null, @@ -132,7 +129,6 @@ export const getOdieTransferMessage = ( botSlug?: OdieAllBotSlugs ): Message[] = context: { flags: { hide_disclaimer_content: true, - show_contact_support_msg: true, show_ai_avatar: false, }, site_id: null, @@ -148,7 +144,6 @@ export const getOdieTransferMessage = ( botSlug?: OdieAllBotSlugs ): Message[] = context: { flags: { hide_disclaimer_content: true, - show_contact_support_msg: true, show_ai_avatar: false, }, site_id: null, @@ -157,22 +152,6 @@ export const getOdieTransferMessage = ( botSlug?: OdieAllBotSlugs ): Message[] = ]; }; -export const getOdieOnErrorTransferMessage = (): Message[] => [ - { - content: getOdieErrorMessage(), - role: 'bot', - type: 'message', - context: { - flags: { - hide_disclaimer_content: true, - show_contact_support_msg: false, - show_ai_avatar: true, - }, - site_id: null, - }, - }, -]; - export const getOdieThirdPartyMessageContent = (): string => `${ __( 'I’m happy to connect you to a human! However, it looks like 3rd party cookies are disabled in your browser. Please turn them on for our live chat to work properly. [Use our guide](https://wordpress.com/support/third-party-cookies/)', @@ -203,7 +182,6 @@ export const getOdieEmailFallbackMessage = (): Message => ( { type: 'message', context: { flags: { - show_contact_support_msg: false, forward_to_human_support: true, }, question_tags: { @@ -330,6 +308,20 @@ export const getOdieZendeskConnectionErrorMessage = (): Message => { }; }; +export const getZendeskChatStartedMetaMessage = (): Message => ( { + content: null, + role: 'bot', + type: 'meta', + internal_message_id: 'zendesk-chat-started', + context: { + site_id: null, + flags: { + hide_disclaimer_content: true, + show_ai_avatar: false, + }, + }, +} ); + export const ODIE_THUMBS_DOWN_RATING_VALUE = 0; export const ODIE_THUMBS_UP_RATING_VALUE = 1; diff --git a/packages/odie-client/src/data/use-send-odie-message.ts b/packages/odie-client/src/data/use-send-odie-message.ts index b11858032678..91dc1e5f734c 100644 --- a/packages/odie-client/src/data/use-send-odie-message.ts +++ b/packages/odie-client/src/data/use-send-odie-message.ts @@ -48,7 +48,6 @@ const getErrorMessageForSiteIdAndInternalMessageId = ( flags: { forward_to_human_support: true, hide_disclaimer_content: false, - show_contact_support_msg: true, show_ai_avatar: true, is_error_message: true, }, diff --git a/packages/odie-client/src/hooks/use-create-zendesk-conversation.ts b/packages/odie-client/src/hooks/use-create-zendesk-conversation.ts index 169bc4f38d4d..ff34f03762fb 100644 --- a/packages/odie-client/src/hooks/use-create-zendesk-conversation.ts +++ b/packages/odie-client/src/hooks/use-create-zendesk-conversation.ts @@ -2,14 +2,13 @@ import { useUpdateZendeskUserFields, type ZendeskConversation } from '@automatti import { useLocation, useNavigate } from 'react-router-dom'; import Smooch from 'smooch'; import { - getOdieOnErrorTransferMessage, - getOdieTransferMessage, getErrorTryAgainLaterMessage, + getOdieTransferMessages, + getZendeskChatStartedMetaMessage, } from '../constants'; import { useOdieAssistantContext } from '../context'; import { useManageSupportInteraction } from '../data'; import { useCurrentSupportInteraction } from '../data/use-current-support-interaction'; -import type { OdieAllBotSlugs } from '../types'; export const useCreateZendeskConversation = () => { const { @@ -81,10 +80,9 @@ export const useCreateZendeskConversation = () => { active_interaction_id: activeInteractionId || null, is_chat_loaded: isChatLoaded, } ); - const errorMessageObj = getErrorTryAgainLaterMessage(); setChat( { - messages: [ ...previousMessages, errorMessageObj ], + messages: [ ...previousMessages, getErrorTryAgainLaterMessage() ], status: 'loaded', provider: previousProvider, conversationId: previousConversationId, @@ -94,14 +92,8 @@ export const useCreateZendeskConversation = () => { } ); }; - // Get transfer messages to identify and remove them on error - const transferMessages = isFromError - ? getOdieOnErrorTransferMessage() - : getOdieTransferMessage( currentSupportInteraction?.bot_slug as OdieAllBotSlugs ); - setChat( ( prevChat ) => ( { ...prevChat, - messages: [ ...prevChat.messages, ...transferMessages ], status: 'transfer', } ) ); @@ -186,6 +178,11 @@ export const useCreateZendeskConversation = () => { setChat( ( prevChat ) => ( { ...prevChat, conversationId: conversationId, + messages: [ + ...prevChat.messages, + ...getOdieTransferMessages( currentSupportInteraction?.bot_slug ), + getZendeskChatStartedMetaMessage(), + ], provider: 'zendesk', status: 'loaded', } ) ); diff --git a/packages/odie-client/src/hooks/use-get-combined-chat.ts b/packages/odie-client/src/hooks/use-get-combined-chat.ts index 34bca40d4713..c66488f9b7a2 100644 --- a/packages/odie-client/src/hooks/use-get-combined-chat.ts +++ b/packages/odie-client/src/hooks/use-get-combined-chat.ts @@ -5,7 +5,7 @@ import { useIsMutating } from '@tanstack/react-query'; import { useSelect } from '@wordpress/data'; import { useState, useEffect, useRef } from '@wordpress/element'; import { getMessageUniqueIdentifier } from '../components/message/utils/get-message-unique-identifier'; -import { getOdieTransferMessage } from '../constants'; +import { getOdieTransferMessages, getZendeskChatStartedMetaMessage } from '../constants'; import { emptyChat } from '../context'; import { useGetZendeskConversation, useManageSupportInteraction, useOdieChat } from '../data'; import { useCurrentSupportInteraction } from '../data/use-current-support-interaction'; @@ -14,7 +14,7 @@ import { getOdieIdFromInteraction, getIsRequestingHumanSupport, } from '../utils'; -import type { Chat, Message, OdieAllBotSlugs } from '../types'; +import type { Chat, Message } from '../types'; function isEqual( message1: Message, message2: Message ) { const message1Id = getMessageUniqueIdentifier( message1 ); @@ -142,9 +142,8 @@ export const useGetCombinedChat = ( conversationId: conversation.id, messages: [ ...( odieChat ? filteredOdieMessages : [] ), - ...getOdieTransferMessage( - currentSupportInteraction?.bot_slug as OdieAllBotSlugs - ), + ...getOdieTransferMessages( currentSupportInteraction?.bot_slug ), + getZendeskChatStartedMetaMessage(), ...( deduplicateZDMessages( [ // During connection recovery, the user queued messages can be deleted. This ensure they remain. And `deduplicateZDMessages` takes of duplication. ...( isSameConversation diff --git a/packages/odie-client/src/types.ts b/packages/odie-client/src/types.ts index 68c92650a025..3c2f46407381 100644 --- a/packages/odie-client/src/types.ts +++ b/packages/odie-client/src/types.ts @@ -114,7 +114,6 @@ export type Context = { failed_zendesk_connection?: boolean; forward_to_human_support?: boolean; hide_disclaimer_content?: boolean; - show_contact_support_msg?: boolean; show_ai_avatar?: boolean; is_error_message?: boolean; }; diff --git a/packages/odie-client/src/utils/csat.ts b/packages/odie-client/src/utils/csat.ts index a33229606369..55d80269657b 100644 --- a/packages/odie-client/src/utils/csat.ts +++ b/packages/odie-client/src/utils/csat.ts @@ -12,8 +12,8 @@ export const isAttachment = ( message: Message ) => export const isZendeskIntroMessage = ( message: Message | ZendeskMessage ) => 'source' in message && message.source?.type === 'zd:answerBot'; -export const isTransitionToSupportMessage = ( message: Message ) => - !! message?.context?.flags?.show_contact_support_msg; +export const isZendeskChatStartedMessage = ( message: Message ) => + message?.internal_message_id === 'zendesk-chat-started'; export const hasCSATMessage = ( chat: Chat ) => { return chat?.messages.some( isCSATMessage );