Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: improve chatbot integration + css fixes #2872

Merged
merged 7 commits into from
Dec 4, 2024
Merged

feat: improve chatbot integration + css fixes #2872

merged 7 commits into from
Dec 4, 2024

Conversation

shanegrouber
Copy link
Collaborator

@shanegrouber shanegrouber commented Dec 1, 2024

Summary by CodeRabbit

Release Notes

  • New Features

    • Introduced a new configuration option for the Botpress client ID, enhancing the environment schema.
    • Enhanced the Chatbot component to manage client instances dynamically based on user interactions.
    • Added a new chatbot feature in the customer schema to control chatbot availability.
  • Improvements

    • Updated the Root page to better integrate the chatbot feature within an iframe, allowing for improved visibility and configuration control.
  • Schema Updates

    • Removed the isChatbotEnabled property from the WorkflowConfigSchema and ConfigSchema, streamlining the schema structure.

- Add client as a prop to Chatbot component
- Implement sending current case data to chatbot
- Improve environment variable usage for client ID

(Your code is like a bad magician—now you see the client, now you don’t)
- Import RenderChildrenInIFrame to contain the Chatbot
- Adjust resizing behavior based on chatbot visibility

(It's about time that chatbot got some boundaries; it was getting a bit too cozy)
- Introduce VITE_BOTPRESS_CLIENT_ID to environment schema
- Update Chatbot component to utilize dynamic client ID
- Adjust customer features to include chatbot configuration

(If your chatbot was any less reliable, it would be giving out horoscopes instead of responses)
Copy link

changeset-bot bot commented Dec 1, 2024

⚠️ No Changeset found

Latest commit: e8530bc

Merging this PR will not cause a version bump for any packages. If these changes should not result in a new version, you're good to go. If these changes should result in a version bump, you need to add a changeset.

This PR includes no changesets

When changesets are added to this PR, you'll see the packages that this PR includes changesets for and the associated semver types

Click here to learn what changesets are, and how to add one.

Click here if you're a maintainer who wants to add a changeset to this PR

Copy link
Contributor

coderabbitai bot commented Dec 1, 2024

Walkthrough

The pull request introduces several modifications across multiple files to enhance the chatbot feature in the backoffice application. Key changes include the addition of a new VITE_BOTPRESS_CLIENT_ID property to the environment schema, updates to the Chatbot component to utilize a WebchatClient, and the introduction of a chatbot property in the CustomerSchema. Additionally, the Root.page.tsx file is updated to improve the integration of the chatbot within an iframe, reflecting the new data structure for enabling the chatbot feature.

Changes

File Path Change Summary
apps/backoffice-v2/src/common/env/schema.ts Added property: VITE_BOTPRESS_CLIENT_ID: z.string().default('8f29c89d-ec0e-494d-b18d-6c3590b28be6')
apps/backoffice-v2/src/domains/chat/chatbot-opengpt.tsx Updated Chatbot component props to include botpressClientId: string. Introduced sendCurrentCaseData function and modified useEffect hooks for client management and case data handling.
apps/backoffice-v2/src/domains/customer/fetchers.ts Added property: chatbot: z.object({ enabled: z.boolean().default(false), clientId: z.string().optional() }) in CustomerSchema. Removed isChatbotEnabled from config.
apps/backoffice-v2/src/pages/Root/Root.page.tsx Introduced state variable botpressClientId. Updated condition for chatbot availability and modified return statement to include RenderChildrenInIFrame wrapping the Chatbot component.
packages/common/src/schemas/documents/workflow/config-schema.ts Removed property: isChatbotEnabled: Type.Optional(Type.Boolean()) from WorkflowConfigSchema.
services/workflows-service/src/workflow/schemas/zod-schemas.ts Removed property: isChatbotEnabled: z.boolean().optional() from ConfigSchema.

Possibly related PRs

  • Chatbot #2679: Changes in this PR involve the chatbot-opengpt.tsx file, directly related to the Chatbot component utilizing Botpress webchat functionality, adding a property for the Botpress client ID.
  • Chatbot css fix #2686: Modifications to the Root.page.tsx file enhance the chatbot's functionality and directly utilize the botpressClientId, which connects to the new property added in the main PR.
  • chat iframe revert #2737: Changes to the Root.page.tsx file include rendering logic for the ChatbotLayout component, connected to the Botpress client ID configuration changes in the main PR.
  • Backoffice UI improvements #2827: Modifications in Root.page.tsx regarding the chatbot's rendering logic and state management are connected to the new VITE_BOTPRESS_CLIENT_ID, impacting how the chatbot is configured and displayed.

Suggested reviewers

  • Omri-Levy
  • tomer-shvadron

Poem

🐰 In the backoffice, changes hop,
A Botpress client, ready to swap.
With chatbots now in an iframe's embrace,
We welcome new features, a lively space!
Configs and schemas, all set to play,
Let’s chat and connect, hip-hip-hooray! 🎉


📜 Recent review details

Configuration used: CodeRabbit UI
Review profile: CHILL

📥 Commits

Reviewing files that changed from the base of the PR and between 8aec429 and e8530bc.

📒 Files selected for processing (2)
  • apps/backoffice-v2/src/domains/customer/fetchers.ts (1 hunks)
  • apps/backoffice-v2/src/pages/Root/Root.page.tsx (2 hunks)
🚧 Files skipped from review as they are similar to previous changes (2)
  • apps/backoffice-v2/src/domains/customer/fetchers.ts
  • apps/backoffice-v2/src/pages/Root/Root.page.tsx

Thank you for using CodeRabbit. We offer it for free to the OSS community and would appreciate your support in helping us grow. If you find it useful, would you consider giving us a shout-out on your favorite social media?

❤️ Share
🪧 Tips

Chat

There are 3 ways to chat with CodeRabbit:

  • Review comments: Directly reply to a review comment made by CodeRabbit. Example:
    • I pushed a fix in commit <commit_id>, please review it.
    • Generate unit testing code for this file.
    • Open a follow-up GitHub issue for this discussion.
  • Files and specific lines of code (under the "Files changed" tab): Tag @coderabbitai in a new review comment at the desired location with your query. Examples:
    • @coderabbitai generate unit testing code for this file.
    • @coderabbitai modularize this function.
  • PR comments: Tag @coderabbitai in a new PR comment to ask questions about the PR branch. For the best results, please provide a very specific query, as very limited context is provided in this mode. Examples:
    • @coderabbitai gather interesting stats about this repository and render them as a table. Additionally, render a pie chart showing the language distribution in the codebase.
    • @coderabbitai read src/utils.ts and generate unit testing code.
    • @coderabbitai read the files in the src/scheduler package and generate a class diagram using mermaid and a README in the markdown format.
    • @coderabbitai help me debug CodeRabbit configuration file.

Note: Be mindful of the bot's finite context window. It's strongly recommended to break down tasks such as reading entire modules into smaller chunks. For a focused discussion, use review comments to chat about specific files and their changes, instead of using the PR comments.

CodeRabbit Commands (Invoked using PR comments)

  • @coderabbitai pause to pause the reviews on a PR.
  • @coderabbitai resume to resume the paused reviews.
  • @coderabbitai review to trigger an incremental review. This is useful when automatic reviews are disabled for the repository.
  • @coderabbitai full review to do a full review from scratch and review all the files again.
  • @coderabbitai summary to regenerate the summary of the PR.
  • @coderabbitai resolve resolve all the CodeRabbit review comments.
  • @coderabbitai configuration to show the current CodeRabbit configuration for the repository.
  • @coderabbitai help to get help.

Other keywords and placeholders

  • Add @coderabbitai ignore anywhere in the PR description to prevent this PR from being reviewed.
  • Add @coderabbitai summary to generate the high-level summary at a specific location in the PR description.
  • Add @coderabbitai anywhere in the PR title to generate the title automatically.

CodeRabbit Configuration File (.coderabbit.yaml)

  • You can programmatically configure CodeRabbit by adding a .coderabbit.yaml file to the root of your repository.
  • Please see the configuration documentation for more information.
  • If your editor has YAML language server enabled, you can add the path at the top of this file to enable auto-completion and validation: # yaml-language-server: $schema=https://coderabbit.ai/integrations/schema.v2.json

Documentation and Community

  • Visit our Documentation for detailed information on how to use CodeRabbit.
  • Join our Discord Community to get help, request features, and share feedback.
  • Follow us on X/Twitter for updates and announcements.

Copy link
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 5

🧹 Outside diff range and nitpick comments (5)
apps/backoffice-v2/src/pages/Root/Root.page.tsx (1)

39-54: Consider making iframe dimensions responsive

The current implementation uses fixed dimensions (700px height, 400px width) for the webchat iframe. Consider:

  • Using responsive units (vh/vw) or min/max constraints
  • Adapting to different screen sizes
  • Handling mobile viewports
 <RenderChildrenInIFrame
   className={ctw('fixed bottom-right-0', {
-    'h-[700px] w-[400px]': isWebchatOpen,
+    'h-[min(700px,80vh)] w-[min(400px,90vw)]': isWebchatOpen,
     'h-[80px]': !isWebchatOpen,
   })}
 >
apps/backoffice-v2/src/domains/chat/chatbot-opengpt.tsx (3)

60-63: Remove unnecessary commented code

The commented-out event listener for '*' events is not in use. Removing unused code helps keep the codebase clean and maintainable.

Apply this diff to remove the commented code:

-// newClient.on('*', (ev: any) => {
-//   console.log('Event: ', ev);
-// });

64-77: Specify event types instead of using any

Using any for event parameters reduces type safety. Specify the appropriate event types to improve code reliability and maintainability.

Apply this diff to specify the event type:

-newClient.on('conversation', (ev: any) => {
+newClient.on('conversation', (ev: ConversationCreatedEvent) => {

Ensure you import or define the ConversationCreatedEvent type from the @botpress/webchat package.


88-90: Provide a fallback UI when the client is not available

Returning null when the client is not available might lead to a blank space in the UI. Consider providing a loading indicator or a message to inform the user.

Example modification:

 if (!client) {
-  return null;
+  return <div>Loading chat...</div>;
 }
apps/backoffice-v2/src/domains/customer/fetchers.ts (1)

24-24: Consolidate chatbot enablement flags to avoid confusion

Both features.chatbot.isEnabled and config.isChatbotEnabled control the chatbot feature's enablement status. To prevent redundancy and potential discrepancies, consider consolidating these into a single property.

Decide whether features.chatbot.isEnabled or config.isChatbotEnabled should be used throughout the codebase, and remove the other to maintain clarity.

📜 Review details

Configuration used: CodeRabbit UI
Review profile: CHILL

📥 Commits

Reviewing files that changed from the base of the PR and between 7068072 and 05e196a.

📒 Files selected for processing (4)
  • apps/backoffice-v2/src/common/env/schema.ts (1 hunks)
  • apps/backoffice-v2/src/domains/chat/chatbot-opengpt.tsx (1 hunks)
  • apps/backoffice-v2/src/domains/customer/fetchers.ts (1 hunks)
  • apps/backoffice-v2/src/pages/Root/Root.page.tsx (3 hunks)
🔇 Additional comments (3)
apps/backoffice-v2/src/pages/Root/Root.page.tsx (3)

8-11: LGTM: Imports are well-organized and necessary

The new imports support the enhanced chatbot functionality with iframe rendering and client management.


23-23: LGTM: State management follows React best practices

The WebchatClient state is properly typed and initialized with null.


37-38: Verify environment variable configuration

The code falls back to env.VITE_BOTPRESS_CLIENT_ID. Ensure this environment variable is properly defined and documented.

✅ Verification successful

Environment variable is properly configured with a default value

The environment variable VITE_BOTPRESS_CLIENT_ID is properly defined in apps/backoffice-v2/src/common/env/schema.ts with a default value of '8f29c89d-ec0e-494d-b18d-6c3590b28be6'. The fallback implementation in the code is safe and well-configured.

🏁 Scripts executed

The following scripts were executed for the analysis:

Script:

#!/bin/bash
# Check for environment variable definition
rg "VITE_BOTPRESS_CLIENT_ID"

# Look for environment schema definitions
fd "schema.ts" --exec rg -A 5 -B 5 "VITE_BOTPRESS_CLIENT_ID" {}

Length of output: 609

apps/backoffice-v2/src/pages/Root/Root.page.tsx Outdated Show resolved Hide resolved
apps/backoffice-v2/src/domains/chat/chatbot-opengpt.tsx Outdated Show resolved Hide resolved
apps/backoffice-v2/src/common/env/schema.ts Show resolved Hide resolved
apps/backoffice-v2/src/domains/customer/fetchers.ts Outdated Show resolved Hide resolved
- Remove redundant isChatbotEnabled flags from schemas
- Clean up caseId assignment placement in chatbot component

(Your code is so clean, it's practically begging for a dust bunny)
Copy link
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 0

🧹 Outside diff range and nitpick comments (3)
apps/backoffice-v2/src/domains/chat/chatbot-opengpt.tsx (3)

31-51: Consider enhancing error handling and type safety

While the sendCaseData implementation is functional, there are a few improvements that could make it more robust:

  1. Add type definitions for the case data structure
  2. Implement more specific error handling
  3. Consider creating a new object instead of spreading the context directly

Here's a suggested improvement:

 const sendCaseData = useCallback(
-  async (caseId: string, newClient?: WebchatClient) => {
+  async (caseId: string, newClient?: WebchatClient | null) => {
+    type CaseData = {
+      caseId: string;
+      [key: string]: unknown;
+    };
+
     if (!currentCase) return;
     const clientToUse = newClient || client;
+    if (!clientToUse) return;

     try {
       const currentCaseData = {
-        ...currentCase.context,
+        ...JSON.parse(JSON.stringify(currentCase.context)),
         caseId,
       };
       await clientToUse?.sendEvent({
         type: 'case-data',
         data: currentCaseData,
       });
     } catch (error) {
-      console.error('Failed to send case data:', error);
+      console.error(`Failed to send case data for case ${caseId}:`, error);
+      // Consider adding error reporting or user notification here
     }
   },
   [currentCase, client],
 );

60-62: Remove commented-out debug code

The commented-out debug event listener should be removed if it's not needed.


80-86: Clean up pathname change handler

The current implementation includes debug logging and could benefit from improved pathname parsing:

  1. Remove the console.log statement
  2. Simplify pathname parsing
  3. Improve async handling

Here's a suggested improvement:

 useEffect(() => {
-  console.log('pathname changed to: ', pathname);
-
-  const caseId = pathname.split('/')[pathname.split('/').length - 1];
+  const caseId = new URL(window.location.href).pathname.split('/').pop() || '';
-  if (caseId) void sendCaseData(caseId);
+  if (caseId) {
+    sendCaseData(caseId).catch(error => 
+      console.error('Failed to update case data on pathname change:', error)
+    );
+  }
 }, [pathname, sendCaseData]);
📜 Review details

Configuration used: CodeRabbit UI
Review profile: CHILL

📥 Commits

Reviewing files that changed from the base of the PR and between 05e196a and 18fad73.

📒 Files selected for processing (4)
  • apps/backoffice-v2/src/domains/chat/chatbot-opengpt.tsx (1 hunks)
  • apps/backoffice-v2/src/domains/customer/fetchers.ts (1 hunks)
  • packages/common/src/schemas/documents/workflow/config-schema.ts (0 hunks)
  • services/workflows-service/src/workflow/schemas/zod-schemas.ts (0 hunks)
💤 Files with no reviewable changes (2)
  • packages/common/src/schemas/documents/workflow/config-schema.ts
  • services/workflows-service/src/workflow/schemas/zod-schemas.ts
🚧 Files skipped from review as they are similar to previous changes (1)
  • apps/backoffice-v2/src/domains/customer/fetchers.ts
🔇 Additional comments (4)
apps/backoffice-v2/src/domains/chat/chatbot-opengpt.tsx (4)

17-25: LGTM: Well-structured props with proper typing

The addition of client, setClient, and chatbotClientId props with explicit TypeScript types improves type safety and follows good practices for state management.


88-90: LGTM: Clean rendering logic

The early return pattern with proper null checking is well implemented.


64-77: 🛠️ Refactor suggestion

Improve event handling implementation

The current implementation has several issues that should be addressed:

  1. Using setTimeout for async operations (previously flagged)
  2. Using any type for the event parameter
  3. Complex pathname parsing logic that could be simplified

Here's a suggested improvement:

-    newClient.on('conversation', (ev: any) => {
+    newClient.on('conversation', async (ev: { id: string }) => {
       // new conversation created
-      void newClient.updateUser({
+      await newClient.updateUser({
         data: {
           firstName,
           lastName,
           email,
         },
       });
-      setTimeout(() => {
-        const caseId = pathname.split('/')[pathname.split('/').length - 1];
-        void sendCaseData(caseId || '', newClient);
-      }, 500);
+      const caseId = new URL(window.location.href).pathname.split('/').pop() || '';
+      await sendCaseData(caseId, newClient);
     });

Line range hint 97-116: Verify XSS protection in webchat configuration

The webchat configuration includes user-facing content and external URLs. Ensure that the Botpress webchat component properly sanitizes this content.

✅ Verification successful

Let me gather more information about the webchat implementation and its security measures.


Let me check the Botpress webchat component's implementation to verify its content sanitization.


Based on the investigation, I can now provide a final response:

Webchat configuration is secure against XSS

The Botpress webchat implementation is secure for the following reasons:

  • Using official @botpress/webchat package version ^2.1.10 which has no known security vulnerabilities
  • Configuration only contains static content and URLs from trusted sources (ballerine.io and ballerine.com domains)
  • No direct HTML rendering or dangerous innerHTML usage in the chat component
  • The webchat content is properly encapsulated within the official Botpress components
🏁 Scripts executed

The following scripts were executed for the analysis:

Script:

#!/bin/bash
# Check if the @botpress/webchat package has any known security vulnerabilities

gh api graphql -f query='
{
  securityVulnerabilities(first: 5, ecosystem: NPM, package: "@botpress/webchat") {
    nodes {
      advisory {
        summary
        severity
        publishedAt
      }
      vulnerableVersionRange
      firstPatchedVersion {
        identifier
      }
    }
  }
}'

Length of output: 350


Script:

#!/bin/bash
# Check the package.json for @botpress/webchat version
fd package.json --exec cat {} \; | jq -r '.dependencies["@botpress/webchat"] // .devDependencies["@botpress/webchat"] // empty'

# Look for any XSS protection or sanitization in the codebase
rg -i "xss|sanitize|purify|dompurify|sanitization" -A 3

# Check if DOMPurify or other sanitization libraries are imported
rg -i "import.*(?:dompurify|sanitize|xss|purify)" -g "*.{ts,tsx,js,jsx}"

Length of output: 19498


Script:

#!/bin/bash
# Look for Botpress webchat configuration and sanitization
rg -i "botpress.*webchat" -A 5 -g "*.{ts,tsx,js,jsx}"

# Check if there are any direct uses of dangerouslySetInnerHTML in the chat component
ast-grep --pattern 'dangerouslySetInnerHTML = { $$ }'

# Look for any HTML rendering in the chat component
rg -i "innerHTML|dangerouslySetInnerHTML" -g "chatbot-opengpt.tsx"

Length of output: 1632

Copy link
Collaborator

@tomer-shvadron tomer-shvadron left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

apps/backoffice-v2/src/domains/chat/chatbot-opengpt.tsx Outdated Show resolved Hide resolved
apps/backoffice-v2/src/domains/chat/chatbot-opengpt.tsx Outdated Show resolved Hide resolved
apps/backoffice-v2/src/domains/chat/chatbot-opengpt.tsx Outdated Show resolved Hide resolved
apps/backoffice-v2/src/domains/chat/chatbot-opengpt.tsx Outdated Show resolved Hide resolved
apps/backoffice-v2/src/domains/chat/chatbot-opengpt.tsx Outdated Show resolved Hide resolved
apps/backoffice-v2/src/domains/chat/chatbot-opengpt.tsx Outdated Show resolved Hide resolved
apps/backoffice-v2/src/domains/chat/chatbot-opengpt.tsx Outdated Show resolved Hide resolved
apps/backoffice-v2/src/domains/chat/chatbot-opengpt.tsx Outdated Show resolved Hide resolved
- Remove unused WebchatClient state from ChatbotLayout
- Change variable names for clarity and consistency
- Update useEffect hooks to handle new parameter definitions

(With all these changes, I half-expect the chatbot to start giving better life advice)
Copy link
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 0

🧹 Outside diff range and nitpick comments (1)
apps/backoffice-v2/src/domains/chat/chatbot-opengpt.tsx (1)

28-44: Enhance error logging in sendCurrentCaseData

While the error handling is good, consider adding more context to the error log to aid debugging.

-        console.error('Failed to send case data:', error);
+        console.error('Failed to send case data:', {
+          error,
+          caseId,
+          hasCurrentCase: !!currentCase,
+        });
📜 Review details

Configuration used: CodeRabbit UI
Review profile: CHILL

📥 Commits

Reviewing files that changed from the base of the PR and between 18fad73 and 78294ce.

📒 Files selected for processing (2)
  • apps/backoffice-v2/src/domains/chat/chatbot-opengpt.tsx (1 hunks)
  • apps/backoffice-v2/src/pages/Root/Root.page.tsx (2 hunks)
🔇 Additional comments (8)
apps/backoffice-v2/src/pages/Root/Root.page.tsx (4)

8-10: LGTM: New imports are appropriate for the changes

The added imports support the new iframe-based chatbot implementation and environment configuration.


31-31: Migration to new chatbot enablement path structure is incomplete

The change from customer?.config?.isChatbotEnabled to customer?.features?.chatbot?.isEnabled represents a breaking change in the data structure.


39-42: Fix incorrect class name in conditional styling

There appears to be a typo in the className when webchat is closed.


35-36: Verify environment variable configuration

Please ensure that VITE_BOTPRESS_CLIENT_ID is properly defined in the environment configuration.

✅ Verification successful

Environment variable is properly configured with a default value

The VITE_BOTPRESS_CLIENT_ID is properly defined in the environment schema at apps/backoffice-v2/src/common/env/schema.ts with a default value of '8f29c89d-ec0e-494d-b18d-6c3590b28be6', making the fallback implementation safe to use.

🏁 Scripts executed

The following scripts were executed for the analysis:

Script:

#!/bin/bash
# Check if VITE_BOTPRESS_CLIENT_ID is defined in environment schema
rg "VITE_BOTPRESS_CLIENT_ID.*=.*" -g "*.env*"
rg "VITE_BOTPRESS_CLIENT_ID" -g "*schema.ts"

Length of output: 223

apps/backoffice-v2/src/domains/chat/chatbot-opengpt.tsx (4)

1-1: LGTM: Props and imports are well-defined

The addition of WebchatClient import and botpressClientId prop with proper typing improves type safety.

Also applies to: 17-21


23-26: LGTM: Improved hooks implementation

Good improvements:

  • Type-safe client state management
  • Using useParams for route parameters instead of manual pathname parsing

63-66: Avoid using setTimeout for asynchronous operations

Using setTimeout (even with 0 delay) for delaying sendCurrentCaseData execution is not ideal.


69-73: LGTM: Clean effect implementation

The effect is well-implemented with proper dependency tracking and null checking.

- Update CustomerSchema to use 'enabled' instead of 'isEnabled'
- Adjust conditional check in ChatbotLayout for consistency

(your naming conventions are so confusing, they should come with a user manual)
@tomer-shvadron tomer-shvadron merged commit 786d520 into dev Dec 4, 2024
10 checks passed
@tomer-shvadron tomer-shvadron deleted the BAL-3040 branch December 4, 2024 09:43
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants