diff --git a/.changeset/cyan-shoes-fly.md b/.changeset/cyan-shoes-fly.md new file mode 100644 index 000000000000..e89b64a01a31 --- /dev/null +++ b/.changeset/cyan-shoes-fly.md @@ -0,0 +1,6 @@ +--- +"@rocket.chat/meteor": minor +"@rocket.chat/livechat": minor +--- + +Added Livechat setting `Hide system messages` & API method `setHiddenSystemMessages`, to customize system message visibility within the widget. diff --git a/apps/meteor/app/livechat/server/api/lib/livechat.ts b/apps/meteor/app/livechat/server/api/lib/livechat.ts index 24f5f8cc7c36..0f7da0b7c9e9 100644 --- a/apps/meteor/app/livechat/server/api/lib/livechat.ts +++ b/apps/meteor/app/livechat/server/api/lib/livechat.ts @@ -170,6 +170,7 @@ export async function settings({ businessUnit = '' }: { businessUnit?: string } limitTextLength: initSettings.Livechat_enable_message_character_limit && (initSettings.Livechat_message_character_limit || initSettings.Message_MaxAllowedSize), + hiddenSystemMessages: initSettings.Livechat_hide_system_messages, }, theme: { title: initSettings.Livechat_title, diff --git a/apps/meteor/app/livechat/server/lib/LivechatTyped.ts b/apps/meteor/app/livechat/server/lib/LivechatTyped.ts index d9e1fe84d854..776990beaa21 100644 --- a/apps/meteor/app/livechat/server/lib/LivechatTyped.ts +++ b/apps/meteor/app/livechat/server/lib/LivechatTyped.ts @@ -1126,6 +1126,7 @@ class LivechatClass { 'Livechat_show_agent_info', 'Livechat_clear_local_storage_when_chat_ended', 'Livechat_history_monitor_type', + 'Livechat_hide_system_messages', ] as const; type SettingTypes = (typeof validSettings)[number] | 'Livechat_Show_Connecting'; diff --git a/apps/meteor/ee/app/livechat-enterprise/server/settings.ts b/apps/meteor/ee/app/livechat-enterprise/server/settings.ts index 3a99535ca2ed..c2f66bc79355 100644 --- a/apps/meteor/ee/app/livechat-enterprise/server/settings.ts +++ b/apps/meteor/ee/app/livechat-enterprise/server/settings.ts @@ -263,6 +263,23 @@ export const createSettings = async (): Promise => { i18nLabel: 'Omnichannel_transcript_pdf', }); + await settingsRegistry.add('Livechat_hide_system_messages', ['uj', 'ul', 'livechat-close'], { + type: 'multiSelect', + group: 'Omnichannel', + section: 'Livechat', + enterprise: true, + modules: ['livechat-enterprise'], + invalidValue: ['uj', 'ul', 'livechat-close'], + public: true, + values: [ + { key: 'uj', i18nLabel: 'Message_HideType_uj' }, + { key: 'ul', i18nLabel: 'Message_HideType_ul' }, + { key: 'livechat-close', i18nLabel: 'Message_HideType_livechat_closed' }, + { key: 'livechat-started', i18nLabel: 'Message_HideType_livechat_started' }, + { key: 'livechat_transfer_history', i18nLabel: 'Message_HideType_livechat_transfer_history' }, + ], + }); + await Settings.addOptionValueById('Livechat_Routing_Method', { key: 'Load_Balancing', i18nLabel: 'Load_Balancing', diff --git a/packages/i18n/src/locales/en.i18n.json b/packages/i18n/src/locales/en.i18n.json index 2dfcdaf22f05..849dcab49c5c 100644 --- a/packages/i18n/src/locales/en.i18n.json +++ b/packages/i18n/src/locales/en.i18n.json @@ -3175,6 +3175,7 @@ "Livechat_offline": "Omnichannel offline", "Livechat_offline_message_sent": "Livechat offline message sent", "Livechat_OfflineMessageToChannel_enabled": "Send Livechat offline messages to a channel", + "Livechat_hide_system_messages": "Hide system messages", "Omnichannel_chat_closed_due_to_inactivity": "The chat was automatically closed because we haven't received any reply from {{guest}} in {{timeout}} seconds", "Omnichannel_actions": "Omnichannel actions", "Omnichannel_on_hold_chat_resumed": "On Hold Chat Resumed: {{comment}}", @@ -3532,6 +3533,9 @@ "Message_HideType_changed_announcement": "Hide \"Room announcement changed to\" messages", "Message_HideType_ut": "Hide \"User Joined Conversation\" messages", "Message_HideType_wm": "Hide \"Welcome\" messages", + "Message_HideType_livechat_closed": "Hide \"Conversation finished\" messages", + "Message_HideType_livechat_started": "Hide \"Conversation started\" messages", + "Message_HideType_livechat_transfer_history": "Hide \"Conversation transfered\" messages", "Message_Id": "Message Id", "Message_Ignored": "This message was ignored", "message-impersonate": "Impersonate Other Users", diff --git a/packages/i18n/src/locales/pt-BR.i18n.json b/packages/i18n/src/locales/pt-BR.i18n.json index f8cc3513463f..76fc3db44e7e 100644 --- a/packages/i18n/src/locales/pt-BR.i18n.json +++ b/packages/i18n/src/locales/pt-BR.i18n.json @@ -2684,6 +2684,7 @@ "Livechat_offline": "Omnichannel offline", "Livechat_offline_message_sent": "Mensagem offline do livechat enviada", "Livechat_OfflineMessageToChannel_enabled": "Envie mensagens offline do livechat para um canal", + "Livechat_hide_system_messages": "Ocultar mensagens do sistema", "Omnichannel_on_hold_chat_resumed": "Conversa em espera retomada: {{comment}}", "Omnichannel_on_hold_chat_automatically": "A conversa foi automaticamente retomada de em espera após receber uma nova mensagem de {{guest}}", "Omnichannel_on_hold_chat_resumed_manually": "A conversa foi manualmente retomada de em espera por {{user}}", @@ -2961,6 +2962,9 @@ "Message_HideType_user_removed_room_from_team": "Ocultar mensagens de \"Usuário removeu sala da equipe\"", "Message_HideType_ut": "Ocultar mensagens de \"Usuário entrou na conversa\"", "Message_HideType_wm": "Ocultar mensagens de \"Bem-vindo\"", + "Message_HideType_livechat_closed": "Ocultar mensagens de \"Conversa encerrada\"", + "Message_HideType_livechat_started": "Ocultar mensagens de \"Conversa iniciada\"", + "Message_HideType_livechat_transfer_history": "Ocultar mensagens de \"Histórico de transferência\"", "Message_Id": "ID da mensagem", "Message_Ignored": "Esta mensagem foi ignorada", "message-impersonate": "Personificar outros usuários", diff --git a/packages/livechat/src/helpers/canRenderMessage.ts b/packages/livechat/src/helpers/canRenderMessage.ts index b7dd462498e6..726ec689631c 100644 --- a/packages/livechat/src/helpers/canRenderMessage.ts +++ b/packages/livechat/src/helpers/canRenderMessage.ts @@ -1,27 +1,40 @@ import { MESSAGE_TYPE_COMMAND, - MESSAGE_TYPE_LIVECHAT_CLOSED, MESSAGE_TYPE_LIVECHAT_NAVIGATION_HISTORY, MESSAGE_TYPE_PRIORITY_CHANGE, + MESSAGE_TYPE_ROOM_NAME_CHANGED, MESSAGE_TYPE_SLA_CHANGE, MESSAGE_TYPE_USER_ADDED, - MESSAGE_TYPE_USER_JOINED, - MESSAGE_TYPE_USER_LEFT, + MESSAGE_TYPE_USER_REMOVED, + MESSAGE_TYPE_WELCOME, MESSAGE_VIDEO_CALL, MESSAGE_WEBRTC_CALL, } from '../components/Messages/constants'; +import store from '../store'; const msgTypesNotRendered = [ + MESSAGE_TYPE_WELCOME, + MESSAGE_TYPE_ROOM_NAME_CHANGED, + MESSAGE_TYPE_USER_ADDED, + MESSAGE_TYPE_USER_REMOVED, MESSAGE_VIDEO_CALL, MESSAGE_WEBRTC_CALL, MESSAGE_TYPE_LIVECHAT_NAVIGATION_HISTORY, - MESSAGE_TYPE_USER_ADDED, MESSAGE_TYPE_COMMAND, - MESSAGE_TYPE_USER_JOINED, - MESSAGE_TYPE_USER_LEFT, - MESSAGE_TYPE_LIVECHAT_CLOSED, MESSAGE_TYPE_PRIORITY_CHANGE, MESSAGE_TYPE_SLA_CHANGE, ]; -export const canRenderMessage = ({ t }: { t: string }) => !msgTypesNotRendered.includes(t); +export const getHiddenSystemMessages = () => { + const { config, iframe } = store.state; + const configHiddenSystemMessages = config.settings.hiddenSystemMessages || []; + const localHiddenSystemMessages = iframe.hiddenSystemMessages || []; + + return [...configHiddenSystemMessages, ...localHiddenSystemMessages] as string[]; +}; + +export const canRenderMessage = ({ t }: { t: string }) => { + const hiddenSystemMessages = getHiddenSystemMessages(); + + return !msgTypesNotRendered.includes(t) && !hiddenSystemMessages.includes(t); +}; diff --git a/packages/livechat/src/lib/hooks.ts b/packages/livechat/src/lib/hooks.ts index 300c7804e6d7..a3d456fec3bf 100644 --- a/packages/livechat/src/lib/hooks.ts +++ b/packages/livechat/src/lib/hooks.ts @@ -244,10 +244,16 @@ const api = { setParentUrl: (parentUrl: StoreState['parentUrl']) => { store.setState({ parentUrl }); }, + setGuestMetadata(metadata: StoreState['iframe']['guestMetadata']) { const { iframe } = store.state; store.setState({ iframe: { ...iframe, guestMetadata: metadata } }); }, + + setHiddenSystemMessages: (hiddenSystemMessages: StoreState['iframe']['hiddenSystemMessages']) => { + const { iframe } = store.state; + store.setState({ iframe: { ...iframe, hiddenSystemMessages } }); + }, }; function onNewMessageHandler(event: MessageEvent>) { diff --git a/packages/livechat/src/store/index.tsx b/packages/livechat/src/store/index.tsx index 4725a435aad5..d35843e07c8d 100644 --- a/packages/livechat/src/store/index.tsx +++ b/packages/livechat/src/store/index.tsx @@ -10,6 +10,13 @@ import { parentCall } from '../lib/parentCall'; import { createToken } from '../lib/random'; import Store from './Store'; +export type LivechatHiddenSytemMessageType = + | 'uj' // User joined + | 'ul' // User left + | 'livechat-close' // Chat closed + | 'livechat-started' // Chat started + | 'livechat_transfer_history'; // Chat transfered + export type StoreState = { token: string; typing: string[]; @@ -45,6 +52,7 @@ export type StoreState = { showConnecting?: any; limitTextLength?: any; displayOfflineForm?: boolean; + hiddenSystemMessages?: LivechatHiddenSytemMessageType[]; }; online?: boolean; departments: Department[]; @@ -73,6 +81,7 @@ export type StoreState = { department?: string; language?: string; defaultDepartment?: string; + hiddenSystemMessages?: LivechatHiddenSytemMessageType[]; }; gdpr: { accepted: boolean; diff --git a/packages/livechat/src/widget.ts b/packages/livechat/src/widget.ts index 2f1e8f4ea318..b845602acc34 100644 --- a/packages/livechat/src/widget.ts +++ b/packages/livechat/src/widget.ts @@ -42,6 +42,7 @@ type InitializeParams = { agent: StoreState['defaultAgent']; parentUrl: string; setGuestMetadata: StoreState['iframe']['guestMetadata']; + hiddenSystemMessages: StoreState['iframe']['hiddenSystemMessages']; }; const WIDGET_OPEN_WIDTH = 365; @@ -75,6 +76,8 @@ export const VALID_CALLBACKS = [ 'no-agent-online', ]; +const VALID_SYSTEM_MESSAGES = ['uj', 'ul', 'livechat-close', 'livechat-started', 'livechat_transfer_history']; + const callbacks = mitt(); function registerCallback(eventName: string, fn: () => unknown) { @@ -355,6 +358,23 @@ function setGuestMetadata(metadata: StoreState['iframe']['guestMetadata']) { callHook('setGuestMetadata', metadata); } +function setHiddenSystemMessages(hidden: StoreState['iframe']['hiddenSystemMessages']) { + if (!Array.isArray(hidden)) { + throw new Error('Error: Invalid parameters. Value must be an array of strings'); + } + + const hiddenSystemMessages = hidden.filter((h) => { + if (VALID_SYSTEM_MESSAGES.includes(h)) { + return true; + } + + console.warn(`Error: Invalid system message "${h}"`); + return false; + }); + + callHook('setHiddenSystemMessages', hiddenSystemMessages); +} + function initialize(initParams: Partial) { for (const initKey in initParams) { if (!initParams.hasOwnProperty(initKey)) { @@ -407,6 +427,9 @@ function initialize(initParams: Partial) { case 'setGuestMetadata': setGuestMetadata(params as InitializeParams['setGuestMetadata']); continue; + case 'hiddenSystemMessages': + setHiddenSystemMessages(params as InitializeParams['hiddenSystemMessages']); + continue; default: continue; } @@ -506,6 +529,7 @@ const livechatWidgetAPI = { setParentUrl, setGuestMetadata, clearAllCallbacks, + setHiddenSystemMessages, // callbacks onChatMaximized(fn: () => void) {