-
Notifications
You must be signed in to change notification settings - Fork 5.3k
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
base: master
Are you sure you want to change the base?
Conversation
The latest updates on your projects. Learn more about Vercel for Git ↗︎ 3 Skipped Deployments
|
WalkthroughThis 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
Assessment against linked issues
Possibly related PRs
Poem
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? 🪧 TipsChatThere are 3 ways to chat with CodeRabbit:
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)
Other keywords and placeholders
CodeRabbit Configuration File (
|
There was a problem hiding this 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 renamingobjectType
variable for clarityAssigning
const objectType = this.customObjectType ?? this.objectType;
may cause confusion withthis.objectType
. Consider renaming the variable toresolvedObjectType
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 documentationWhile 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 documentationWhile 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 linkThe 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 documentationSince this component interacts with HubSpot's API:
- Document any rate limiting considerations
- Add error handling examples in the description
- 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 selectionThe
objectId
prop depends oncustomObjectType
, but there's no explicit validation to ensurecustomObjectType
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 consistencyFor 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 callWhile 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 safetyThe
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 propertiesWhile 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 operationThe 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 optionsThe 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 documentationThe 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 specificityWhile 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 genericThe
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 clarityThe 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 parsingThe 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 numberThe 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 propertiesWhile 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
⛔ 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.10create-associations
: 0.0.10enroll-contact-into-workflow
: 0.0.10get-company
: 0.0.10get-deal
: 0.0.10get-file-public-url
: 0.0.10update-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:
- Using a more flexible AST pattern
- Using ripgrep with context
- 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
orOBJECT_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:
- The common module being extended
- How custom objects are handled in the HubSpot integration
- 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 whennewOnly
is true - Using
updatedAt
timestamp whennewOnly
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
andupdatedAt
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:
- The searchable properties are now obtained dynamically through the Hubspot API's schema endpoint (
schema.searchableProperties
) - The search functionality is properly maintained through the
searchProperty
andpropertyName
fields in the search configurations - 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:
- Is this file's inclusion necessary for this PR?
- 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:
- Fetches custom object schemas via
listSchemas()
API call - Appends the custom objects to the standard object types
- 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 ) || [];
},
Resolves #14677
Summary by CodeRabbit
Release Notes
New Features
associationType
property for better engagement management.updateIfExists
property for contact creation to allow updates on creation failure.newOnly
property for line items and products to filter events.Bug Fixes
Documentation
Chores