Skip to content

feat(hubspot): add notes, emails, properties & associations tools#5037

Merged
waleedlatif1 merged 3 commits into
stagingfrom
worktree-hubspot-usecase-research
Jun 14, 2026
Merged

feat(hubspot): add notes, emails, properties & associations tools#5037
waleedlatif1 merged 3 commits into
stagingfrom
worktree-hubspot-usecase-research

Conversation

@waleedlatif1

@waleedlatif1 waleedlatif1 commented Jun 14, 2026

Copy link
Copy Markdown
Collaborator

Summary

  • Add 11 HubSpot tools: get_properties (read property definitions + picklist/enum options), notes (create/get/list/search), email engagements (create/get/list/search), and v4 associations (list/create)
  • Add OAuth scope sales-email-read (required to read email-engagement content/body). Note/email object + association endpoints are authorized by the existing crm.objects.contacts.read/write scope — HubSpot does not expose grantable crm.objects.notes.* / crm.objects.emails.* scopes (verified against HubSpot's OpenAPI security blocks; requesting them would break the OAuth authorize flow).
  • Wire the new operations into the HubSpot block (operation options, subBlocks, conditions, tool mapping + coercions, outputs, BlockMeta templates/skills)
  • Fix pre-existing bugs surfaced during a full spec audit of every tool:
    • list_marketing_events list URL → /marketing/marketing-events/v3
    • appointment property names → hs_appointment_* (were hs_meeting_*)
    • get_users outputs → CRM envelope shape (matches /crm/v3/objects/users); forwards properties
    • create_list now unwraps the {list} response envelope
    • create tools now parse a stringified associations array
  • Regenerate integration docs

Note: adding sales-email-read changes the OAuth consent set — existing HubSpot connections must re-authorize before the email-content read works (HubSpot enforces granular scopes all-of).

Type of Change

  • New feature

Testing

Validated every tool and the block against HubSpot's live OpenAPI specs (parallel audit, all 50 tools PASS). bun run lint, tsc, and bun run check:api-validation all clean.

Checklist

  • Code follows project style guidelines
  • Self-reviewed my changes
  • Tests added/updated and passing
  • No new warnings introduced
  • I confirm that I have read and agree to the terms outlined in the Contributor License Agreement (CLA)

- Add 11 tools: get_properties (read property/enum options), notes
  (create/get/list/search), email engagements (create/get/list/search),
  and v4 associations (list/create)
- Add scopes: crm.objects.notes.read/write, crm.objects.emails.read/write,
  sales-email-read (required for email engagement content)
- Wire new operations into the HubSpot block (subBlocks, conditions,
  tool mapping, outputs, BlockMeta templates/skills)
- Fix pre-existing bugs found in validation: list_marketing_events list
  URL (/marketing/marketing-events/v3), appointment property names
  (hs_appointment_*), get_users output shape (CRM envelope), create_list
  response unwrap, and stringified-associations parsing in create tools
- Regenerate integration docs
@vercel

vercel Bot commented Jun 14, 2026

Copy link
Copy Markdown

The latest updates on your projects. Learn more about Vercel for GitHub.

1 Skipped Deployment
Project Deployment Actions Updated (UTC)
docs Skipped Skipped Jun 14, 2026 12:26am

Request Review

@cursor

cursor Bot commented Jun 14, 2026

Copy link
Copy Markdown

PR Summary

Medium Risk
New OAuth scope and broader CRM write/read surface (notes, emails, associations) affect connected accounts; appointment and users API shape changes could break workflows that relied on old field names or user output.

Overview
Adds 11 HubSpot integration tools so workflows can manage notes and email engagements, read property/picklist definitions, and list or create v4 associations between records. The HubSpot block, tool registry, integrations.json, and hubspot.mdx docs are updated (operation count 29 → 38), including new templates/skills for email logging and activity audits.

OAuth now requests sales-email-read so single-email reads can return body content; existing connections need re-authorization for that scope.

Correctness fixes bundled with the expansion: marketing-events list URL, appointment fields switched from hs_meeting_* to hs_appointment_*, get_users aligned to the CRM users object shape (optional properties, default page size 10), create_list response unwrapping, and JSON parsing for string associations on create tools. QuartrIcon in docs is redrawn as a compact 32×32 mark.

Reviewed by Cursor Bugbot for commit 73b42db. Configure here.

Comment thread apps/sim/blocks/blocks/hubspot.ts
@greptile-apps

greptile-apps Bot commented Jun 14, 2026

Copy link
Copy Markdown
Contributor

Greptile Summary

This PR adds 11 new HubSpot tools (notes, email engagements, property definitions, and v4 associations) along with the sales-email-read OAuth scope for reading email body content. It also fixes several pre-existing bugs: the list_marketing_events URL, appointment property names, the create_list response envelope unwrap, and the get_users output shape.

  • 11 new tools wired end-to-end: create_note, get_note, list_notes, search_notes, create_email, get_email, list_emails, search_emails, get_properties, list_associations, create_association — all registered in the tool registry, exported from the index, and mapped in the HubSpot block with correct dual-dispatch for get_notes/get_emails.
  • create_association cleanly handles both paths: the default PUT (no body, no Content-Type) and the labeled PUT (JSON body, Content-Type: application/json) are correctly differentiated; response parsing falls back to params values for fromObjectId/toObjectId when the default-association response omits them.
  • Pre-existing bug fixes: create_list now unwraps the {list} envelope, get_users switches to the generic CRM output shape, and appointment property names are corrected to hs_appointment_*.

Confidence Score: 5/5

The change is safe to merge — all new tools follow established patterns, the dual-dispatch routing in the block is correct, and the OAuth scope addition is the only change that touches existing user sessions (re-auth required for email content, as documented).

All 11 new tools are correctly registered, exported, and wired into the block with accurate URL construction and response normalisation. The only findings are a leftover any body type in the two search tools, which is a style inconsistency with no runtime impact.

apps/sim/tools/hubspot/search_emails.ts and apps/sim/tools/hubspot/search_notes.ts — request body typed as any instead of Record<string, unknown>.

Important Files Changed

Filename Overview
apps/sim/tools/hubspot/create_association.ts New v4 associations tool: cleanly conditionalises the PUT URL, Content-Type header, and body for default vs. labeled paths; response fallback to params values for fromObjectId/toObjectId is correct.
apps/sim/tools/hubspot/create_note.ts New note creation tool; uses Record<string, unknown> for body (previously flagged issue fixed), handles string→JSON coercion for both properties and associations inputs.
apps/sim/tools/hubspot/create_email.ts New email engagement creation tool; uses Record<string, unknown> for body (previously flagged issue fixed), mirrors create_note.ts pattern closely.
apps/sim/tools/hubspot/search_emails.ts New email search tool; uses any for the request body instead of Record<string, unknown>, inconsistent with other create/search tools.
apps/sim/tools/hubspot/search_notes.ts New notes search tool; same any body type issue as search_emails.ts; otherwise mirrors search_emails.ts faithfully.
apps/sim/tools/hubspot/get_properties.ts New properties fetch tool; correctly switches between single-property and all-properties URLs, handles archived flag, and normalises both list and single-object responses via Array.isArray(data.results) ? data.results : [data].
apps/sim/tools/hubspot/list_associations.ts New v4 association listing tool; URL construction, pagination, and response shape all look correct.
apps/sim/blocks/blocks/hubspot.ts New operations wired in: get_notes/get_emails dual-dispatch (id present → get, absent → list), create_note/create_email, search_notes/search_emails, get_properties, list/create_association; coercions for associationTypeId and archived are correct.
apps/sim/lib/oauth/oauth.ts Adds sales-email-read scope for reading email engagement content; PR author has verified HubSpot does not expose separate crm.objects.notes./crm.objects.emails. scopes — existing crm.objects.contacts.read/write covers those endpoints.
apps/sim/tools/hubspot/types.ts Adds well-typed output constants and interface definitions for notes, emails, properties, and associations; removes the now-unused HubSpotUser interface and USERS_ARRAY_OUTPUT in favour of the generic CRM shape.
apps/sim/tools/hubspot/create_list.ts Pre-existing bug fix: unwraps the {list} envelope from the HubSpot create-list response before extracting listId.
apps/sim/tools/hubspot/get_users.ts Fixed to use GENERIC_CRM_ARRAY_OUTPUT (matches the /crm/v3/objects/users envelope); adds optional properties query param forwarding.

Flowchart

%%{init: {'theme': 'neutral'}}%%
flowchart TD
    A[HubSpot Block - operation] --> B{operation type}
    B --> C[get_notes]
    B --> D[get_emails]
    B --> E[create_note / create_email]
    B --> F[search_notes / search_emails]
    B --> G[get_properties]
    B --> H[list_associations]
    B --> I[create_association]

    C -->|noteId present| C1[hubspot_get_note\n/crm/v3/objects/notes/id]
    C -->|no noteId| C2[hubspot_list_notes\n/crm/v3/objects/notes]

    D -->|emailId present| D1[hubspot_get_email\n/crm/v3/objects/emails/id]
    D -->|no emailId| D2[hubspot_list_emails\n/crm/v3/objects/emails]

    E --> E1[POST /crm/v3/objects/notes\nPOST /crm/v3/objects/emails]
    F --> F1[POST /crm/v3/objects/notes-emails/search]

    G --> G1[GET /crm/v3/properties/objectType\nor /objectType/propertyName]

    H --> H1[GET /crm/v4/objects/type/id/associations/toType]

    I -->|associationTypeId = null| I1[PUT .../associations/default/toType/toId\nno body, no Content-Type]
    I -->|associationTypeId present| I2[PUT .../associations/toType/toId\nJSON body with category + typeId]
Loading

Reviews (3): Last reviewed commit: "fix(hubspot): address review comments" | Re-trigger Greptile

Comment thread apps/sim/tools/hubspot/types.ts Outdated
Comment thread apps/sim/tools/hubspot/create_note.ts Outdated
Comment thread apps/sim/tools/hubspot/create_email.ts Outdated
Comment thread apps/sim/tools/hubspot/create_association.ts
…omments

- crm.objects.notes.*/crm.objects.emails.* are not grantable HubSpot
  scopes (would break the OAuth authorize flow). Notes/emails engagement
  and association endpoints are authorized by crm.objects.contacts.*;
  sales-email-read remains for email-engagement content
- Remove non-TSDoc inline comments from new tool files
@waleedlatif1

Copy link
Copy Markdown
Collaborator Author

@greptile

@waleedlatif1

Copy link
Copy Markdown
Collaborator Author

@cursor review

Comment thread apps/sim/lib/oauth/oauth.ts
- Forward the properties param for the Get Users operation (block param
  mapping + Properties-to-Return field now include get_users)
- Use Record<string, unknown> for create_note/create_email request bodies
- Only send Content-Type on create_association when a body is sent
  (default-association PUT has no body)
- Remove stray duplicate JSDoc opener in types.ts
@waleedlatif1

Copy link
Copy Markdown
Collaborator Author

@greptile

@waleedlatif1

Copy link
Copy Markdown
Collaborator Author

@cursor review

@cursor cursor Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

✅ Bugbot reviewed your changes and found no new issues!

Comment @cursor review or bugbot run to trigger another review on this PR

Reviewed by Cursor Bugbot for commit 73b42db. Configure here.

@waleedlatif1 waleedlatif1 merged commit 6282b16 into staging Jun 14, 2026
15 checks passed
@waleedlatif1 waleedlatif1 deleted the worktree-hubspot-usecase-research branch June 14, 2026 00:42
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.

1 participant