Skip to content

Conversation

luancazarine
Copy link
Collaborator

@luancazarine luancazarine commented Mar 20, 2025

Resolves #15920.

Summary by CodeRabbit

  • New Features

    • Introduced new modules for creating and updating customer and conversation records.
    • Enabled real-time event notifications for new and updated conversations, customers, and messages.
    • Expanded configuration options with additional selectable settings for statuses, priorities, languages, and more.
  • Chores

    • Upgraded the component version and dependencies to improve integration stability and performance.

@luancazarine luancazarine added the ai-assisted Content generated by AI, with human refinement and modification label Mar 20, 2025
Copy link

vercel bot commented Mar 20, 2025

The latest updates on your projects. Learn more about Vercel for Git ↗︎

3 Skipped Deployments
Name Status Preview Comments Updated (UTC)
docs-v2 ⬜️ Ignored (Inspect) Visit Preview Mar 24, 2025 3:23pm
pipedream-docs ⬜️ Ignored (Inspect) Mar 24, 2025 3:23pm
pipedream-docs-redirect-do-not-edit ⬜️ Ignored (Inspect) Mar 24, 2025 3:23pm

Copy link
Contributor

coderabbitai bot commented Mar 20, 2025

Walkthrough

This pull request introduces new modules for interacting with the Kustomer API. It adds actions to create and update both conversations and customers with detailed property configurations, error handling, and data parsing via utility functions. Additionally, a set of common constants and utility methods have been implemented to standardize operations. The application module now includes extensive property definitions and API methods. Several source modules have also been introduced for emitting events (new conversation, new customer, new message, updated conversation, updated customer), along with corresponding test event files. Lastly, the package configuration was updated for versioning and dependencies.

Changes

File(s) Change Summary
components/kustomer/actions/(create-conversation.mjs, create-customer.mjs, update-conversation.mjs, update-customer.mjs) New modules added for creating and updating conversations and customers. Each handles optional parameters, utilizes utility functions for parsing, and includes proper error handling.
components/kustomer/common/(constants.mjs, utils.mjs) Introduced constants for statuses, directions, and language options; added utility functions (parseObject and throwError) for standardized data processing and error reporting.
components/kustomer/kustomer.app.mjs Expanded property definitions and API method implementations for managing customers and conversations; restructured the module by removing obsolete authentication methods.
components/kustomer/package.json Version updated from 0.0.1 to 0.1.0 and a dependency on @pipedream/platform (^3.0.3) added.
components/kustomer/sources/** New source modules (and corresponding test events) added for emitting events on new conversation, new customer, new message, updated conversation, and updated customer.

Sequence Diagram(s)

sequenceDiagram
    participant Action as CreateConversation Action
    participant Utils as parseObject Utility
    participant API as Kustomer API
    Action->>Utils: Parse input fields (tags, assignedUsers, assignedTeams)
    Action->>API: Call createConversation with parsed data
    API-->>Action: Return conversation ID or error
Loading
sequenceDiagram
    participant Source as NewConversation Source
    participant Common as Common Base Module
    participant Emitter as Event Emitter
    Source->>Common: Invoke getEventType() & getSummary()
    Common->>Emitter: Emit event with details
    Emitter-->>Source: Confirm event emission
Loading

Assessment against linked issues

Objective Addressed Explanation
Emit source events for new and updated conversations, customers, and messages [#15920]
Implement actions to create and update conversations and customers in Kustomer [#15920]

Possibly related PRs

Suggested labels

action, trigger / source

Poem

I'm a bunny, hopping through lines of code so neat,
Celebrating new actions that make our API complete.
Conversations and customers now dance in the light,
With events that spring forth both day and night.
My whiskers twitch with joy as the modules take flight,
CodeRabbit cheers in every byte! 🐇
Happy coding with a burrow of delight!

Warning

There were issues while running some tools. Please review the errors and either fix the tool’s configuration or disable the tool if it’s a critical failure.

🔧 ESLint

If the error stems from missing dependencies, add them to the package.json file. For unrecoverable errors (e.g., due to private dependencies), disable the tool in the CodeRabbit configuration.

components/kustomer/common/utils.mjs

Oops! Something went wrong! :(

ESLint: 8.57.1

Error [ERR_MODULE_NOT_FOUND]: Cannot find package 'jsonc-eslint-parser' imported from /eslint.config.mjs
at packageResolve (node:internal/modules/esm/resolve:839:9)
at moduleResolve (node:internal/modules/esm/resolve:908:18)
at defaultResolve (node:internal/modules/esm/resolve:1038:11)
at ModuleLoader.defaultResolve (node:internal/modules/esm/loader:557:12)
at ModuleLoader.resolve (node:internal/modules/esm/loader:525:25)
at ModuleLoader.getModuleJob (node:internal/modules/esm/loader:246:38)
at ModuleJob._link (node:internal/modules/esm/module_job:126:49)


📜 Recent review details

Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between f9c308c and 93975c0.

📒 Files selected for processing (1)
  • components/kustomer/common/utils.mjs (1 hunks)
🚧 Files skipped from review as they are similar to previous changes (1)
  • components/kustomer/common/utils.mjs
⏰ Context from checks skipped due to timeout of 90000ms (3)
  • GitHub Check: Verify TypeScript components
  • GitHub Check: pnpm publish
  • GitHub Check: Publish TypeScript components

🪧 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 generate docstrings to generate docstrings for this 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.

Sources
 - New Conversation (Instant)
 - New Customer (Instant)
 - New Message (Instant)
 - Updated Conversation (Instant)
 - Updated Customer (Instant)

Actions
 - Create Conversation
 - Update Conversation
 - Create Customer
 - Update Customer
@luancazarine luancazarine marked this pull request as ready for review March 21, 2025 20:53
jcortes
jcortes previously approved these changes Mar 21, 2025
Copy link
Collaborator

@jcortes jcortes left a comment

Choose a reason for hiding this comment

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

Hi @luancazarine lgtm! Ready for QA!

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: 11

🧹 Nitpick comments (12)
components/kustomer/common/constants.mjs (1)

1-22: Consider using numeric values for SENTIMENT_OPTIONS.

The SENTIMENT_OPTIONS array contains string values ("-1", "0", "1") rather than numeric values. This might cause type conversion issues if used in numeric comparisons or calculations.

export const SENTIMENT_OPTIONS = [
-  "-1",
-  "0",
-  "1",
+  -1,
+  0,
+  1,
];
components/kustomer/actions/create-conversation/create-conversation.mjs (1)

92-117: Consider enhancing error handling with more context.

While the current error handling catches and throws the error message, it would be helpful to add more context about the operation that failed.

  async run({ $ }) {
    try {
      const response = await this.kustomer.createConversation({
        $,
        data: {
          customer: this.customer,
          externalId: this.externalId,
          name: this.name,
          status: this.status,
          priority: this.priority,
          direction: this.direction,
          tags: parseObject(this.tags),
          assignedUsers: parseObject(this.assignedUsers),
          assignedTeams: parseObject(this.assignedTeams),
          defaultLang: this.defaultLang,
          queue: {
            id: this.queueId,
          },
        },
      });

      $.export("$summary", `Created conversation with ID ${response.data.id}`);
      return response;
    } catch ({ message }) {
-      throwError(message);
+      throwError(`Failed to create conversation: ${message}`);
    }
  },
components/kustomer/actions/create-customer/create-customer.mjs (2)

148-153: Simplify sentiment object creation.

The current approach for creating the sentiment object is somewhat complex. Consider using a more concise approach.

  async run({ $ }) {
    try {
-      const sentiment = {};
-      if (this.sentimentConfidence) sentiment.confidence = parseInt(this.sentimentConfidence);
-      if (this.sentimentPolarity) sentiment.polarity = parseInt(this.sentimentPolarity);
+      const sentiment = {
+        ...(this.sentimentConfidence && { confidence: parseInt(this.sentimentConfidence) }),
+        ...(this.sentimentPolarity && { polarity: parseInt(this.sentimentPolarity) }),
+      };

174-182: Clarify the purpose of string conversion for phone numbers.

The code uses template literals (${phone}) to convert phone numbers to strings. The purpose of this conversion should be made clearer with a comment.

          phones: parseObject(this.phones)?.map((phone) => ({
-            phone: `${phone}`,
+            phone: `${phone}`, // Ensure phone is treated as a string
          })),
          sharedPhones: parseObject(this.sharedPhones)?.map((phone) => ({
-            phone: `${phone}`,
+            phone: `${phone}`, // Ensure phone is treated as a string
          })),
          whatsapps: parseObject(this.whatsApps)?.map((phone) => ({
-            phone: `${phone}`,
+            phone: `${phone}`, // Ensure phone is treated as a string
          })),
components/kustomer/sources/new-conversation-instant/test-event.mjs (2)

1-192: Test event structure looks comprehensive but has placeholder IDs that should be clarified.

The test event structure provides a detailed representation of a Kustomer conversation creation event, which is excellent for testing. However, I noticed that all IDs (e.g., on lines 3, 32-34, 48-49, 52-54) use the same placeholder value "67dd47dfbc632c1804db1bf1". While this works for testing, it might be helpful to:

  1. Add a comment indicating these are placeholder IDs
  2. Consider using different placeholder IDs for different entities to help distinguish between them during testing

This would make the test event more representative of real-world data and help developers better understand the relationships between different entities.


15-101: Future dates used in test event might cause confusion.

The test event uses dates in 2025 (e.g., lines 16, 25-28, 91-99) for timestamps like createdAt, updatedAt, etc. Using future dates might cause confusion or unexpected behavior in tests that rely on date comparisons.

Consider using either:

  1. More recent dates (e.g., current year)
  2. A comment explaining why future dates are used
  3. Variables that generate dates relative to the current time when tests are run
components/kustomer/sources/new-customer-instant/new-customer-instant.mjs (1)

1-24: Source component looks well-structured but version should follow semantic versioning.

The new customer instant source component is well-structured, extending the common base functionality appropriately. The getEventType() and getSummary() methods are implemented correctly.

However, I would recommend following semantic versioning best practices:

  1. For an initial release that's ready for production use, consider starting with version "1.0.0" instead of "0.0.1"
  2. If this is truly a pre-release/experimental version, add a comment indicating its status

Semantic versioning would make it clearer to users what to expect in terms of stability and compatibility.

components/kustomer/sources/common/base.mjs (1)

11-15: The 'name' prop should have a default value.

The name prop is required for webhook creation but doesn't have a default value. This could lead to errors if users don't provide a name.

Consider adding a default value that includes a unique identifier (like the component key) to ensure webhooks are always named properly:

name: {
  type: "string",
  label: "Webhook Name",
  description: "The name of the webhook to be identified in the UI",
+ default: "Pipedream Kustomer Webhook",
},
components/kustomer/sources/new-customer-instant/test-event.mjs (3)

1-111: Test event structure is comprehensive but has the same placeholder ID issue.

Similar to the conversation test event, this customer test event uses the same placeholder ID "67dd47dfbc632c1804db1bf1" throughout the object (e.g., lines 2-5, 9, etc.). Using different IDs for different entities would make the test data more realistic and easier to understand.

Additionally, this test event also uses future dates in 2025 (lines 31-36), which could cause the same potential issues mentioned previously.


6-6: The 'orgName' property is hardcoded to a specific organization.

Line 6 contains a hardcoded organization name "par-pipedream-berta" which appears to be a specific testing organization. This might cause confusion for other users of this component.

Consider:

  1. Using a more generic name like "Example Organization"
  2. Adding a comment explaining this is just an example value

10-64: Consider adding example custom fields in customer attributes.

The customer attributes section is comprehensive but doesn't include any example of custom fields that users might have in their Kustomer instance. Since custom fields are common in CRM systems like Kustomer, it would be helpful to show an example of how they appear in the payload.

Consider adding an example custom field like custom or customAttributes to help users understand how to access these values.

components/kustomer/sources/updated-customer-instant/updated-customer-instant.mjs (1)

7-7: Rename source to follow Pipedream’s guidelines.
According to the lint warning, source names should start with "New". For example:

-  name: "Updated Customer (Instant)",
+  name: "New Updated Customer (Instant)",
🧰 Tools
🪛 GitHub Check: Lint Code Base

[warning] 7-7:
Source names should start with "New". See https://pipedream.com/docs/components/guidelines/#source-name

📜 Review details

Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 70b218c and f9c308c.

⛔ Files ignored due to path filters (1)
  • pnpm-lock.yaml is excluded by !**/pnpm-lock.yaml
📒 Files selected for processing (19)
  • components/kustomer/actions/create-conversation/create-conversation.mjs (1 hunks)
  • components/kustomer/actions/create-customer/create-customer.mjs (1 hunks)
  • components/kustomer/actions/update-conversation/update-conversation.mjs (1 hunks)
  • components/kustomer/actions/update-customer/update-customer.mjs (1 hunks)
  • components/kustomer/common/constants.mjs (1 hunks)
  • components/kustomer/common/utils.mjs (1 hunks)
  • components/kustomer/kustomer.app.mjs (1 hunks)
  • components/kustomer/package.json (2 hunks)
  • components/kustomer/sources/common/base.mjs (1 hunks)
  • components/kustomer/sources/new-conversation-instant/new-conversation-instant.mjs (1 hunks)
  • components/kustomer/sources/new-conversation-instant/test-event.mjs (1 hunks)
  • components/kustomer/sources/new-customer-instant/new-customer-instant.mjs (1 hunks)
  • components/kustomer/sources/new-customer-instant/test-event.mjs (1 hunks)
  • components/kustomer/sources/new-message-instant/new-message-instant.mjs (1 hunks)
  • components/kustomer/sources/new-message-instant/test-event.mjs (1 hunks)
  • components/kustomer/sources/updated-conversation-instant/test-event.mjs (1 hunks)
  • components/kustomer/sources/updated-conversation-instant/updated-conversation-instant.mjs (1 hunks)
  • components/kustomer/sources/updated-customer-instant/test-event.mjs (1 hunks)
  • components/kustomer/sources/updated-customer-instant/updated-customer-instant.mjs (1 hunks)
🧰 Additional context used
🪛 GitHub Check: Lint Code Base
components/kustomer/sources/updated-conversation-instant/updated-conversation-instant.mjs

[warning] 7-7:
Source names should start with "New". See https://pipedream.com/docs/components/guidelines/#source-name

components/kustomer/sources/updated-customer-instant/updated-customer-instant.mjs

[warning] 7-7:
Source names should start with "New". See https://pipedream.com/docs/components/guidelines/#source-name

🔇 Additional comments (14)
components/kustomer/package.json (2)

3-3: Version bump looks appropriate for new component features.

The version bump from 0.0.1 to 0.1.0 follows semantic versioning principles for adding new functionality.


14-16: Dependency configuration properly structured.

The dependency on @pipedream/platform is correctly specified with a caret range to allow for compatible updates.

components/kustomer/common/constants.mjs (1)

24-337: Well-structured language options.

The DEFAULT_LANG_OPTIONS array is comprehensive and consistently structured with label/value pairs.

components/kustomer/actions/create-conversation/create-conversation.mjs (1)

85-90:

❓ Verification inconclusive

Verify if queueId should be required.

Unlike other props which are marked as optional, queueId doesn't have the optional: true flag, making it a required field. Ensure this is intentional based on Kustomer API requirements.


🏁 Script executed:

#!/bin/bash
# Check Kustomer API documentation to see if queueId is required
rg -A 3 -B 3 "queue.*required" --type js components/kustomer/

Length of output: 63


Action Required: Confirm if queueId Must Be Required According to Kustomer API

The current implementation marks queueId as required (i.e. without the optional: true flag), unlike other properties. Our automated search in the codebase for any explicit note regarding it being required returned no conclusive results. Please manually verify against the Kustomer API documentation to confirm if this field indeed must be required or if it should be made optional for consistency.

  • File: components/kustomer/actions/create-conversation/create-conversation.mjs
  • Snippet:
        queueId: {
          propDefinition: [
            kustomer,
            "queueId",
          ],
        },
  • Action: Double-check the Kustomer API docs and update the definition if needed (e.g., add optional: true if the field should not be required).
components/kustomer/sources/updated-conversation-instant/updated-conversation-instant.mjs (1)

1-24: LGTM! The source implementation follows best practices

The component is well-structured and implements the correct methods for an instant source. The warning about source names starting with "New" is a false positive in this case since this source is for "Updated" conversations, not "New" ones.

🧰 Tools
🪛 GitHub Check: Lint Code Base

[warning] 7-7:
Source names should start with "New". See https://pipedream.com/docs/components/guidelines/#source-name

components/kustomer/sources/new-conversation-instant/new-conversation-instant.mjs (1)

1-24: LGTM! The source implementation follows best practices

The component is well-structured and implements the correct methods for an instant source. The name correctly reflects its purpose of detecting new conversation creation.

components/kustomer/sources/new-message-instant/new-message-instant.mjs (1)

4-24: Module structure looks good and follows the component pattern.

The module correctly extends the common base module and implements the necessary methods for handling new message events. The event type is properly defined as "kustomer.message.create" and the getSummary method formats a clear message with the dataId.

components/kustomer/sources/updated-conversation-instant/test-event.mjs (1)

1-250: Sample test event appears well-structured.

This test event provides comprehensive data for testing the updated conversation source. It includes a detailed conversation object with properties, relationships, and change tracking that accurately represents a Kustomer API response.

components/kustomer/sources/new-message-instant/test-event.mjs (1)

1-115: Sample event provides good test coverage, including error states.

The test event includes a realistic error scenario (lines 24-41) with error codes and messages, which is excellent for testing error handling. The message structure includes all necessary fields for testing the integration.

components/kustomer/sources/updated-customer-instant/test-event.mjs (1)

1-222: Sample event structure provides comprehensive test data.

Apart from the syntax issue noted above, the test event provides a thorough representation of an updated customer with detailed attributes, contact information, and change tracking. This is valuable for testing the integration.

components/kustomer/actions/update-customer/update-customer.mjs (3)

1-3: Imports look good.


6-153: Comprehensive props configuration.
These prop definitions are consistent with the Kustomer API fields. Great job making them optional unless required.


157-158: Consider using parseFloat if confidence and polarity can be decimal values.
Currently, you are using parseInt(this.sentimentConfidence) and parseInt(this.sentimentPolarity), which will truncate decimal values. If the Kustomer API accepts fractional sentiment confidences (e.g., 0.95), using parseInt may lead to data loss.

Do you want me to generate a quick check or query for the Kustomer API docs regarding whether fractional values are accepted for sentiment confidence?

components/kustomer/kustomer.app.mjs (1)

19-25: Verify pagination logic for listing resources.
Each options method sets page: page + 1 and pageSize: LIMIT * page. When page is 0, pageSize is 0, possibly returning no results for the first page. You might instead do something like (page + 1) * LIMIT for pageSize, or maintain a constant limit regardless of the page to retrieve consistent results.

Do you want me to generate a script to call these endpoints with different page values to confirm that you get the expected data?

Also applies to: 39-52, 58-71, 78-91, 97-109, 115-128

@luancazarine
Copy link
Collaborator Author

/approve

@luancazarine luancazarine merged commit b6e4ac2 into master Mar 25, 2025
11 checks passed
@luancazarine luancazarine deleted the issue-15920 branch March 25, 2025 17:35
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
ai-assisted Content generated by AI, with human refinement and modification
Projects
None yet
Development

Successfully merging this pull request may close these issues.

[Components] kustomer
2 participants