- CategoryBookings
- AuthOAuth
Overview
Jobber connects on /integrations in the dashboard. Click the Jobber card and the "Connect Jobber" modal opens; nothing is pasted because MessageMind runs its own Jobber public app. Click Integrate and the dashboard calls connectJobber({ userId }) which navigates the browser to /jobber/connect on the MessageMind server; the server signs an OAuth state, stashes it in req.app.locals.jobberOauthState, and redirects you to Jobber's authorization screen. After consent, Jobber bounces back to /jobber/callback, MessageMind exchanges the code for tokens and persists them. From then on the AI talks to Jobber over GraphQL at https://api.getjobber.com/api/graphql, and Jobber's CLIENT_CREATE and REQUEST_CREATE webhooks drive contact creation and the 'jobber' automation trigger behind a 90-day entity ledger that keeps a redelivery, a parallel create or a sync replay from double-firing. The booking action is the configured 60-minute free-survey workflow with a fixed team assignment; it is not a general paid-job or invoicing action.
What MessageMind can do with it
- Create a MessageMind contact when a client is first created in Jobber (CLIENT_CREATE).
- Create a MessageMind contact when a client first appears via a Jobber request (REQUEST_CREATE), merging with any contact a parallel CLIENT_CREATE for the same client has already made.
- Fire the 'jobber' automation trigger exactly once per (Jobber client, created contact) pair; a redelivered webhook, a parallel create or a sync replay never fires it twice.
- Preview and import existing Jobber clients into MessageMind as contacts, with a job id you can poll for status.
- Write back to a linked Jobber client when the matching MessageMind contact changes, through the Jobber GraphQL API.
- Read scheduled visits and create the configured free-survey job and visit when the account is used for that booking workflow.
- Keep the ledger of past firings for 90 days so a sweep retry delivers the same envelope.
Requirements
- A Jobber account with permission to install a third-party app and approve the scopes the MessageMind Jobber app requests.
- A MessageMind plan on Starter, Professional or Enterprise. The Jobber card on /integrations is plan-gated.
- A deployed MessageMind Jobber public app on the server side (nothing to configure on your side; the modal mentions Client ID, Client Secret and Domain but no such fields are surfaced).
How to connect
- Open /integrations in the dashboard and click the Jobber card. The 'Connect Jobber' modal opens with the description: 'Enter your Jobber Client ID, Client Secret, and Domain to connect. Once connected, MessageMind can read CRM data (e.g., leads, contacts, opportunities) and trigger your selected automations.'
- Click Integrate. The dashboard calls connectJobber({ userId: user?._id }); the browser is navigated to /jobber/connect on the MessageMind server, which mints and signs an OAuth state (kept in req.app.locals.jobberOauthState) and redirects you to Jobber's authorization screen.
- On Jobber, pick the account you want MessageMind to work with and approve the requested scopes.
- Jobber redirects back to /jobber/callback on the MessageMind server, which validates the state against the server-side map, exchanges the code for access and refresh tokens and persists them against your tenant.
- The integration status flips to Enabled. From then on, GET /jobber/status reports the live connection and the AI can read Jobber over GraphQL.
Authentication and permissions
- Mechanism
- OAuth 2.0 authorization-code flow against MessageMind's Jobber public app. The /jobber/connect handler signs a state value and stashes it in req.app.locals.jobberOauthState so the /jobber/callback handler can validate it before token exchange. There is no bring-your-own client ID: the Jobber client credentials live on the MessageMind server.
- Credentials
- No credentials to paste. After the OAuth round-trip MessageMind stores Jobber's access token and refresh token on your integration record; the refresh token renews the access token transparently.
Available data and actions
Reads
- Jobber clients, fetched over the GraphQL API at https://api.getjobber.com/api/graphql with an X-JOBBER-GRAPHQL-VERSION header, used to list and preview clients before import.
- Jobber CLIENT_CREATE webhooks (used to sync the client into MessageMind and to fire the 'jobber' automation trigger).
- Jobber REQUEST_CREATE webhooks (used when a client first appears through a Jobber request).
- Scheduled visits and client/property records needed by the configured survey-booking workflow.
Writes
- A MessageMind contact for a newly-seen Jobber client.
- A Jobber client, created or updated through the GraphQL API when a MessageMind contact is pushed to Jobber for the first time or when its matching Jobber client changes.
- A client and property when needed, a one-off free-survey job and the schedule for its visit.
- An entity-ledger mark recording that the 'jobber' trigger fired for this (Jobber client, contact) pair, kept for 90 days.
AI agent use cases
- Start an onboarding or welcome automation the first time a Jobber client lands in MessageMind, whether they arrived via Jobber's client create or via a Jobber request.
- Avoid double-firing when CLIENT_CREATE and REQUEST_CREATE land for the same Jobber client at nearly the same time: the identity lock merges them into one contact, and the ledger makes the second webhook a no-op.
- Bring an existing Jobber client base into MessageMind as contacts through the preview and import flow, then let the AI resume conversations with people your field team already knows.
- Let the AI quote availability and create a Jobber booking from inside a chat when Jobber is the connected Bookings-section provider.
Configuration
- Ledger retention: 90 days per fired event, well inside Jobber's retry window, so a legitimate retry is recognized as a duplicate rather than firing the trigger again.
- Delivery: the Jobber handler starts every active campaign on the 'jobber' trigger itself and reports failure only when nothing started, so the sweep may retry a failed delivery safely.
- Bookings coexistence: the Jobber card is presented under the Bookings section via categoryMerge.CRM_TO_BOOKINGS, and section-based blocking lets it coexist with Cal.com, Acuity, SimplyBook, Square, Setmore, Google Calendar, GHL Calendar, Amelia, Zoom, Teams and Phorest on the same tenant.
Example workflows
First-time OAuth connect
- On /integrations click the Jobber card and then Integrate.
- The dashboard calls connectJobber({ userId }) and navigates to /jobber/connect on the MessageMind server.
- The server signs an OAuth state, stashes it in req.app.locals.jobberOauthState and redirects you to Jobber's authorization screen.
- You pick the Jobber account and approve the scopes.
- Jobber redirects back to /jobber/callback; the server validates the state, exchanges the code for tokens and persists them.
- The integration flips to Enabled and GET /jobber/status reports the live connection.
First-touch Jobber client fires 'jobber' once
- Jobber delivers CLIENT_CREATE (or REQUEST_CREATE) for a brand-new client.
- MessageMind creates or merges a contact for that Jobber client under an identity lock, so a parallel delivery for the same client ends on the same surviving contact.
- MessageMind records the (Jobber client, contact) mark on the entity ledger.
- Every active campaign on the 'jobber' trigger starts once; a second webhook for the same client finds the mark and is a no-op.
Import existing Jobber clients
- From the Jobber card, run a preview against POST /jobber/preview to list clients MessageMind can see on the connected account.
- Pick the clients to pull and start the import with POST /jobber/import-contacts; a job id is returned.
- Poll GET /jobber/import-status/:jobId until the import completes.
- Confirm the import with POST /jobber/confirm-import so the selected clients land as linked MessageMind contacts.
Limitations
- The 'jobber' trigger fires once per Jobber client, keyed by the Jobber client id and the created contact id. A Jobber client whose MessageMind contact is still live will not fire the trigger again on later Jobber events.
- The connection uses MessageMind's Jobber public app. There is no bring-your-own Jobber app flow in /integrations today; the modal description mentioning Client ID, Client Secret and Domain is misleading and not surfaced as fields.
- The verified Jobber-driven automation triggers today are CLIENT_CREATE and REQUEST_CREATE. Quote, job, invoice and other Jobber object events are not exposed as MessageMind triggers.
- 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.
- The current booking workflow is configured for a 60-minute free survey with a fixed team assignment. It is not a general quote, paid-job, deposit or invoice-sending workflow.
Disconnect and reconnect
- On /integrations, open the Jobber card and call DELETE /jobber/disconnect. The stored OAuth tokens are cleared from your MessageMind tenant and future reads and writes against Jobber stop.
- Previously imported contacts stay in MessageMind, and clients MessageMind created or updated stay in Jobber; disconnecting does not delete anything on either side.
- To reconnect later, click the Jobber card again and complete the OAuth round-trip from /jobber/connect through /jobber/callback.