- CategoryCRM
- AuthOAuth
- Scopes2
Overview
HubSpot connects on /integrations in the dashboard. Click the HubSpot card and the "Connect hubspot" modal opens; there is nothing to paste because MessageMind runs its own HubSpot public app. Click Integrate and the browser goes to /integration/hubspot/connect, which signs an HMAC state and redirects you to app.hubspot.com/oauth/authorize to pick the HubSpot account and approve access. After consent, HubSpot bounces back to /integrations?hubSpotSuccess=true and MessageMind fetches the list of HubSpot meeting links on your account so you can pick which ones the AI is allowed to book on. The same connection also powers two contact-event automation triggers: when a contact is created in HubSpot (or an existing contact's properties change) MessageMind receives the webhook, syncs the contact and fires the 'hubspotContactCreated' trigger so follow-up campaigns can enrol the contact.
What MessageMind can do with it
- Let the AI check availability and book meetings on your HubSpot scheduler links from inside a chat, respecting each meeting type's duration, buffers and form fields.
- Narrow the AI to a chosen subset of HubSpot meeting links; non-selected links are not offered.
- React to a HubSpot contact being created by firing the 'hubspotContactCreated' automation trigger so a MessageMind campaign can start a follow-up.
- Sync the HubSpot contact (and its subsequent property changes) into MessageMind through the webhook handler before the trigger fires.
- Mutate a HubSpot contact (write properties back) when the connected app's token carries the crm.objects.contacts.write scope.
- Deduplicate retried HubSpot webhook deliveries so a repeated delivery does not enrol the same contact into the same campaign twice.
Requirements
- A HubSpot account with permission to install a public app and authorize the scopes MessageMind requests.
- A MessageMind plan on Starter, Professional or Enterprise. The HubSpot card on /integrations is plan-gated.
- At least one bookable scheduler link in HubSpot (meetings.hubspot.com) if you want the AI to book meetings. The settings panel reads the list after connect.
- A deployed MessageMind HubSpot public app (owned by the MessageMind operator, with its HUBSPOT_CLIENT_ID, HUBSPOT_CLIENT_SECRET, HUBSPOT_REDIRECT_URI and HUBSPOT_SCOPES configured on the server). Nothing to configure on your side.
How to connect
- Open /integrations in the dashboard and click the HubSpot card. The 'Connect hubspot' modal opens with the description about CRM activity.
- Click Integrate. The browser navigates to /integration/hubspot/connect on the MessageMind server, which signs an HMAC state and redirects you to app.hubspot.com/oauth/authorize.
- On HubSpot, pick the account you want MessageMind to work with and approve the requested scopes. The authorization window is ten minutes; the signed state expires after that.
- HubSpot redirects back to /integration/hubspot/callback on MessageMind's server, which exchanges the code for access and refresh tokens and persists them. The browser is bounced to /integrations?hubSpotSuccess=true&provider=hubspot&status=success&integrationId=<id> on success, or ?hubSpotSuccess=false&status=error&message=<reason> on failure.
- MessageMind calls /integration/hubspot/settings-preview and shows the HubSpot meeting-link selector. Pick the meeting types the AI should offer and save; the AI starts booking on them immediately.
- If any previously selected meetings are no longer available on HubSpot (deleted or disabled) the dashboard surfaces a toast 'Some previously selected meetings are no longer available and have been removed.' and strips them from the saved list.
Authentication and permissions
- Mechanism
- OAuth 2.0 authorization-code flow against MessageMind's HubSpot public app. There is no bring-your-own client ID: the client credentials live on the MessageMind server (HUBSPOT_CLIENT_ID, HUBSPOT_CLIENT_SECRET). A per-connection HMAC-signed state (HUBSPOT_STATE_SECRET) with a 10-minute expiry protects the callback against CSRF and replay.
- Credentials
- No credentials to paste. After the OAuth round-trip MessageMind stores HubSpot's access token, refresh token, expiry and the granted-scope list on your integration record. The refresh token is used to renew the access token transparently.
Required scopes
The scope list is whatever is configured in HUBSPOT_SCOPES on the MessageMind server; HubSpot shows the resolved list on its consent screen before you approve.The 'crm.objects.contacts.write' scope specifically gates whether MessageMind can write contact properties back to HubSpot. If it is absent, the integration still reads contacts and books meetings but refuses to mutate HubSpot contacts.
Available data and actions
Reads
- The HubSpot meeting-link catalog for the authorized account, including per-link form fields, used to present the selector and to validate booking requests.
- HubSpot contact-creation webhooks (used both to sync the contact into MessageMind and to fire the 'hubspotContactCreated' automation trigger).
- HubSpot contact property-change webhooks (used by the webhook handler to update the contact in MessageMind).
- Live availability on a chosen meeting type when the AI is about to propose a slot in chat.
Writes
- HubSpot bookings created from inside a chat, scoped to the meeting types you selected in the settings panel.
- HubSpot contact property updates when the stored token carries the 'crm.objects.contacts.write' scope. Without that scope, writes are refused and the AI only reads.
AI agent use cases
- Let a prospect book a 30-minute discovery call from a chat on your HubSpot sales rep's scheduler link, with the AI picking the right link based on the conversation.
- Give the AI a curated subset of your HubSpot meeting types so it does not accidentally offer an internal-only link.
- Enrol a brand-new HubSpot contact into a MessageMind follow-up campaign automatically on creation.
- Keep MessageMind's view of a HubSpot contact up to date as HubSpot property changes arrive, without manual export or import.
Configuration
- The settings panel keeps only meeting-link IDs you explicitly select. If you later uncheck a link, the AI stops offering it on the next save.
- Contact-created events fire the automation trigger 'hubspotContactCreated'. Point your MessageMind campaigns at that trigger to react to new HubSpot contacts.
- The event ledger keeps entries for 90 days, well inside HubSpot's retry window, so a legitimate HubSpot retry is recognized as a duplicate rather than re-enrolling the contact.
- If MessageMind detects the saved selection intersected with the live catalog is empty, saving fails with 'None of the selected meetings are available. They may have been deleted or disabled in HubSpot.'
Example workflows
First-time OAuth connect and meeting selection
- On /integrations click the HubSpot card and then Integrate.
- On app.hubspot.com, pick the HubSpot account and approve the scopes shown on the consent screen.
- HubSpot redirects back to /integrations?hubSpotSuccess=true and MessageMind opens the meeting-link selector.
- Tick the meeting types the AI should offer in chat and save. The selector surfaces per-link form fields so you can confirm what each meeting type requires from invitees.
- The AI can now check availability on, and book, any of the selected links. Non-selected links are not visible to the AI.
AI books a HubSpot meeting from chat
- The customer asks for a meeting in the chat thread.
- The AI picks a selected HubSpot meeting link that matches the request (duration, team, meeting type).
- MessageMind pulls live availability from HubSpot for that link.
- The AI proposes a slot; the customer confirms along with the invitee fields the meeting-link form requires.
- MessageMind creates the booking on HubSpot and confirms the booking inside the same chat thread.
New HubSpot contact enrols in a MessageMind campaign
- A contact is created in HubSpot (through a form, an import, a sync or by a user).
- HubSpot delivers the contact.creation webhook to MessageMind.
- The webhook handler syncs the contact into MessageMind.
- The event is written to the entity ledger and the 'hubspotContactCreated' automation trigger fires.
- Any MessageMind campaign subscribed to that trigger picks up the contact and starts its follow-up.
- If HubSpot retries the same webhook delivery, the ledger recognizes it and skips enrolment the second time.
Limitations
- The connection uses MessageMind's HubSpot public app. There is no bring-your-own HubSpot app flow in /integrations today; the modal description mentioning Client ID, Client Secret and Domain is misleading and not surfaced as fields.
- The verified automation trigger exposed for HubSpot today is contact creation. Deal, ticket, company and other HubSpot object events are not exposed as MessageMind triggers.
- The 'crm.objects.contacts.write' scope is required to write contact properties back to HubSpot. Without it, the AI reads contacts and books meetings but cannot mutate HubSpot contacts.
- Meeting booking depends on the HubSpot scheduler feature. Accounts without scheduler links have an empty selector and the AI cannot book on HubSpot until at least one link exists.
- The ledger records whether the trigger fired, not whether each downstream campaign started: a failed campaign delivery can still be retried on the next pass.
Troubleshooting
The OAuth round-trip ends on /integrations?hubSpotSuccess=false with an error message in the URL.
HubSpot rejected the consent (common causes: the authorized user does not have permission to install apps, the account tier does not include the requested scopes, or the signed state expired because consent took longer than ten minutes). Open the HubSpot card and click Integrate to run the flow again.
A toast reads 'Your HubSpot connection is no longer valid. Please reconnect.'
HubSpot invalidated the OAuth tokens (common after a password change, scope revocation or app re-authorization). Reconnect from the HubSpot card to issue fresh tokens; the previous selection is restored on the next settings-preview load.
A toast reads 'Failed to load HubSpot settings.'
HubSpot's meeting-link API refused the request. Retry the modal; if the problem persists, confirm the meetings scope is granted on the HubSpot consent screen and that the HubSpot account still has at least one scheduler link.
Saving the meeting selection fails with 'None of the selected meetings are available. They may have been deleted or disabled in HubSpot.'
Every previously saved link has been removed or disabled on HubSpot. Reload the selector to see the live catalog and tick at least one still-available link before saving.
Saving fails with 'Please select at least one meeting.'
The AI cannot book on an empty selection. Tick at least one meeting type and save.
A new HubSpot contact did not start a MessageMind campaign.
Confirm the campaign is subscribed to the 'hubspotContactCreated' trigger and that the HubSpot webhook for contact creation is reaching MessageMind. HubSpot retries non-2xx responses, so a transient outage usually recovers on its own; a persistent failure needs the webhook subscription checked in HubSpot.
The same HubSpot contact seems to have been enrolled more than once.
The ledger blocks a repeated HubSpot delivery of the same creation event, but a contact created, deleted and re-created in HubSpot is a new event and will enrol again. Check the HubSpot timeline for the contact to confirm which case applies.
Disconnect and reconnect
- On /integrations, open the HubSpot card and click Disconnect. The dashboard calls DELETE /integration/hubspot/disconnect, and the toast reads 'HubSpot disconnected successfully'.
- After disconnect the OAuth tokens, meeting selection and settings cache are cleared from your MessageMind tenant. The AI immediately stops booking on HubSpot and stops receiving contact-event webhooks for your account.
- On HubSpot, remove the MessageMind connected app from Settings, Integrations, Connected Apps if you also want to revoke access on HubSpot's side.
- To reconnect later, click the HubSpot card again and complete the OAuth round-trip. Previously selected meetings are not auto-restored; re-pick the links on the first settings-preview after reconnect.