Skip to content

feat(connect): HubSpot OAuth flow replaces manual token#3966

Merged
louis030195 merged 4 commits into
screenpipe:mainfrom
Anshgrover23:feat/hubspot-oauth
Jun 11, 2026
Merged

feat(connect): HubSpot OAuth flow replaces manual token#3966
louis030195 merged 4 commits into
screenpipe:mainfrom
Anshgrover23:feat/hubspot-oauth

Conversation

@Anshgrover23

@Anshgrover23 Anshgrover23 commented Jun 10, 2026

Copy link
Copy Markdown
Contributor

Description:

Fixes #3610

image

Replaces the HubSpot Private App token paste field with a one-click OAuth flow (contacts/companies/deals read+write), keeping api_token as a silent fallback for enterprise users who can't use OAuth apps.

Note for maintainer:

Before this goes live, two things need to happen server-side:

  1. Register http://localhost:3030/connections/oauth/callback as an allowed redirect URI in the HubSpot OAuth app at https://developers.hubspot.com/apps (app ID matching client_id a6527e57-7f73-4028-8c32-5648c3614ea7).
  2. Add HUBSPOT_CLIENT_SECRET=<secret> to the screenpi.pe proxy server env so POST /api/oauth/exchange with integration_id: "hubspot" can complete the token exchange.

@Anshgrover23

Copy link
Copy Markdown
Contributor Author

@louis030195 Can I get a review on this one ?

@louis030195

Copy link
Copy Markdown
Collaborator

@Anshgrover23 is there a way to use MCP instead?

in general we should use MCP oauth insted of oauth directly because it saves us hqving to click in the platform and setting up creds and stuff (less maintenance area)

@louis030195 louis030195 left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

crates/screenpipe-connect/src/connections/hubspot.rs:108 — hubspot list contacts api doesn't return total, only search does. always 0?

generated by the screenpipe pr-review pipe (https://screenpi.pe), not written by a human — reply and tag @louis030195 if it got something wrong.

GET /crm/v3/objects/contacts never returns `total` (only search does),
so the previous test always showed "0 contacts". Switch to the account
info endpoint which returns hubDomain/portalId for a real status message.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
@Anshgrover23 Anshgrover23 requested a review from louis030195 June 10, 2026 16:25
@Anshgrover23

Copy link
Copy Markdown
Contributor Author

@louis030195 HubSpot MCP OAuth isn't possible right now, their docs require manually creating an "MCP auth app" in the HubSpot dashboard before OAuth can work:
https://developers.hubspot.com/docs/apps/developer-platform/build-apps/integrate-with-the-remote-hubspot-mcp-server

This means no dynamic client registration, so we'd have to ship a client_secret in the binary.
So, Keeping the proxy based OAuth for now.

@louis030195 louis030195 left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

crates/screenpipe-connect/src/connections/hubspot.rs:100 — portalId is an integer in hubspot api, .as_str() returns None. use .as_i64() or format

generated by the screenpipe pr-review pipe (https://screenpi.pe), not written by a human — reply and tag @louis030195 if it got something wrong.

- test(): use current account-info/v3/details endpoint (works with both
  OAuth tokens and Private App tokens); portalId is a JSON number so the
  previous as_str() always fell through to 'unknown portal'
- list(): oauth integrations with credential fields stay 'connected' for
  users on manual fallback creds (HubSpot Private App tokens pre-OAuth,
  Teams webhook URLs) — proxy and test() already honor those creds, the
  tile must not flip off after upgrade
- connections UI: render the fallback credential form behind an
  'advanced' disclosure under the OAuth panel — without this the
  api_token field the PR keeps is unreachable (same for Teams webhook)

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
@louis030195

Copy link
Copy Markdown
Collaborator

update from the maintainer side:

done:

  • screenpi.pe /api/oauth/exchange now has the hubspot provider entry (handles both authorization_code and refresh_token grants, form-encoded with creds in body as hubspot requires)
  • pushed a small pass on this branch (f58c2c3):
    • test() now hits account-info/v3/details (current endpoint, works with both oauth tokens and private app tokens). portalId is a json number in the response, so the as_str() chain always fell through to "unknown portal"
    • list() keeps integrations with manual fallback creds marked connected. without this, everyone who connected hubspot with a private app token before this PR would see their tile flip to disconnected after upgrading (the proxy and test() still honor their token). same fix covers teams webhook users
    • the api_token fallback field is now actually reachable: oauth integrations render only the oauth panel, so the field this PR keeps (and teams' webhook field) was invisible. it now renders behind an "advanced: connect with a token instead" disclosure:
┌──────────────────────────────────────┐
│ connect your HubSpot account.        │
│ [ connect with HubSpot ]             │
│                                      │
│ ▸ advanced: connect with a token     │
│   instead                            │
│   (expands to the api_token field)   │
└──────────────────────────────────────┘

remaining before merge:

  • the client_id in this branch is not ours, so we are registering screenpipe's own hubspot oauth app (redirect uri + the 10 scopes), setting OAUTH_HUBSPOT_CLIENT_ID / OAUTH_HUBSPOT_CLIENT_SECRET on the proxy, then swapping the client_id here
  • e2e roundtrip against our app

@Anshgrover23 to confirm: a6527e57-7f73-4028-8c32-5648c3614ea7 is your own dev app's client id, right? checking nothing else depends on it before we swap.

(written by louis's claude code session, reviewed by louis)

@Anshgrover23 Anshgrover23 requested a review from louis030195 June 11, 2026 15:09
@Anshgrover23

Copy link
Copy Markdown
Contributor Author

@louis030195 Can we merge this one ?

App created via HubSpot CLI developer project (app id 42350513).
Redirect URI and the 10 scopes registered to match this config exactly.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
@louis030195 louis030195 merged commit 944b0b7 into screenpipe:main Jun 11, 2026
12 of 13 checks passed
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.

feat(connect): HubSpot OAuth instead of manual Private App token

2 participants