-
Notifications
You must be signed in to change notification settings - Fork 5.5k
[ACTION] Hubspot Meetings #16295
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
[ACTION] Hubspot Meetings #16295
Conversation
|
The latest updates on your projects. Learn more about Vercel for Git ↗︎ 3 Skipped Deployments
|
|
""" WalkthroughThis update introduces comprehensive support for HubSpot Meetings within the codebase. It adds three new action modules: creating a meeting (with optional associations), retrieving a specific meeting by ID, and fetching meetings associated with a contact, company, or deal (with flexible time-based and recency filters). The HubSpot app module is extended with new property definitions and methods to support meeting operations, including association handling and dynamic meeting ID options. The package version is incremented to reflect these new capabilities. Changes
Sequence Diagram(s)sequenceDiagram
participant User
participant ActionModule
participant HubSpotApp
participant HubSpotAPI
User->>ActionModule: Trigger "Get Associated Meetings"
ActionModule->>HubSpotApp: Resolve objectId (email lookup if needed)
HubSpotApp->>HubSpotAPI: Search Contacts (if email)
HubSpotApp->>HubSpotAPI: Get Associations (object to meetings)
HubSpotApp->>HubSpotAPI: Search Meetings (with filters)
HubSpotApp-->>ActionModule: Return meetings data
ActionModule-->>User: Return filtered meetings
sequenceDiagram
participant User
participant ActionModule
participant HubSpotApp
participant HubSpotAPI
User->>ActionModule: Trigger "Create Meeting"
ActionModule->>HubSpotApp: createMeeting (with properties and associations)
HubSpotApp->>HubSpotAPI: POST /crm/v3/objects/meetings
HubSpotAPI-->>HubSpotApp: Response
HubSpotApp-->>ActionModule: Meeting data
ActionModule-->>User: Meeting created summary
Assessment against linked issues
Suggested labels
Poem
Warning There were issues while running some tools. Please review the errors and either fix the tool's configuration or disable the tool if it's a critical failure. 🔧 ESLint
components/hubspot/actions/create-communication/create-communication.mjsOops! Something went wrong! :( ESLint: 8.57.1 Error [ERR_MODULE_NOT_FOUND]: Cannot find package 'jsonc-eslint-parser' imported from /eslint.config.mjs components/hubspot/actions/add-contact-to-list/add-contact-to-list.mjsOops! Something went wrong! :( ESLint: 8.57.1 Error [ERR_MODULE_NOT_FOUND]: Cannot find package 'jsonc-eslint-parser' imported from /eslint.config.mjs components/hubspot/actions/batch-create-or-update-contact/batch-create-or-update-contact.mjsOops! Something went wrong! :( ESLint: 8.57.1 Error [ERR_MODULE_NOT_FOUND]: Cannot find package 'jsonc-eslint-parser' imported from /eslint.config.mjs
Tip ⚡💬 Agentic Chat (Pro Plan, General Availability)
📜 Recent review detailsConfiguration used: CodeRabbit UI ⛔ Files ignored due to path filters (1)
📒 Files selected for processing (53)
✅ Files skipped from review due to trivial changes (14)
🚧 Files skipped from review as they are similar to previous changes (39)
⏰ Context from checks skipped due to timeout of 90000ms (4)
🪧 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
🧹 Nitpick comments (1)
components/hubspot/actions/get-associated-meetings/get-associated-meetings.mjs (1)
171-174: Consider pagination for large result setsThe code limits results to 100 meetings when not requesting only the most recent one. For objects with many associated meetings, this could truncate results.
Consider implementing pagination to handle cases where there are more than 100 associated meetings:
- limit: mostRecent - ? 1 - : 100, + limit: mostRecent ? 1 : 100, + // Add pagination params here if supported by the APIYou might also want to add a
maxResultsprop to allow users to specify how many meetings they want to retrieve, with appropriate pagination handling.
📜 Review details
Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro
⛔ Files ignored due to path filters (1)
pnpm-lock.yamlis excluded by!**/pnpm-lock.yaml
📒 Files selected for processing (5)
components/hubspot/actions/create-meeting/create-meeting.mjs(1 hunks)components/hubspot/actions/get-associated-meetings/get-associated-meetings.mjs(1 hunks)components/hubspot/actions/get-meeting/get-meeting.mjs(1 hunks)components/hubspot/hubspot.app.mjs(2 hunks)components/hubspot/package.json(1 hunks)
🧰 Additional context used
🪛 GitHub Actions: Components Checks
components/hubspot/package.json
[error] 1-1: Version of 46 dependencies needs to be increased.
⏰ Context from checks skipped due to timeout of 90000ms (1)
- GitHub Check: pnpm publish
🔇 Additional comments (13)
components/hubspot/hubspot.app.mjs (5)
451-511: Well-structured property definitions for meeting management.The new property definitions for meetings are well organized and provide comprehensive filtering options through timeframe, date ranges, and a most recent flag. The meetingId property with dynamic options via the searchMeetings method is particularly useful for user experience.
1106-1114: The getAssociations method enhances relationship management capabilities.This method provides a clean interface for retrieving associations between HubSpot objects, which is crucial for the new meeting-related functionality.
1115-1129: Well-documented getMeeting method with proper JSDoc.The method includes clear documentation with parameter and return type descriptions. The implementation correctly uses the CRM v3 API endpoint for retrieving meeting data.
1130-1142: The createMeeting method follows consistent patterns.The implementation matches other object creation methods in the codebase, making the API easy to understand for developers familiar with the HubSpot component.
1143-1155: Well-implemented searchMeetings method with proper JSDoc.This method includes clear documentation and correctly uses the search endpoint with POST method, consistent with other search implementations in the codebase.
components/hubspot/actions/get-meeting/get-meeting.mjs (1)
1-28: Well-structured meeting retrieval action.This new action is well-implemented with clear documentation links and a straightforward implementation that follows the component's patterns. The export summary provides a helpful message indicating success.
A few suggestions for enhancements:
- Consider adding support for retrieving specific properties of the meeting through an optional
propertiesprop, similar to other HubSpot object retrieval actions.- You could add error handling to provide more specific error messages when the meeting can't be found.
components/hubspot/actions/create-meeting/create-meeting.mjs (4)
8-54: Well-structured meeting creation action with comprehensive association support.The action properly extends the common create base and provides clear properties for specifying associations and meeting data. The description includes appropriate documentation links.
55-72: Clean method implementations follow established patterns.The methods properly override and extend the common methods, specifically identifying the object type as a meeting and implementing the createMeeting wrapper method.
73-108: Strong validation and data preparation logic.The run method includes:
- Proper validation to ensure both association ID and type are provided together
- Flexible parsing of objectProperties from either string or object format
- Clean construction of the associations array when needed
109-114: Clear API invocation and result reporting.The final steps of the action correctly call the API, export a user-friendly summary, and return the complete meeting data.
Consider adding validation for required meeting properties (title, body, start/end times) to provide more helpful error messages before the API call fails.
components/hubspot/actions/get-associated-meetings/get-associated-meetings.mjs (3)
4-59: Component configuration looks goodThe component is well-structured with appropriate props and clear descriptions. The integration with HubSpot's API is cleanly defined.
180-221: Run method logic is soundThe main
runmethod has good logic for resolving contact emails to IDs and handling the meeting retrieval process. The summary export provides helpful feedback to users.
155-162:❓ Verification inconclusive
Review operator usage for date range filters
The filter construction uses the operator "IN" for all filters, including date ranges. The HubSpot API might expect different operators for date range comparisons.
Verify that the "IN" operator is appropriate for date range filters or adjust as needed:
🏁 Script executed:
#!/bin/bash # Find documentation or examples of HubSpot meeting search filters rg -A 5 -B 5 "searchMeetings" components/hubspot/Length of output: 2629
Clarify Date Range Filter Operator Usage
The current implementation maps all filters to use the
"IN"operator, but for date range filters the HubSpot API might expect a different operator (for example,"BETWEEN"or a combination of"GTE"/"LTE"). Please verify the API documentation for meeting search filters to ensure that date range comparisons are handled correctly. If a date range filter is indeed in use, adjust the filtering logic accordingly.
components/hubspot/actions/get-associated-meetings/get-associated-meetings.mjs
Outdated
Show resolved
Hide resolved
components/hubspot/actions/get-associated-meetings/get-associated-meetings.mjs
Show resolved
Hide resolved
components/hubspot/actions/get-associated-meetings/get-associated-meetings.mjs
Show resolved
Hide resolved
4e1168f to
fb2b936
Compare
luancazarine
left a comment
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.
Hi @jcortes, LGTM! Ready for QA!
dc31fa8 to
227688e
Compare
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: 1
♻️ Duplicate comments (3)
components/hubspot/actions/get-associated-meetings/get-associated-meetings.mjs (3)
192-203: 🛠️ Refactor suggestionAdd validation for custom date range
The code should validate that the start date is before the end date when using custom timeframes.
Add validation to ensure that the start date is before the end date:
case "custom": + if (!startDate || !endDate) { + return {}; + } + + // Validate that start date is before end date + if (new Date(startDate) > new Date(endDate)) { + throw new Error("Start date must be before end date"); + } return { hs_meeting_start_time: { operator: "LTE", value: startDate, }, hs_meeting_end_time: { operator: "GTE", value: endDate, }, };
215-223: 🛠️ Refactor suggestionAdd error handling for API calls
The code lacks error handling for the
getAssociationsAPI call. If the API returns an error, it will propagate up without providing a user-friendly message.Add try/catch blocks around API calls with specific error messages:
async getAssociatedMeetings({ objectType, objectId, timeframe, startDate, endDate, mostRecent, }) { - const { results: associations } = await this.hubspot.getAssociations({ - objectType, - objectId, - toObjectType: OBJECT_TYPE.MEETING, - }); + try { + const { results: associations } = await this.hubspot.getAssociations({ + objectType, + objectId, + toObjectType: OBJECT_TYPE.MEETING, + }); + + if (!associations?.length) { + return []; + } + + // Continue with the rest of the method... + } catch (error) { + throw new Error(`Failed to get associations: ${error.message}`); + }
229-265: 🛠️ Refactor suggestionAdd error handling for the searchMeetings API call
Similar to the getAssociations call, there's no error handling for searchMeetings.
Add try/catch blocks around the searchMeetings call:
- const { results } = await this.hubspot.searchMeetings({ - data: { - properties: [ - ...DEFAULT_MEETING_PROPERTIES, - ...(this.additionalProperties || []), - ], - filterGroups: [ - // ... existing filter groups ... - ], - sorts: [ - // ... existing sorts ... - ], - limit: mostRecent - ? 1 - : 100, - }, - }); + try { + const { results } = await this.hubspot.searchMeetings({ + data: { + properties: [ + ...DEFAULT_MEETING_PROPERTIES, + ...(this.additionalProperties || []), + ], + filterGroups: [ + // ... existing filter groups ... + ], + sorts: [ + // ... existing sorts ... + ], + limit: mostRecent + ? 1 + : 100, + }, + }); + + return results; + } catch (error) { + throw new Error(`Failed to search meetings: ${error.message}`); + }
📜 Review details
Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro
⛔ Files ignored due to path filters (1)
pnpm-lock.yamlis excluded by!**/pnpm-lock.yaml
📒 Files selected for processing (53)
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-get-object.mjs(2 hunks)components/hubspot/actions/create-associations/create-associations.mjs(1 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-meeting/create-meeting.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-associated-meetings/get-associated-meetings.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/get-meeting/get-meeting.mjs(1 hunks)components/hubspot/actions/search-crm/search-crm.mjs(1 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-deal/update-deal.mjs(1 hunks)components/hubspot/actions/update-lead/update-lead.mjs(1 hunks)components/hubspot/common/constants.mjs(2 hunks)components/hubspot/hubspot.app.mjs(2 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-custom-object-property-change/new-custom-object-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-note/new-note.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-task/new-task.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 (22)
- components/hubspot/sources/new-company-property-change/new-company-property-change.mjs
- components/hubspot/sources/new-ticket/new-ticket.mjs
- components/hubspot/sources/new-or-updated-contact/new-or-updated-contact.mjs
- components/hubspot/actions/create-engagement/create-engagement.mjs
- components/hubspot/sources/new-ticket-property-change/new-ticket-property-change.mjs
- components/hubspot/actions/batch-create-or-update-contact/batch-create-or-update-contact.mjs
- components/hubspot/sources/new-or-updated-company/new-or-updated-company.mjs
- components/hubspot/sources/new-or-updated-blog-article/new-or-updated-blog-article.mjs
- components/hubspot/sources/new-or-updated-product/new-or-updated-product.mjs
- components/hubspot/sources/new-email-subscriptions-timeline/new-email-subscriptions-timeline.mjs
- components/hubspot/actions/get-deal/get-deal.mjs
- components/hubspot/sources/new-event/new-event.mjs
- components/hubspot/actions/get-contact/get-contact.mjs
- components/hubspot/actions/get-company/get-company.mjs
- components/hubspot/actions/create-communication/create-communication.mjs
- components/hubspot/sources/new-email-event/new-email-event.mjs
- components/hubspot/sources/new-note/new-note.mjs
- components/hubspot/actions/search-crm/search-crm.mjs
- components/hubspot/sources/new-contact-property-change/new-contact-property-change.mjs
- components/hubspot/sources/new-custom-object-property-change/new-custom-object-property-change.mjs
- components/hubspot/actions/update-custom-object/update-custom-object.mjs
- components/hubspot/common/constants.mjs
🚧 Files skipped from review as they are similar to previous changes (28)
- components/hubspot/actions/add-contact-to-list/add-contact-to-list.mjs
- components/hubspot/sources/new-or-updated-crm-object/new-or-updated-crm-object.mjs
- components/hubspot/package.json
- components/hubspot/sources/new-social-media-message/new-social-media-message.mjs
- components/hubspot/actions/update-company/update-company.mjs
- components/hubspot/actions/enroll-contact-into-workflow/enroll-contact-into-workflow.mjs
- components/hubspot/sources/new-or-updated-custom-object/new-or-updated-custom-object.mjs
- components/hubspot/actions/create-ticket/create-ticket.mjs
- components/hubspot/actions/update-contact/update-contact.mjs
- components/hubspot/sources/new-deal-property-change/new-deal-property-change.mjs
- components/hubspot/sources/new-engagement/new-engagement.mjs
- components/hubspot/actions/create-or-update-contact/create-or-update-contact.mjs
- components/hubspot/actions/create-associations/create-associations.mjs
- components/hubspot/actions/create-deal/create-deal.mjs
- components/hubspot/actions/create-custom-object/create-custom-object.mjs
- components/hubspot/actions/create-lead/create-lead.mjs
- components/hubspot/actions/update-lead/update-lead.mjs
- components/hubspot/sources/new-or-updated-line-item/new-or-updated-line-item.mjs
- components/hubspot/sources/new-task/new-task.mjs
- components/hubspot/sources/delete-blog-article/delete-blog-article.mjs
- components/hubspot/sources/new-form-submission/new-form-submission.mjs
- components/hubspot/actions/create-company/create-company.mjs
- components/hubspot/actions/update-deal/update-deal.mjs
- components/hubspot/sources/new-or-updated-deal/new-or-updated-deal.mjs
- components/hubspot/actions/get-file-public-url/get-file-public-url.mjs
- components/hubspot/sources/new-deal-in-stage/new-deal-in-stage.mjs
- components/hubspot/actions/create-meeting/create-meeting.mjs
- components/hubspot/hubspot.app.mjs
⏰ Context from checks skipped due to timeout of 90000ms (2)
- GitHub Check: Verify TypeScript components
- GitHub Check: Publish TypeScript components
🔇 Additional comments (13)
components/hubspot/actions/common/common-get-object.mjs (3)
9-10: LGTM: Successfully imported required constantsThe imports of
DEFAULT_MEETING_PROPERTIESandOBJECT_TYPEconstants align with the implementation of HubSpot Meetings support.
67-78: LGTM: Standardized object type checksGood refactoring to use the
OBJECT_TYPEenum constants instead of string literals, making the code more maintainable and less prone to typos.
79-81: LGTM: Added meeting object type supportSuccessfully extended the
getDefaultPropertiesmethod to support meetings.components/hubspot/actions/get-meeting/get-meeting.mjs (4)
1-3: LGTM: Clean importsThe imports are appropriate and minimal for the requirements of this component.
4-10: LGTM: Well-defined action metadataThe action is properly defined with a clear key, name, description with documentation link, and appropriate versioning.
11-18: LGTM: Proper property customizationGood approach to extend the common props while customizing the objectId property specifically for meetings.
19-25: LGTM: Correctly implemented required methodThe
getObjectTypemethod correctly returns the meeting object type, fulfilling the requirements of the common module.components/hubspot/actions/get-associated-meetings/get-associated-meetings.mjs (6)
1-4: LGTM: Proper importsAll necessary dependencies are correctly imported, including constants required for meetings functionality.
5-11: LGTM: Well-defined action metadataThe action is properly defined with a descriptive name, clear description with documentation link, and appropriate versioning.
12-54: LGTM: Comprehensive props definitionThe component has well-defined props for object selection, filtering, and additional properties retrieval.
55-72: LGTM: Dynamic props for custom timeframeGood implementation of dynamic props that only appear when needed for custom time ranges.
269-292: LGTM: Email to contact ID resolutionGood implementation of resolving a contact's email to their ID when needed.
293-310: LGTM: Clean implementation of run methodThe run method is well-structured, with clear API calls, proper summary messages, and return values.
components/hubspot/actions/get-associated-meetings/get-associated-meetings.mjs
Show resolved
Hide resolved
227688e to
54ea7fb
Compare
|
/approve |
54ea7fb to
83c45d7
Compare
83c45d7 to
3129146
Compare
WHY
Resolves #16258
Summary by CodeRabbit
New Features
Chores