diff --git a/apps/backoffice-v2/src/common/env/schema.ts b/apps/backoffice-v2/src/common/env/schema.ts index ab346db9aa..5be4b76602 100644 --- a/apps/backoffice-v2/src/common/env/schema.ts +++ b/apps/backoffice-v2/src/common/env/schema.ts @@ -39,4 +39,5 @@ export const EnvSchema = z.object({ return new RegExp(value); }, z.custom(value => value instanceof RegExp).optional()), VITE_SAOLA_API_KEY: z.string().optional(), + VITE_BOTPRESS_CLIENT_ID: z.string().default('8f29c89d-ec0e-494d-b18d-6c3590b28be6'), }); diff --git a/apps/backoffice-v2/src/domains/chat/chatbot-opengpt.tsx b/apps/backoffice-v2/src/domains/chat/chatbot-opengpt.tsx index bc0462d6db..c10b74cad2 100644 --- a/apps/backoffice-v2/src/domains/chat/chatbot-opengpt.tsx +++ b/apps/backoffice-v2/src/domains/chat/chatbot-opengpt.tsx @@ -1,7 +1,9 @@ -import { getClient, Webchat, WebchatProvider } from '@botpress/webchat'; +import { getClient, Webchat, WebchatProvider, WebchatClient } from '@botpress/webchat'; import { buildTheme } from '@botpress/webchat-generator'; -import { useEffect } from 'react'; +import { useCallback, useEffect, useState } from 'react'; import { useAuthenticatedUserQuery } from '../../domains/auth/hooks/queries/useAuthenticatedUserQuery/useAuthenticatedUserQuery'; +import { useCurrentCaseQuery } from '../../pages/Entity/hooks/useCurrentCaseQuery/useCurrentCaseQuery'; +import { useParams } from 'react-router-dom'; // declare const themeNames: readonly ["prism", "galaxy", "dusk", "eggplant", "dawn", "midnight"]; const { theme, style } = buildTheme({ @@ -9,30 +11,70 @@ const { theme, style } = buildTheme({ themeColor: 'blue', }); -const clientId = '8f29c89d-ec0e-494d-b18d-6c3590b28be6'; - const Chatbot = ({ isWebchatOpen, toggleIsWebchatOpen, + botpressClientId, }: { isWebchatOpen: boolean; toggleIsWebchatOpen: () => void; + botpressClientId: string; }) => { - const client = getClient({ clientId }); + const [client, setClient] = useState(null); const { data: session } = useAuthenticatedUserQuery(); + const { data: currentCase } = useCurrentCaseQuery(); + const { entityId: caseId } = useParams(); + + const sendCurrentCaseData = useCallback( + async (botpressClient: WebchatClient | null = client) => { + if (!currentCase || !botpressClient) { + return; + } + + try { + await botpressClient.sendEvent({ + type: 'case-data', + data: currentCase.context, + }); + } catch (error) { + console.error('Failed to send case data:', error); + } + }, + [currentCase, client], + ); useEffect(() => { - if (session?.user) { - const { firstName, lastName, email } = session.user; - void client.updateUser({ + if (client || !botpressClientId || !session?.user) { + return; + } + + const { firstName, lastName, email } = session.user; + const botpressClientInstance = getClient({ clientId: botpressClientId }); + setClient(botpressClientInstance); + + botpressClientInstance.on('conversation', (ev: any) => { + void botpressClientInstance.updateUser({ data: { firstName, lastName, email, }, }); + setTimeout(() => { + void sendCurrentCaseData(botpressClientInstance); + }, 0); + }); + }, [session, client, sendCurrentCaseData, botpressClientId]); + + useEffect(() => { + if (caseId) { + void sendCurrentCaseData(); } - }, [session, client]); + }, [caseId, sendCurrentCaseData]); + + if (!client) { + return null; + } return (
diff --git a/apps/backoffice-v2/src/domains/customer/fetchers.ts b/apps/backoffice-v2/src/domains/customer/fetchers.ts index 94587404af..dbe623de31 100644 --- a/apps/backoffice-v2/src/domains/customer/fetchers.ts +++ b/apps/backoffice-v2/src/domains/customer/fetchers.ts @@ -21,6 +21,9 @@ const CustomerSchema = z.object({ language: z.union([z.string(), z.null()]).optional(), features: z .object({ + chatbot: z + .object({ enabled: z.boolean().default(false), clientId: z.string().optional() }) + .optional(), createBusinessReport: z .object({ enabled: z.boolean().default(false), options: createBusinessReportOptions }) .optional(), @@ -35,7 +38,6 @@ const CustomerSchema = z.object({ isMerchantMonitoringEnabled: z.boolean().default(false), isExample: z.boolean().default(false), isDemo: z.boolean().default(false), - isChatbotEnabled: z.boolean().default(false), }) .nullable() .default({ diff --git a/apps/backoffice-v2/src/pages/Root/Root.page.tsx b/apps/backoffice-v2/src/pages/Root/Root.page.tsx index 4655a1ab77..1291224bc8 100644 --- a/apps/backoffice-v2/src/pages/Root/Root.page.tsx +++ b/apps/backoffice-v2/src/pages/Root/Root.page.tsx @@ -5,6 +5,9 @@ import { ServerDownLayout } from './ServerDown.layout'; import { useCustomerQuery } from '@/domains/customer/hooks/queries/useCustomerQuery/useCustomerQuery'; import { FullScreenLoader } from '@/common/components/molecules/FullScreenLoader/FullScreenLoader'; import Chatbot from '@/domains/chat/chatbot-opengpt'; +import { RenderChildrenInIFrame } from '@/common/components/organisms/RenderChildrenInIFrame/RenderChildrenInIFrame'; +import { ctw } from '@/common/utils/ctw/ctw'; +import { env } from '@/common/env/env'; const ReactQueryDevtools = lazy(() => process.env.NODE_ENV !== 'production' @@ -25,11 +28,26 @@ const ChatbotLayout: FunctionComponent = () => { return ; } - if (!customer?.config?.isChatbotEnabled) { + if (!customer?.features?.chatbot?.enabled) { return null; } - return ; + const botpressClientId = customer?.features?.chatbot?.clientId || env.VITE_BOTPRESS_CLIENT_ID; + + return ( + + + + ); }; export const Root: FunctionComponent = () => { diff --git a/packages/common/src/schemas/documents/workflow/config-schema.ts b/packages/common/src/schemas/documents/workflow/config-schema.ts index e3f6464bed..ebfebc3945 100644 --- a/packages/common/src/schemas/documents/workflow/config-schema.ts +++ b/packages/common/src/schemas/documents/workflow/config-schema.ts @@ -83,7 +83,6 @@ export const WorkflowConfigSchema = Type.Object({ hasUboOngoingMonitoring: Type.Optional(Type.Boolean()), maxBusinessReports: Type.Optional(Type.Number()), isMerchantMonitoringEnabled: Type.Optional(Type.Boolean()), - isChatbotEnabled: Type.Optional(Type.Boolean()), }); export type TWorkflowConfig = Static; diff --git a/services/workflows-service/src/workflow/schemas/zod-schemas.ts b/services/workflows-service/src/workflow/schemas/zod-schemas.ts index c47d641554..dc07bb4f07 100644 --- a/services/workflows-service/src/workflow/schemas/zod-schemas.ts +++ b/services/workflows-service/src/workflow/schemas/zod-schemas.ts @@ -62,7 +62,6 @@ export const ConfigSchema = z hasUboOngoingMonitoring: z.boolean().optional(), maxBusinessReports: z.number().nonnegative().optional(), isMerchantMonitoringEnabled: z.boolean().optional(), - isChatbotEnabled: z.boolean().optional(), uiOptions: z .object({ redirectUrls: z