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

Hubspot updates - Leads and Custom Objects #14686

Open
wants to merge 6 commits into
base: master
Choose a base branch
from
Open

Conversation

michelle0927
Copy link
Collaborator

@michelle0927 michelle0927 commented Nov 19, 2024

Resolves #14677

Summary by CodeRabbit

Release Notes

  • New Features

    • Introduced new modules for creating and updating custom objects and leads in HubSpot.
    • Enhanced search functionality to include leads and custom objects.
    • Added associationType property for better engagement management.
    • New updateIfExists property for contact creation to allow updates on creation failure.
    • New newOnly property for line items and products to filter events.
  • Bug Fixes

    • Various version updates across components to ensure consistency and reliability.
  • Documentation

    • Improved property labels and descriptions for clarity in several modules.
  • Chores

    • Incremented version numbers for multiple components to reflect updates.

Copy link

vercel bot commented Nov 19, 2024

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 Nov 22, 2024 8:02pm
pipedream-docs ⬜️ Ignored (Inspect) Nov 22, 2024 8:02pm
pipedream-docs-redirect-do-not-edit ⬜️ Ignored (Inspect) Nov 22, 2024 8:02pm

Copy link
Contributor

coderabbitai bot commented Nov 19, 2024

Walkthrough

This pull request includes multiple updates primarily focused on incrementing version numbers across various HubSpot action modules and sources. The changes span a wide range of components, including those for creating, updating, and managing custom objects and leads. Additionally, new properties and methods have been introduced in some modules to enhance functionality, while others have seen no changes beyond version updates.

Changes

File Path Change Summary
components/hubspot/actions/add-contact-to-list/add-contact-to-list.mjs Version updated from "0.0.9" to "0.0.10".
components/hubspot/actions/batch-create-or-update-contact/batch-create-or-update-contact.mjs Version updated from "0.0.6" to "0.0.7".
components/hubspot/actions/common/common-create-object.mjs Added property propertyGroups and method createObject.
components/hubspot/actions/common/common-update-object.mjs Added property propertyGroups and method isRelevantProperty.
components/hubspot/actions/create-associations/create-associations.mjs Version updated from "0.0.9" to "0.0.10" and added method getAssociationCategory.
components/hubspot/actions/create-communication/create-communication.mjs Version updated from "0.0.1" to "0.0.2".
components/hubspot/actions/create-company/create-company.mjs Version updated from "0.0.12" to "0.0.13".
components/hubspot/actions/create-custom-object/create-custom-object.mjs New module introduced for creating custom objects.
components/hubspot/actions/create-deal/create-deal.mjs Version updated from "0.0.12" to "0.0.13".
components/hubspot/actions/create-engagement/create-engagement.mjs Version updated from "0.0.11" to "0.0.12" and added property associationType.
components/hubspot/actions/create-lead/create-lead.mjs New module introduced for creating leads.
components/hubspot/actions/create-or-update-contact/create-or-update-contact.mjs Added property updateIfExists and version updated from "0.0.10" to "0.0.11".
components/hubspot/actions/create-ticket/create-ticket.mjs Version updated from "0.0.3" to "0.0.4".
components/hubspot/actions/enroll-contact-into-workflow/enroll-contact-into-workflow.mjs Version updated from "0.0.9" to "0.0.10".
components/hubspot/actions/get-company/get-company.mjs Version updated from "0.0.9" to "0.0.10".
components/hubspot/actions/get-contact/get-contact.mjs Version updated from "0.0.9" to "0.0.10" and updated objectId property with label/description.
components/hubspot/actions/get-deal/get-deal.mjs Version updated from "0.0.9" to "0.0.10" and updated objectId property with label/description.
components/hubspot/actions/get-file-public-url/get-file-public-url.mjs Version updated from "0.0.9" to "0.0.10".
components/hubspot/actions/search-crm/search-crm.mjs Added property customObjectType and method getCustomObjectTypes(), version updated from "0.0.7" to "0.0.8".
components/hubspot/actions/update-company/update-company.mjs Version updated from "0.0.8" to "0.0.9".
components/hubspot/actions/update-contact/update-contact.mjs Version updated from "0.0.9" to "0.0.10".
components/hubspot/actions/update-custom-object/update-custom-object.mjs New module introduced for updating custom objects.
components/hubspot/actions/update-lead/update-lead.mjs New module introduced for updating leads.
components/hubspot/common/constants.mjs Removed SEARCHABLE_OBJECT_PROPERTIES, added DEFAULT_LEAD_PROPERTIES.
components/hubspot/common/object-types.mjs Added LEAD to OBJECT_TYPE and updated OBJECT_TYPES array.
components/hubspot/hubspot.app.mjs Added properties leadId and customObjectType, updated objectType to accept includeCustom.
components/hubspot/package.json Version updated from "0.9.0" to "0.10.0".
components/hubspot/sources/delete-blog-article/delete-blog-article.mjs Version updated from "0.0.14" to "0.0.15".
components/hubspot/sources/new-company-property-change/new-company-property-change.mjs Version updated from "0.0.7" to "0.0.8".
components/hubspot/sources/new-contact-property-change/new-contact-property-change.mjs Version updated from "0.0.9" to "0.0.10".
components/hubspot/sources/new-deal-in-stage/new-deal-in-stage.mjs Version updated from "0.0.18" to "0.0.19".
components/hubspot/sources/new-deal-property-change/new-deal-property-change.mjs Version updated from "0.0.8" to "0.0.9".
components/hubspot/sources/new-email-event/new-email-event.mjs Version updated from "0.0.17" to "0.0.18".
components/hubspot/sources/new-email-subscriptions-timeline/new-email-subscriptions-timeline.mjs Version updated from "0.0.14" to "0.0.15".
components/hubspot/sources/new-engagement/new-engagement.mjs Version updated from "0.0.19" to "0.0.20".
components/hubspot/sources/new-event/new-event.mjs Version updated from "0.0.18" to "0.0.19".
components/hubspot/sources/new-form-submission/new-form-submission.mjs Version updated from "0.0.19" to "0.0.20".
components/hubspot/sources/new-or-updated-blog-article/new-or-updated-blog-article.mjs Version updated from "0.0.1" to "0.0.2".
components/hubspot/sources/new-or-updated-company/new-or-updated-company.mjs Version updated from "0.0.1" to "0.0.2".
components/hubspot/sources/new-or-updated-contact/new-or-updated-contact.mjs Version updated from "0.0.1" to "0.0.2".
components/hubspot/sources/new-or-updated-crm-object/new-or-updated-crm-object.mjs Version updated from "0.0.14" to "0.0.15".
components/hubspot/sources/new-or-updated-custom-object/new-or-updated-custom-object.mjs Version updated from "0.0.3" to "0.0.4".
components/hubspot/sources/new-or-updated-deal/new-or-updated-deal.mjs Version updated from "0.0.1" to "0.0.2".
components/hubspot/sources/new-or-updated-line-item/new-or-updated-line-item.mjs Version updated from "0.0.1" to "0.0.2" and added property newOnly.
components/hubspot/sources/new-or-updated-product/new-or-updated-product.mjs Version updated from "0.0.1" to "0.0.2" and added property newOnly.
components/hubspot/sources/new-social-media-message/new-social-media-message.mjs Version updated from "0.0.14" to "0.0.15".
components/hubspot/sources/new-ticket-property-change/new-ticket-property-change.mjs Version updated from "0.0.7" to "0.0.8".
components/hubspot/sources/new-ticket/new-ticket.mjs Version updated from "0.0.14" to "0.0.15".
components/hubspot/actions/common/common-create.mjs Updated makePropDefinition and additionalProps to be asynchronous.

Assessment against linked issues

Objective Addressed Explanation
Add support for Custom Objects and Leads in Search CRM action. The changes do not address this objective.
Add support for Custom Objects and Leads in Create Association action. The changes do not address this objective.

Possibly related PRs

Poem

🐰 In the land of code, we hop and play,
With versions updated, we cheer hooray!
Custom objects and leads, oh what a sight,
In HubSpot's garden, everything feels right.
So let’s celebrate with a joyful tune,
For every new change, we’ll dance 'neath the moon! 🌙


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

🧹 Outside diff range and nitpick comments (19)
components/hubspot/actions/search-crm/search-crm.mjs (1)

58-58: Consider renaming objectType variable for clarity

Assigning const objectType = this.customObjectType ?? this.objectType; may cause confusion with this.objectType. Consider renaming the variable to resolvedObjectType for better clarity.

Apply this diff to rename the variable:

- const objectType = this.customObjectType ?? this.objectType;
+ const resolvedObjectType = this.customObjectType ?? this.objectType;

And update subsequent references to objectType in this scope:

- const schema = await this.hubspot.getSchema({
-   objectType,
+ const schema = await this.hubspot.getSchema({
+   objectType: resolvedObjectType,
components/hubspot/actions/update-lead/update-lead.mjs (1)

1-28: Consider adding error handling documentation

While the implementation is clean and follows the common pattern, it would be beneficial to document potential error scenarios and their handling in the component description. This could include:

  • Invalid lead ID scenarios
  • API rate limiting
  • Permission issues
  • Common error responses

This would improve the component's maintainability and user experience.

components/hubspot/actions/create-or-update-contact/create-or-update-contact.mjs (1)

Line range hint 1-24: Consider enhancing error handling documentation

While the new updateIfExists property adds flexibility in handling creation errors, it would be beneficial to document specific error scenarios in the component's description.

Apply this diff to enhance the documentation:

   description: "Create or update a contact in Hubspot. [See the documentation](https://developers.hubspot.com/docs/api/crm/contacts#endpoint?spec=POST-/crm/v3/objects/contacts)",
+  description: "Create or update a contact in Hubspot. If a contact already exists and 'Update If Exists' is enabled, the contact will be updated instead of returning an error. [See the documentation](https://developers.hubspot.com/docs/api/crm/contacts#endpoint?spec=POST-/crm/v3/objects/contacts)",
components/hubspot/actions/create-custom-object/create-custom-object.mjs (2)

4-10: Consider updating to stable API documentation link

The description links to beta documentation. While this is helpful, it might be better to link to the stable API documentation if available, as beta endpoints might change.


1-27: Consider adding rate limiting and error handling documentation

Since this component interacts with HubSpot's API:

  1. Document any rate limiting considerations
  2. Add error handling examples in the description
  3. Consider adding retry logic for transient failures

This will help users implement the component more effectively in their workflows.

components/hubspot/actions/update-custom-object/update-custom-object.mjs (1)

17-36: Consider adding validation for customObjectType selection

The objectId prop depends on customObjectType, but there's no explicit validation to ensure customObjectType is selected first.

Consider adding validation in the objectId prop definition:

 objectId: {
   propDefinition: [
     hubspot,
     "objectId",
     (c) => ({
+      if (!c.customObjectType) {
+        throw new Error("Please select a Custom Object Type first");
+      }
       objectType: c.customObjectType,
     }),
   ],
   description: "The ID of the custom object",
 },
components/hubspot/actions/create-lead/create-lead.mjs (1)

14-28: Use OBJECT_TYPE constant for consistency

For better maintainability and consistency, consider using the OBJECT_TYPE constant instead of the hardcoded string "contact".

  objectType: "contact",
+  objectType: OBJECT_TYPE.CONTACT,
components/hubspot/actions/common/common-update-object.mjs (4)

Line range hint 6-19: Add error handling for the HubSpot API call

While the propertyGroups implementation is good, it should include error handling for the API call to ensure graceful failure and better debugging.

Consider wrapping the API call in a try-catch block:

     async options() {
+      try {
         const { results: groups } = await this.hubspot.getPropertyGroups({
           objectType: this.getObjectType(),
         });
         return groups.map((group) => ({
           label: group.label,
           value: group.name,
         }));
+      } catch (error) {
+        console.error('Failed to fetch property groups:', error);
+        return [];
+      }
     },

Line range hint 22-26: Enhance method documentation and null safety

The isRelevantProperty method combines multiple conditions but lacks documentation explaining its purpose and requirements.

Consider adding JSDoc and improving null safety:

+    /**
+     * Determines if a property is relevant based on common criteria and property groups
+     * @param {Object} property - The property to check
+     * @returns {boolean} - True if the property is relevant
+     */
     isRelevantProperty(property) {
-      const isInPropertyGroups = this.propertyGroups?.includes(property.groupName);
+      const isInPropertyGroups = Array.isArray(this.propertyGroups) && 
+        this.propertyGroups.includes(property.groupName);
       return common.methods.isRelevantProperty(property) && isInPropertyGroups;
     },

Line range hint 42-49: Consider adding input validation for array properties

While the array to string conversion is correct, adding validation for the array values would make the code more robust.

Consider adding validation:

     Object.keys(properties)
       .forEach((key) => {
         let value = properties[key];
         if (Array.isArray(value)) {
+          // Validate array values
+          if (value.some(item => item?.includes(";"))) {
+            throw new Error(`Array values cannot contain semicolons: ${key}`);
+          }
           properties[key] = value.join(";");
         }
       });

Line range hint 51-61: Add error handling for the update operation

The update operation should include error handling to provide better feedback when updates fail.

Consider adding try-catch and validation:

+    if (!objectId) {
+      throw new Error("Object ID is required for updates");
+    }
+
+    try {
       const response = await hubspot.updateObject({
         objectType,
         objectId,
         data: {
           properties,
         },
       });
       const objectName = hubspot.getObjectTypeName(objectType);
 
       $.export("$summary", `Successfully updated ${objectName}`);
       return response;
+    } catch (error) {
+      throw new Error(`Failed to update ${hubspot.getObjectTypeName(objectType)}: ${error.message}`);
+    }
components/hubspot/actions/common/common-create-object.mjs (3)

Line range hint 8-19: Add error handling to propertyGroups options

The async options method should include error handling to gracefully handle API failures and provide meaningful feedback to users.

Consider implementing error handling:

 propertyGroups: {
   type: "string[]",
   label: "Property Groups",
   reloadProps: true,
   async options() {
+    try {
       const { results: groups } = await this.hubspot.getPropertyGroups({
         objectType: this.getObjectType(),
       });
       return groups.map((group) => ({
         label: group.label,
         value: group.name,
       }));
+    } catch (error) {
+      console.error('Failed to fetch property groups:', error);
+      return [];
+    }
   },
 },

36-38: Enhance createObject method with validation and documentation

The current implementation is a thin wrapper that could benefit from additional functionality and documentation.

Consider enhancing the method:

+  /**
+   * Creates a HubSpot object with validation
+   * @param {Object} opts - The options for creating the object
+   * @param {Object} opts.$ - The Pipedream event object
+   * @param {string} opts.objectType - The type of object to create
+   * @param {Object} opts.data - The object data
+   * @returns {Promise<Object>} The created object
+   */
   createObject(opts = {}) {
+    if (!opts.objectType) {
+      throw new Error('objectType is required');
+    }
+    if (!opts.data?.properties) {
+      throw new Error('data.properties is required');
+    }
     return this.hubspot.createObject(opts);
   },

Line range hint 62-89: Consider enhancing error handling specificity

While the error handling for conflicts is good, it could be more specific in identifying the type of error and providing better error messages.

Consider these improvements:

       return response;
     } catch (err) {
       if (updateIfExists && err?.message) {
-        const errorObj = JSON.parse(err?.message);
+        let errorObj;
+        try {
+          errorObj = JSON.parse(err?.message);
+        } catch (parseError) {
+          throw new Error(`Failed to parse error message: ${err.message}`);
+        }
         if (errorObj?.category === "CONFLICT" || errorObj?.category === "OBJECT_ALREADY_EXISTS") {
           const objectId = parseInt(errorObj.message.replace(/[^\d]/g, ""));
+          if (isNaN(objectId)) {
+            throw new Error(`Failed to extract object ID from error message: ${errorObj.message}`);
+          }
           const response = await hubspot.updateObject({
             $,
             objectType,
             objectId,
             data: {
               properties,
             },
           });
           const objectName = hubspot.getObjectTypeName(objectType);
           $.export("$summary", `Successfully updated ${objectName}`);
           return response;
         }
       }
+      // Enhance error message with more context
+      const errorMessage = err?.message 
+        ? `Failed to create/update object: ${err.message}`
+        : 'Failed to create/update object: Unknown error';
+      throw new Error(errorMessage);
-      throw err;
     }
components/hubspot/actions/create-engagement/create-engagement.mjs (3)

Line range hint 44-54: Update property description to be more generic

The associationType description specifically mentions "task", but this property appears to be used for all engagement types, not just tasks.

-      description: "A unique identifier to indicate the association type between the task and the other object",
+      description: "A unique identifier to indicate the association type between the engagement and the associated object",

Line range hint 91-93: Enhance error message clarity

The current error message could be more descriptive about the relationship between these fields.

-      throw new ConfigurationError("Both `toObjectId` and `associationType` must be entered");
+      throw new ConfigurationError("When creating an association, both `toObjectId` and `associationType` must be provided. Either provide both fields or omit both.");

Line range hint 111-113: Consider extracting task-specific date parsing

The task reminder date parsing is mixed with general engagement creation logic. Consider extracting this into a task-specific method for better separation of concerns.

+    methods: {
+      ...common.methods,
+      parseTaskProperties(properties) {
+        if (properties.hs_task_reminders) {
+          properties.hs_task_reminders = Date.parse(properties.hs_task_reminders);
+        }
+        return properties;
+      },
+    },
     async run({ $ }) {
       // ... existing code ...
-      if (properties.hs_task_reminders) {
-        properties.hs_task_reminders = Date.parse(properties.hs_task_reminders);
+      if (objectType === 'task') {
+        properties = this.parseTaskProperties(properties);
       }
components/hubspot/sources/new-ticket-property-change/new-ticket-property-change.mjs (1)

10-10: Remove redundant commented version number

The line contains both commented and uncommented versions showing the same number. This redundancy could lead to confusion in future updates.

-  //version: "0.0.8",
   version: "0.0.8",
components/hubspot/hubspot.app.mjs (1)

415-430: Consider enhancing lead selection with additional properties

While the implementation is functional, consider adding more identifying properties beyond just hs_lead_name to help users better identify leads, especially when the name is not set.

 const { results } = await this.listObjectsInPage("lead", undefined, {
-  properties: "hs_lead_name",
+  properties: [
+    "hs_lead_name",
+    "hs_lead_status",
+    "hs_lead_source",
+    "email"
+  ].join(","),
 });
 return results?.map(({
   id: value, properties,
 }) => ({
   value,
-  label: properties?.hs_lead_name || value,
+  label: properties?.hs_lead_name
+    ? `${properties.hs_lead_name} (${properties.hs_lead_status || 'No Status'})`
+    : `Lead ${value} (${properties.email || 'No Email'})`,
 })) || [];
📜 Review details

Configuration used: CodeRabbit UI
Review profile: CHILL

📥 Commits

Reviewing files that changed from the base of the PR and between 9cbf1c2 and 7be67fe.

⛔ Files ignored due to path filters (1)
  • pnpm-lock.yaml is excluded by !**/pnpm-lock.yaml
📒 Files selected for processing (48)
  • components/hubspot/actions/add-contact-to-list/add-contact-to-list.mjs (1 hunks)
  • components/hubspot/actions/batch-create-or-update-contact/batch-create-or-update-contact.mjs (1 hunks)
  • components/hubspot/actions/common/common-create-object.mjs (2 hunks)
  • components/hubspot/actions/common/common-update-object.mjs (1 hunks)
  • components/hubspot/actions/create-associations/create-associations.mjs (5 hunks)
  • components/hubspot/actions/create-communication/create-communication.mjs (1 hunks)
  • components/hubspot/actions/create-company/create-company.mjs (1 hunks)
  • components/hubspot/actions/create-custom-object/create-custom-object.mjs (1 hunks)
  • components/hubspot/actions/create-deal/create-deal.mjs (1 hunks)
  • components/hubspot/actions/create-engagement/create-engagement.mjs (1 hunks)
  • components/hubspot/actions/create-lead/create-lead.mjs (1 hunks)
  • components/hubspot/actions/create-or-update-contact/create-or-update-contact.mjs (1 hunks)
  • components/hubspot/actions/create-ticket/create-ticket.mjs (1 hunks)
  • components/hubspot/actions/enroll-contact-into-workflow/enroll-contact-into-workflow.mjs (1 hunks)
  • components/hubspot/actions/get-company/get-company.mjs (1 hunks)
  • components/hubspot/actions/get-contact/get-contact.mjs (1 hunks)
  • components/hubspot/actions/get-deal/get-deal.mjs (1 hunks)
  • components/hubspot/actions/get-file-public-url/get-file-public-url.mjs (1 hunks)
  • components/hubspot/actions/search-crm/search-crm.mjs (6 hunks)
  • components/hubspot/actions/update-company/update-company.mjs (1 hunks)
  • components/hubspot/actions/update-contact/update-contact.mjs (1 hunks)
  • components/hubspot/actions/update-custom-object/update-custom-object.mjs (1 hunks)
  • components/hubspot/actions/update-lead/update-lead.mjs (1 hunks)
  • components/hubspot/common/constants.mjs (2 hunks)
  • components/hubspot/common/object-types.mjs (3 hunks)
  • components/hubspot/hubspot.app.mjs (3 hunks)
  • components/hubspot/package.json (1 hunks)
  • components/hubspot/sources/delete-blog-article/delete-blog-article.mjs (1 hunks)
  • components/hubspot/sources/new-company-property-change/new-company-property-change.mjs (1 hunks)
  • components/hubspot/sources/new-contact-property-change/new-contact-property-change.mjs (1 hunks)
  • components/hubspot/sources/new-deal-in-stage/new-deal-in-stage.mjs (1 hunks)
  • components/hubspot/sources/new-deal-property-change/new-deal-property-change.mjs (1 hunks)
  • components/hubspot/sources/new-email-event/new-email-event.mjs (1 hunks)
  • components/hubspot/sources/new-email-subscriptions-timeline/new-email-subscriptions-timeline.mjs (1 hunks)
  • components/hubspot/sources/new-engagement/new-engagement.mjs (1 hunks)
  • components/hubspot/sources/new-event/new-event.mjs (1 hunks)
  • components/hubspot/sources/new-form-submission/new-form-submission.mjs (1 hunks)
  • components/hubspot/sources/new-or-updated-blog-article/new-or-updated-blog-article.mjs (1 hunks)
  • components/hubspot/sources/new-or-updated-company/new-or-updated-company.mjs (1 hunks)
  • components/hubspot/sources/new-or-updated-contact/new-or-updated-contact.mjs (1 hunks)
  • components/hubspot/sources/new-or-updated-crm-object/new-or-updated-crm-object.mjs (1 hunks)
  • components/hubspot/sources/new-or-updated-custom-object/new-or-updated-custom-object.mjs (1 hunks)
  • components/hubspot/sources/new-or-updated-deal/new-or-updated-deal.mjs (1 hunks)
  • components/hubspot/sources/new-or-updated-line-item/new-or-updated-line-item.mjs (1 hunks)
  • components/hubspot/sources/new-or-updated-product/new-or-updated-product.mjs (1 hunks)
  • components/hubspot/sources/new-social-media-message/new-social-media-message.mjs (1 hunks)
  • components/hubspot/sources/new-ticket-property-change/new-ticket-property-change.mjs (1 hunks)
  • components/hubspot/sources/new-ticket/new-ticket.mjs (1 hunks)
✅ Files skipped from review due to trivial changes (32)
  • components/hubspot/actions/add-contact-to-list/add-contact-to-list.mjs
  • components/hubspot/actions/batch-create-or-update-contact/batch-create-or-update-contact.mjs
  • components/hubspot/actions/create-communication/create-communication.mjs
  • components/hubspot/actions/create-company/create-company.mjs
  • components/hubspot/actions/create-deal/create-deal.mjs
  • components/hubspot/actions/create-ticket/create-ticket.mjs
  • components/hubspot/actions/enroll-contact-into-workflow/enroll-contact-into-workflow.mjs
  • components/hubspot/actions/get-company/get-company.mjs
  • components/hubspot/actions/get-deal/get-deal.mjs
  • components/hubspot/actions/get-file-public-url/get-file-public-url.mjs
  • components/hubspot/actions/update-company/update-company.mjs
  • components/hubspot/actions/update-contact/update-contact.mjs
  • components/hubspot/package.json
  • components/hubspot/sources/delete-blog-article/delete-blog-article.mjs
  • components/hubspot/sources/new-company-property-change/new-company-property-change.mjs
  • components/hubspot/sources/new-contact-property-change/new-contact-property-change.mjs
  • components/hubspot/sources/new-deal-in-stage/new-deal-in-stage.mjs
  • components/hubspot/sources/new-deal-property-change/new-deal-property-change.mjs
  • components/hubspot/sources/new-email-event/new-email-event.mjs
  • components/hubspot/sources/new-email-subscriptions-timeline/new-email-subscriptions-timeline.mjs
  • components/hubspot/sources/new-engagement/new-engagement.mjs
  • components/hubspot/sources/new-event/new-event.mjs
  • components/hubspot/sources/new-form-submission/new-form-submission.mjs
  • components/hubspot/sources/new-or-updated-blog-article/new-or-updated-blog-article.mjs
  • components/hubspot/sources/new-or-updated-company/new-or-updated-company.mjs
  • components/hubspot/sources/new-or-updated-contact/new-or-updated-contact.mjs
  • components/hubspot/sources/new-or-updated-crm-object/new-or-updated-crm-object.mjs
  • components/hubspot/sources/new-or-updated-custom-object/new-or-updated-custom-object.mjs
  • components/hubspot/sources/new-or-updated-deal/new-or-updated-deal.mjs
  • components/hubspot/sources/new-or-updated-product/new-or-updated-product.mjs
  • components/hubspot/sources/new-social-media-message/new-social-media-message.mjs
  • components/hubspot/sources/new-ticket/new-ticket.mjs
🔇 Additional comments (56)
components/hubspot/actions/search-crm/search-crm.mjs (17)

10-10: Import DEFAULT_LEAD_PROPERTIES

The import statement correctly includes DEFAULT_LEAD_PROPERTIES to support lead properties.


17-17: Update description to include leads and custom objects

The description now accurately reflects the added support for leads and custom objects.


18-18: Increment version number to 0.0.8

Version number updated appropriately for the new changes.


26-32: Add "Custom Object" to object type options

The objectType options now include "Custom Object", allowing users to select and search custom objects.


46-53: Add customObjectType prop for custom objects

The additionalProps method correctly adds a customObjectType prop when objectType is "custom_object", enabling users to select the specific custom object type.


54-56: Ensure early return when required properties are missing

The condition checks if necessary properties are set before proceeding, preventing potential errors.


59-61: Fetch schema for resolved object type

Fetching the schema using the resolved object type ensures correct properties are retrieved.


67-67: Set searchProperty options from schema's searchable properties

Provides users with the correct searchable properties based on the selected object type.


92-92: Fetch properties for resolved object type in additionalProperties

Ensures that additionalProperties options correspond to the correct object type.


103-103: Conditionally generate creation properties based on createIfNotFound and object type

Appropriately checks conditions before generating properties for object creation.


105-105: Use resolved object type when fetching properties for creation

Ensures properties fetched for object creation match the correct object type.


137-138: Support lead object type in getDefaultProperties

Includes default properties for leads, enhancing functionality for lead management.


143-146: Implement getCustomObjectTypes method

The method correctly retrieves custom object types from HubSpot schemas.


152-152: Destructure customObjectType in run method

Ensures customObjectType is accessible within the run method.


177-177: Use resolved object type in searchCRM call

Passing customObjectType ?? objectType ensures the correct object type is used when searching.


185-185: Use resolved object type when creating object

Ensures the object is created with the correct type.


190-190: Use resolved object type when exporting summary message

Retrieves the object name based on the resolved object type for accurate summary output.

components/hubspot/actions/get-contact/get-contact.mjs (3)

Line range hint 13-17: LGTM! Documentation improvements enhance clarity.

The added label and description for the objectId property provide clear context for users.


9-9: Verify version consistency across HubSpot components.

The version bump to "0.0.10" looks good, but let's ensure consistency across related components.

✅ Verification successful

Version update is consistent with related components

The version bump to "0.0.10" in get-contact.mjs is consistent with several other related action components in the HubSpot integration:

  • add-contact-to-list: 0.0.10
  • create-associations: 0.0.10
  • enroll-contact-into-workflow: 0.0.10
  • get-company: 0.0.10
  • get-deal: 0.0.10
  • get-file-public-url: 0.0.10
  • update-contact: 0.0.10
🏁 Scripts executed

The following scripts were executed for the analysis:

Script:

#!/bin/bash
# Description: Check version numbers across HubSpot components to ensure consistency
# Expected: All related components should have the same version number

echo "Checking version numbers in HubSpot components..."
rg -g "components/hubspot/**/*.{mjs,js}" 'version: "0.0.' -A 1

Length of output: 8018


Line range hint 1-24: Verify alignment with PR objectives.

While the documentation improvements are valuable, this component's changes appear to be primarily version and documentation updates. The PR objectives mention implementing custom objects and leads functionality, but this file doesn't contain such changes. Please confirm if additional changes are needed to support the custom objects and leads requirements outlined in issue #14677.

✅ Verification successful

Changes align with PR objectives - custom objects and leads functionality exists

The changes in this file are part of a broader implementation that includes both custom objects and leads functionality. The search results confirm:

  • Custom objects implementation exists across multiple files including create, update, and search actions
  • Leads functionality is implemented with dedicated actions (update-lead, create-lead) and proper object type support

The version bump and documentation updates in this file are appropriate as part of the overall PR changes.

🏁 Scripts executed

The following scripts were executed for the analysis:

Script:

#!/bin/bash
# Description: Search for custom objects and leads related changes
# Expected: Find implementations related to PR objectives

echo "Searching for custom objects implementation..."
rg -g "components/hubspot/**/*.{mjs,js}" -i "custom.?object"

echo "Searching for leads implementation..."
rg -g "components/hubspot/**/*.{mjs,js}" -i "\.leads?\b|lead.?object"

Length of output: 5147

components/hubspot/actions/update-lead/update-lead.mjs (4)

1-3: Clean and well-structured imports

The imports follow ES module patterns and clearly define dependencies.


5-11: Verify the beta documentation link

The component references beta documentation. Please verify if there's a stable API documentation link available, as beta endpoints might change.

✅ Verification successful

The previous curl showed the URL is accessible but we need to verify if there's a stable API documentation being used elsewhere in the codebase to suggest a better alternative.


The previous searches didn't yield results, so let's try a broader search to understand the documentation patterns used in other HubSpot components.


Documentation link is valid and appropriate

The beta documentation link is correct and accessible. The codebase shows consistent usage of HubSpot's CRM v3 API (CRMV3) for lead-related operations, and the provided beta documentation aligns with this version. Since leads are part of HubSpot's CRM objects API, and the component is using the latest API version, the current documentation reference is appropriate.

🏁 Scripts executed

The following scripts were executed for the analysis:

Script:

#!/bin/bash
# Check if the documentation URL is accessible and if there's a stable version
curl -I "https://developers.hubspot.com/beta-docs/guides/api/crm/objects/leads"

# Search for any stable documentation references in the codebase
rg -l "developers\.hubspot\.com/docs" --type js

Length of output: 3635


Script:

#!/bin/bash
# Let's search for the current stable API documentation references in the codebase
rg "https://developers\.hubspot\.com/docs/api/crm/objects" -l

# Also search for any other HubSpot lead-related documentation references
rg "hubspot.*lead.*documentation" -A 2 -B 2

# Check other HubSpot components for documentation patterns
fd -e mjs -e js hubspot --exec grep -l "documentation" {}

Length of output: 169


Script:

#!/bin/bash
# Let's check other HubSpot components for their documentation patterns
fd hubspot -e mjs -t f | xargs cat | grep -B 2 -A 2 "documentation"

# Also check specifically for any CRM-related documentation
fd hubspot -e mjs -t f | xargs cat | grep -B 2 -A 2 "crm"

# Look for any other HubSpot API version references
fd hubspot -e mjs -t f | xargs cat | grep -B 2 -A 2 "api"

Length of output: 6646


18-27: Verify leadId propDefinition in hubspot app

The component uses the leadId propDefinition from the hubspot app. Let's verify this definition exists and is properly implemented.

✅ Verification successful

Let's try a broader search to locate the propDefinition and understand its implementation. The previous pattern might have been too strict, so we're:

  1. Using a more flexible AST pattern
  2. Using ripgrep with context
  3. Directly examining the hubspot app file where prop definitions are typically defined

leadId propDefinition exists and is properly implemented

The leadId propDefinition is correctly defined in the hubspot app with:

  • Proper type definition as string
  • Clear label "Lead ID"
  • Description "The identifier of the lead"
  • Async options function that fetches lead data from the HubSpot API
🏁 Scripts executed

The following scripts were executed for the analysis:

Script:

#!/bin/bash
# Search for leadId propDefinition in hubspot app
ast-grep --pattern 'leadId: {
  $$$
}'

# Check for other components using this propDefinition
rg '"leadId"' --type js

Length of output: 66


Script:

#!/bin/bash
# Search for leadId in app definition with more flexible pattern
ast-grep --pattern 'leadId: $_'

# Search for leadId in prop definitions with context
rg 'leadId' -A 5 -B 5 --type js

# Search specifically in the hubspot app directory
fd hubspot.app.mjs -x cat {}

Length of output: 25711


12-17: Verify OBJECT_TYPE.LEAD constant usage

The method returns OBJECT_TYPE.LEAD. Let's ensure this constant is properly defined and consistently used across the codebase.

✅ Verification successful

OBJECT_TYPE.LEAD constant is properly defined and used correctly

The constant is correctly defined in components/hubspot/common/object-types.mjs as LEAD: "lead" and is properly imported and used in the update-lead component. The constant is also consistently used across the codebase as it's part of both OBJECT_TYPES and SEARCHABLE_OBJECT_TYPES_ARRAY.

🏁 Scripts executed

The following scripts were executed for the analysis:

Script:

#!/bin/bash
# Check the definition and usage of OBJECT_TYPE.LEAD
ast-grep --pattern 'OBJECT_TYPE = {
  $$$
  LEAD: $_,
  $$$
}'

# Check for consistent usage of OBJECT_TYPE.LEAD
rg "OBJECT_TYPE\.LEAD" --type js

Length of output: 99


Script:

#!/bin/bash
# Let's first find where OBJECT_TYPE is defined
rg "OBJECT_TYPE\s*=\s*" --type js -A 5

# Also search for any import of OBJECT_TYPE
rg "import.*OBJECT_TYPE" --type js

# Search for any export of OBJECT_TYPE
rg "export.*OBJECT_TYPE" --type js

Length of output: 114


Script:

#!/bin/bash
# Let's try to find the file by looking for .mjs files in the components/hubspot directory
fd "\.mjs$" components/hubspot

# Let's also check for any constants or types files in the hubspot component
fd "constants|types" components/hubspot

# And check the content of the update-lead.mjs file to see the imports
cat components/hubspot/actions/update-lead/update-lead.mjs

Length of output: 5687


Script:

#!/bin/bash
# Let's check the content of the constants.mjs file where OBJECT_TYPE is imported from
cat components/hubspot/common/constants.mjs

Length of output: 3887


Script:

#!/bin/bash
# Let's check the content of object-types.mjs where OBJECT_TYPE is defined
cat components/hubspot/common/object-types.mjs

Length of output: 2869

components/hubspot/actions/create-or-update-contact/create-or-update-contact.mjs (2)

9-9: LGTM: Version increment is appropriate

The version bump from 0.0.10 to 0.0.11 aligns with the addition of new functionality.


Line range hint 13-17: Verify the implementation of updateIfExists functionality

The new updateIfExists property is well-documented, but we should verify its implementation in the common base object.

✅ Verification successful

Based on the results, I can generate the final response as we have clear evidence of the implementation.

The updateIfExists functionality is properly implemented in the common base object

The implementation in common-create-object.mjs shows correct error handling and update logic:

  • Checks for specific error categories (CONFLICT or OBJECT_ALREADY_EXISTS)
  • Extracts the existing object ID from the error message
  • Performs an update operation using the HubSpot API when appropriate
🏁 Scripts executed

The following scripts were executed for the analysis:

Script:

#!/bin/bash
# Description: Verify the implementation of updateIfExists functionality

# Check the common base object implementation
echo "Checking common-create-object.mjs for updateIfExists handling:"
rg -A 10 "updateIfExists" "components/hubspot/actions/common/common-create-object.mjs"

# Check for similar patterns in other HubSpot components
echo "Checking for similar patterns in other components:"
rg -l "updateIfExists" "components/hubspot/"

# Look for error handling related to object creation
echo "Checking error handling patterns:"
ast-grep --pattern 'catch ($_) {
  $$$
  if ($$.updateIfExists) {
    $$$
  }
}'

Length of output: 1468

components/hubspot/actions/create-custom-object/create-custom-object.mjs (3)

1-3: LGTM! Well-structured imports

The imports are correctly structured using ESM syntax, and the use of a common module promotes code reuse.


11-20: Verify the customObjectType propDefinition implementation

The code references the customObjectType propDefinition from the HubSpot app. Let's verify its implementation.

✅ Verification successful

The customObjectType propDefinition is properly implemented

The verification confirms that the customObjectType propDefinition exists in hubspot.app.mjs with proper implementation:

  • It's defined as a string type with appropriate label and description
  • Includes an async options() method that fetches available schema names from listSchemas()
  • The propDefinition is correctly referenced by multiple components including create-custom-object, update-custom-object, and search-crm actions
🏁 Scripts executed

The following scripts were executed for the analysis:

Script:

#!/bin/bash
# Description: Verify the customObjectType propDefinition exists in hubspot.app.mjs
# and check its implementation details

# Search for the customObjectType propDefinition
ast-grep --pattern 'customObjectType: {
  $$$
}'

# Backup: Use ripgrep if the AST pattern doesn't match
rg -A 10 'customObjectType.*[:=]' 

Length of output: 3683


21-26: Verify the getObjectType method usage

Let's verify how the getObjectType method is utilized in the common module to ensure it meets the requirements for custom object creation.

✅ Verification successful

Let me generate additional scripts to check the common module and HubSpot API integration:

This will help us verify:

  1. The common module being extended
  2. How custom objects are handled in the HubSpot integration
  3. The API calls made for custom object operations

Based on the shell script results, I can now provide a final response:

The getObjectType implementation is correctly integrated with HubSpot's custom object handling

The method implementation is properly integrated with HubSpot's API and common module architecture:

  • It extends the common methods from common-create-object.mjs which provides the base implementation for object creation
  • The method returns this.customObjectType which is used by HubSpot's API to identify the custom object type for creation
  • The property is properly defined in the component's props via HubSpot's propDefinitions
  • The value is used consistently across the codebase for custom object operations including schema validation, property group handling, and API calls
🏁 Scripts executed

The following scripts were executed for the analysis:

Script:

#!/bin/bash
# Description: Check how getObjectType is used in the common module
# and verify its integration with HubSpot's API

# Search for references to getObjectType
rg -A 5 'getObjectType'

# Look for API calls or object creation patterns
ast-grep --pattern 'async $create($$$) {
  $$$
}'

Length of output: 44134


Script:

#!/bin/bash
# Search for common module implementation and API calls
# Look for the common module that's being extended
rg -l "common.*methods" components/hubspot/actions/

# Check the common module's implementation
fd "common" components/hubspot/actions/ -t f -x cat {}

# Look for HubSpot API calls related to custom objects
rg -A 5 "customObject" components/hubspot/

Length of output: 21128

components/hubspot/actions/update-custom-object/update-custom-object.mjs (3)

1-2: LGTM: Imports are correctly defined

The necessary dependencies are properly imported using ES module syntax.


11-16: LGTM: Methods are well-structured

The getObjectType method follows the single responsibility principle and integrates well with the common methods.


4-10: Consider updating the documentation link to stable API docs

The description links to beta documentation (beta-docs). This might become outdated or change unexpectedly.

Let's check if there's a stable version of the documentation:

components/hubspot/actions/create-lead/create-lead.mjs (3)

1-5: LGTM! Well-organized imports

The imports are clean, purposeful, and properly structured, importing only what's needed for the module's functionality.


31-33: LGTM! Clear object type definition

The getObjectType method is clean and uses the appropriate constant.


7-13: Consider using stable documentation links

The description links to beta documentation (beta-docs). While this is currently accurate, beta documentation might change or become deprecated.

Let's check if there's a stable version of the documentation:

Consider updating to the stable documentation URL if available.

✅ Verification successful

Beta documentation is currently the only available source

The beta documentation URL is accessible and returns a 200 status code, while the stable documentation URL returns a 404. This indicates that the API documentation for leads is currently only available in beta, making the current documentation link in the code appropriate.

🏁 Scripts executed

The following scripts were executed for the analysis:

Script:

#!/bin/bash
# Description: Check if the documentation URL is accessible and if there's a stable version
# Note: Using curl with -I for headers only to check both beta and stable URLs

echo "Checking beta docs..."
curl -Is "https://developers.hubspot.com/beta-docs/guides/api/crm/objects/leads"

echo "Checking stable docs..."
curl -Is "https://developers.hubspot.com/docs/api/crm/objects/leads"

Length of output: 5973

components/hubspot/actions/common/common-update-object.mjs (1)

35-35: Verify the necessity of the unused customObjectType parameter

The customObjectType is destructured but marked as unused (eslint-disable). If it's not needed, consider removing it to maintain code clarity.

Let's check if this parameter is used elsewhere in the codebase:

✅ Verification successful

The customObjectType parameter is correctly used and necessary

The parameter is not actually unused. While it's marked with eslint-disable no-unused-vars, it's indirectly used through this.getObjectType() which is called in the implementation. The update-custom-object action extends this common module and provides the implementation of getObjectType() that returns this.customObjectType. This is a valid pattern for shared functionality between regular and custom object updates.

🏁 Scripts executed

The following scripts were executed for the analysis:

Script:

#!/bin/bash
# Search for customObjectType usage in HubSpot components
rg -l 'customObjectType' components/hubspot/

Length of output: 396


Script:

#!/bin/bash
# Check how customObjectType is used in the update-custom-object action
rg -A 5 -B 5 'customObjectType' components/hubspot/actions/update-custom-object/update-custom-object.mjs

# Check the common update object implementation
rg -A 10 -B 10 'customObjectType' components/hubspot/actions/common/common-update-object.mjs

Length of output: 1324


Script:

#!/bin/bash
# Check how getObjectType is implemented in the common update object
rg -A 5 'getObjectType' components/hubspot/actions/common/common-update-object.mjs

# Also check if there are any other references to customObjectType in the implementation
rg -A 5 'customObjectType' components/hubspot/actions/common/common-update-object.mjs

Length of output: 1091

components/hubspot/sources/new-or-updated-line-item/new-or-updated-line-item.mjs (4)

Line range hint 29-36: LGTM! Well-structured property definition

The new newOnly property is well-documented with clear purpose and default value. The boolean type and optional flag are appropriate for this filtering functionality.


Line range hint 55-57: LGTM! Unchanged core functionality

The core functionality in isRelevant, getParams, and processResults remains unchanged, which is appropriate as these methods don't need modification for the new filtering feature.

Also applies to: 58-75, 76-78


12-12: Verify changelog for version 0.0.2

The version bump from 0.0.1 to 0.0.2 aligns with the new functionality added. However, let's ensure this is documented.


Line range hint 39-44: Verify the timestamp handling logic

The modifications to getTs and generateMeta methods look correct, providing consistent handling of the newOnly flag. The changes maintain backward compatibility while adding new functionality.

Also applies to: 45-54

✅ Verification successful

Timestamp handling implementation is correct and consistent

The getTs implementation correctly handles both new and updated line items by:

  • Using createdAt timestamp when newOnly is true
  • Using updatedAt timestamp when newOnly is false

This aligns with the common pattern in the codebase where:

  • The base component defines the interface requiring getTs implementation
  • The timestamp is used consistently in pagination and event processing
  • The test event shows both createdAt and updatedAt fields are available in the line item object
🏁 Scripts executed

The following scripts were executed for the analysis:

Script:

#!/bin/bash
# Check for similar timestamp handling patterns in other HubSpot components
ast-grep --pattern 'getTs($$_) {
  return this.newOnly
    ? Date.parse($$$)
    : Date.parse($$$)
}'

Length of output: 103


Script:

#!/bin/bash
# Let's try a broader search for timestamp handling patterns in HubSpot components
rg -U "getTs.*\{[\s\S]*?Date\.parse" --type js

# Also search for newOnly flag usage
rg "newOnly" --type js -C 3

# And look for similar line item components
fd "line-item" -t f

Length of output: 374


Script:

#!/bin/bash
# Let's examine the content of the line item component and related files
cat components/hubspot/sources/new-or-updated-line-item/new-or-updated-line-item.mjs

# Also check for any common methods that might be imported
rg -l "common\.methods" --type js components/hubspot/

Length of output: 2238


Script:

#!/bin/bash
# Let's check the common methods file to understand the shared functionality
cat components/hubspot/sources/common/common.mjs

# Also check the test event file to see the expected output
cat components/hubspot/sources/new-or-updated-line-item/test-event.mjs

Length of output: 5998

components/hubspot/common/object-types.mjs (5)

20-20: LGTM! Addition of LEAD object type

The addition follows the established pattern and naming conventions, aligning with HubSpot's API documentation.


81-84: LGTM! Addition of Leads to object types list

The new entry maintains consistency with existing entries in terms of structure and formatting.


95-95: Verify search implementation for leads

While adding LEAD to searchable types is correct, we should verify that the search implementation properly handles lead objects.

✅ Verification successful

Let me gather more information about the search implementation.


Let me check the search implementation details in the search-crm action.


Based on the gathered information, I can now provide the final response:

Search implementation for leads is properly configured

The search functionality for leads is correctly implemented with:

  • Default lead properties defined in constants.mjs: email, name, company domain, etc.
  • Search-CRM action properly handles lead objects using the same search mechanism as other object types
  • Default properties are automatically included in search requests
  • The implementation uses HubSpot's standard search API with proper filtering
🏁 Scripts executed

The following scripts were executed for the analysis:

Script:

#!/bin/bash
# Description: Check for lead-related search implementation in the codebase

# Look for lead-specific search handling
rg -l "lead.*search|search.*lead" --type js --type mjs

# Check for any lead-specific properties or fields used in search
ast-grep --pattern 'const $_ = {
  $$$
  lead: $$$
  $$$
}'

Length of output: 1433


Script:

#!/bin/bash
# Search for lead-related search implementation with proper file extensions
rg -l "lead.*search|search.*lead" --type javascript --type typescript

# Look for search implementation files
fd -e js -e mjs -e ts "search" components/hubspot

# Check for lead properties or fields in search-related files
rg -A 5 "LEAD" components/hubspot/

Length of output: 3766


Script:

#!/bin/bash
# Check the search implementation in search-crm action
rg -A 10 "async run" components/hubspot/actions/search-crm/search-crm.mjs

# Look for property handling in search
rg -B 5 -A 10 "getDefaultProperties" components/hubspot/actions/search-crm/search-crm.mjs

# Check if search method handles different object types
ast-grep --pattern 'searchCRM($$$) {
  $$$
}'

Length of output: 2548


Line range hint 1-158: Verify impact of removed SEARCHABLE_OBJECT_PROPERTIES

The AI summary indicates that SEARCHABLE_OBJECT_PROPERTIES was removed. We should verify that this removal doesn't break existing search functionality and that these properties are defined elsewhere.

✅ Verification successful

Let me gather more specific information about the SEARCHABLE_OBJECT_PROPERTIES usage.


Let me try one more search with different parameters to find any search-related configurations in the Hubspot component.


Removal of SEARCHABLE_OBJECT_PROPERTIES is safe

Based on the search results, the removal of SEARCHABLE_OBJECT_PROPERTIES is safe because:

  1. The searchable properties are now obtained dynamically through the Hubspot API's schema endpoint (schema.searchableProperties)
  2. The search functionality is properly maintained through the searchProperty and propertyName fields in the search configurations
  3. Each object type (contacts, companies, deals, etc.) has its own property validation against the API-provided properties
🏁 Scripts executed

The following scripts were executed for the analysis:

Script:

#!/bin/bash
# Description: Check for searchable properties definitions

# Look for any new locations of searchable properties
rg -l "searchable.*properties|SEARCHABLE.*PROPERTIES" --type js --type mjs

# Check for property definitions in other files
ast-grep --pattern 'const $_ = {
  $$$
  properties: $$$
  $$$
}'

Length of output: 12355


Script:

#!/bin/bash
# Search for SEARCHABLE_OBJECT_PROPERTIES references
rg "SEARCHABLE_OBJECT_PROPERTIES" -B 2 -A 2

# Search for any search-related property configurations in Hubspot files
rg "searchableProperties|searchProperty|propertyName" --type js components/hubspot/

Length of output: 129


Script:

#!/bin/bash
# Look for search configurations and property definitions in Hubspot files
rg -A 5 "search.*properties|properties.*search" components/hubspot/

# Check specific files that might contain search configurations
fd -e mjs -e js . components/hubspot/ -x cat {} | grep -A 5 -B 5 "propertyName\|searchProperty"

Length of output: 9189


Line range hint 1-158: Missing custom objects support

While the PR objectives mention adding support for custom objects, this file doesn't include any changes related to custom object types. Consider whether custom object type definitions should be added here.

components/hubspot/actions/create-engagement/create-engagement.mjs (2)

12-12: LGTM: Version increment is appropriate

The minor version bump from 0.0.11 to 0.0.12 correctly reflects the backward-compatible additions of new optional properties and enhanced validation.


Line range hint 95-109: Verify association structure compatibility

The association structure looks correct, but let's verify it works with all supported object types.

components/hubspot/sources/new-ticket-property-change/new-ticket-property-change.mjs (1)

Line range hint 1-116: Verify relevance of this file to PR objectives

This file appears to be included in the PR but doesn't contain any changes related to the stated objectives (Hubspot leads and custom objects functionality). The only change is a version bump.

Consider:

  1. Is this file's inclusion necessary for this PR?
  2. Are there missing changes needed to support the PR objectives?
components/hubspot/actions/create-associations/create-associations.mjs (4)

8-8: LGTM! Version bump is appropriate

The version increment is consistent with the addition of new features for custom object support.


99-105: LGTM! Dynamic association category properly implemented

The update to use a dynamic associationCategory instead of a hardcoded value improves the component's flexibility while maintaining existing functionality.

Also applies to: 120-120


16-18: LGTM! Custom object support properly implemented

The addition of includeCustom: true enables custom object support for both source and target objects, aligning with the PR objectives.

Let's verify the custom object types are properly exposed:

Also applies to: 39-41

✅ Verification successful

Based on the code review, I can now provide a final response since I have found the relevant implementation in the HubSpot app file. The objectType prop definition includes support for custom objects through the includeCustom parameter, which when set to true, fetches and includes custom object schemas from the HubSpot API.

Custom object support properly implemented and verified

The implementation in hubspot.app.mjs confirms that when includeCustom: true is set, the code:

  1. Fetches custom object schemas via listSchemas() API call
  2. Appends the custom objects to the standard object types
  3. Returns the combined list as available options
🏁 Scripts executed

The following scripts were executed for the analysis:

Script:

#!/bin/bash
# Description: Verify that the hubspot.objectType propDefinition supports custom objects
ast-grep --pattern 'propDefinition: [
  hubspot,
  "objectType",
  $$$
]'

Length of output: 75


Script:

#!/bin/bash
# Let's try a different approach to find object type definitions
# First, let's look for the file content
rg -l "objectType" --type js --type mjs

# Then, let's examine the actual implementation
rg "objectType.*includeCustom" -A 5 -B 5 --type js --type mjs

Length of output: 159


Script:

#!/bin/bash
# Let's try without file type restrictions since mjs is not recognized
# First check the file content
rg -l "objectType"

# Then look for the implementation details
rg "objectType.*includeCustom" -A 5 -B 5

Length of output: 3803


Script:

#!/bin/bash
# Let's examine the hubspot app file for object type definitions
cat components/hubspot/hubspot.app.mjs

# And also check the common files that might contain the object type implementation
cat components/hubspot/actions/common/common-create-object.mjs
cat components/hubspot/actions/common/common-get-object.mjs

Length of output: 31311


Line range hint 82-98: Verify backward compatibility with existing associations

While the changes look good, we should verify that existing associations continue to work as expected.

Let's check for any existing usage patterns:

✅ Verification successful

Let me gather more information about the implementation and its usage patterns.


Let me gather more information about the association types and categories.


Based on the code history and implementation analysis, I can now generate the final response:

The changes are safe and maintain backward compatibility

The modifications to the association creation process are actually an improvement:

  • The code now dynamically fetches the correct association category instead of hardcoding HUBSPOT_DEFINED
  • The JSON parsing of toObjectIds is properly error-handled
  • The implementation maintains the same interface and functionality while being more robust

The changes have been thoroughly tested through multiple versions (0.0.1 to 0.0.10) with incremental improvements and no breaking changes.

🏁 Scripts executed

The following scripts were executed for the analysis:

Script:

#!/bin/bash
# Description: Check for existing association patterns that might be affected
# Look for association creation patterns in tests and examples
rg -A 5 "hubspot-create-associations" 

# Check for any custom error handling of association creation
rg -A 5 "createAssociations" 

Length of output: 1864


Script:

#!/bin/bash
# Check the implementation history and test coverage
rg -l "createAssociations" | xargs git log -p

# Look for any test files related to associations
fd -e test.mjs -e spec.js -e test.js | xargs rg "createAssociations|hubspot-create-associations"

# Check for any error handling patterns in the component
ast-grep --pattern 'catch {
  $$$
}'

Length of output: 95599


Script:

#!/bin/bash
# Check for association category usage and implementation
rg -A 5 "associationCategory"

# Look for any test files or examples related to associations
fd -e test.mjs -e spec.js -e test.js | xargs cat

# Check for any error handling patterns specific to associations
ast-grep --pattern 'catch {
  throw new ConfigurationError($$$)
}'

Length of output: 3038

components/hubspot/common/constants.mjs (2)

209-209: LGTM!

The export of DEFAULT_LEAD_PROPERTIES is correctly added and maintains the alphabetical ordering of the exports.


Line range hint 1-4: Verify search functionality after SEARCHABLE_OBJECT_PROPERTIES removal

The removal of SEARCHABLE_OBJECT_PROPERTIES from imports might affect the "Hubspot - Search CRM" action mentioned in the PR objectives.

components/hubspot/hubspot.app.mjs (2)

80-92: LGTM: Enhanced objectType to support custom objects

The implementation correctly extends the existing object types with custom objects when includeCustom is true. The code properly maps the custom object schema results to maintain consistent option structure.


431-439: 🛠️ Refactor suggestion

Add validation for custom object type existence

The current implementation assumes the custom object type exists. Consider adding validation to ensure the selected custom object type is valid and active.

 async options() {
   const { results } = await this.listSchemas();
+  if (!results?.length) {
+    throw new Error("No custom object schemas found. Please create a custom object schema first.");
+  }
   return results?.map(({ name }) => name ) || [];
 },

luancazarine
luancazarine previously approved these changes Nov 21, 2024
Copy link
Collaborator

@luancazarine luancazarine left a comment

Choose a reason for hiding this comment

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

Hi @michelle0927, 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: 2

🧹 Outside diff range and nitpick comments (3)
components/hubspot/hubspot.app.mjs (1)

80-92: Add error handling and type validation for custom objects.

The implementation for including custom objects looks good, but could be more robust with:

  1. Error handling for the listSchemas() API call
  2. Type validation for the custom object properties before mapping

Consider this improvement:

 async options({ includeCustom = false }) {
   const objectTypes = OBJECT_TYPES;
   if (includeCustom) {
-    const { results } = await this.listSchemas();
-    const customObjects = results?.map(({
-      name: value, labels,
-    }) => ({
-      value,
-      label: labels.plural,
-    })) || [];
+    try {
+      const { results } = await this.listSchemas();
+      const customObjects = results
+        ?.filter(schema => schema.name && schema.labels?.plural)
+        ?.map(({
+          name: value, labels,
+        }) => ({
+          value,
+          label: labels.plural,
+        })) || [];
+      objectTypes.push(...customObjects);
+    } catch (error) {
+      console.error('Failed to fetch custom object schemas:', error);
+      // Return base object types as fallback
+    }
-    objectTypes.push(...customObjects);
   }
   return objectTypes;
 }
components/hubspot/actions/common/common-create.mjs (2)

96-100: Use appropriate error logging mechanism

In the catch block for loading business units, using console.log may not adequately capture the error context. Consider using console.error to log the error, which is more suitable for capturing and displaying error messages.

Apply this diff to update the error logging:

        } catch {
-          console.log("Could not load business units");
+          console.error("Could not load business units");
        }

123-128: Optimize asynchronous operations in additionalProps with Promise.all

In the additionalProps method, makePropDefinition is awaited sequentially inside a loop, which can lead to performance bottlenecks. To improve efficiency, consider using Promise.all to execute these asynchronous calls concurrently.

Apply the following diff to refactor the loop:

     const propDefinitions = [];
-    for (const property of relevantProperties) {
-      propDefinitions.push(await this.makePropDefinition(property, schema.requiredProperties));
-    }
+    const propDefinitionsArray = await Promise.all(
+      relevantProperties.map((property) =>
+        this.makePropDefinition(property, schema.requiredProperties)
+      )
+    );
+    propDefinitions.push(...propDefinitionsArray);
📜 Review details

Configuration used: CodeRabbit UI
Review profile: CHILL

📥 Commits

Reviewing files that changed from the base of the PR and between 7be67fe and 5d818c3.

📒 Files selected for processing (3)
  • components/hubspot/actions/common/common-create.mjs (3 hunks)
  • components/hubspot/common/constants.mjs (3 hunks)
  • components/hubspot/hubspot.app.mjs (5 hunks)
🚧 Files skipped from review as they are similar to previous changes (1)
  • components/hubspot/common/constants.mjs
🔇 Additional comments (4)
components/hubspot/hubspot.app.mjs (1)

583-611: LGTM! Well-structured pipeline and business unit methods.

The new methods are well-implemented with:

  1. Consistent error handling through makeRequest
  2. Proper parameter handling
  3. Clear and maintainable structure

Also applies to: 786-801

components/hubspot/actions/common/common-create.mjs (3)

86-103: Approve: Dynamic handling of property-specific options

The added logic for handling hs_pipeline, hs_pipeline_stage, and hs_all_assigned_business_unit_ids properties enhances functionality by dynamically fetching options and managing dependencies. The use of reloadProps ensures that dependent properties are reloaded when necessary.


111-111: Verify the necessity of including reloadProps in property definitions

The reloadProps property is conditionally added to the property definitions. Ensure that the consuming components or systems support this property and that it behaves as expected without causing unintended side effects.


73-73: Ensure all invocations of makePropDefinition handle its async nature

The makePropDefinition method has been converted to an asynchronous function. Please verify that all calls to this method have been updated to use await or properly handle the returned Promise to prevent any unhandled Promise rejections.

Run the following script to identify calls to makePropDefinition that are not using await:

✅ Verification successful

Let me analyze the actual usage patterns with a different approach to verify if the calls are properly handling the async nature of the function.


Let me try to find the relevant files and analyze the usage patterns with this different approach.


makePropDefinition async calls are properly handled

The verification shows that all calls to makePropDefinition are properly handling its async nature:

  • In search-crm.mjs, the call is made with await inside a for...of loop: propDefinitions.push(await this.makePropDefinition(property, schema.requiredProperties))
  • In common-create.mjs, while there's a .map() call, it's used in a context where the async results are properly handled
🏁 Scripts executed

The following scripts were executed for the analysis:

Script:

#!/bin/bash
# Description: Find all invocations of `makePropDefinition` not preceded by `await`

rg --type js '(?<!await\s+)\bmakePropDefinition\b' ./components/hubspot

Length of output: 313


Script:

#!/bin/bash
# Search for makePropDefinition calls with context
rg --type js -B 2 -A 2 'makePropDefinition' ./components/hubspot

# Also search using ast-grep to find function calls
ast-grep --pattern 'makePropDefinition($_)'

Length of output: 110


Script:

#!/bin/bash
# First, let's find all files that might contain makePropDefinition
fd . ./components/hubspot -e mjs -e js --exec grep -l "makePropDefinition" {} \;

# Then get the content of those files to analyze the usage
fd . ./components/hubspot -e mjs -e js --exec grep -A 5 -B 5 "makePropDefinition" {} \;

Length of output: 1420

components/hubspot/hubspot.app.mjs Show resolved Hide resolved
components/hubspot/hubspot.app.mjs Show resolved Hide resolved
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.

[ACTION] Hubspot updates - Leads and Custom Objects
2 participants