Bookings integration

Jobber

Jobber integration overview
  • 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

  1. 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.'
  2. 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.
  3. On Jobber, pick the account you want MessageMind to work with and approve the requested scopes.
  4. 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.
  5. 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

  1. On /integrations click the Jobber card and then Integrate.
  2. The dashboard calls connectJobber({ userId }) and navigates to /jobber/connect on the MessageMind server.
  3. The server signs an OAuth state, stashes it in req.app.locals.jobberOauthState and redirects you to Jobber's authorization screen.
  4. You pick the Jobber account and approve the scopes.
  5. Jobber redirects back to /jobber/callback; the server validates the state, exchanges the code for tokens and persists them.
  6. The integration flips to Enabled and GET /jobber/status reports the live connection.

First-touch Jobber client fires 'jobber' once

  1. Jobber delivers CLIENT_CREATE (or REQUEST_CREATE) for a brand-new client.
  2. 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.
  3. MessageMind records the (Jobber client, contact) mark on the entity ledger.
  4. 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

  1. From the Jobber card, run a preview against POST /jobber/preview to list clients MessageMind can see on the connected account.
  2. Pick the clients to pull and start the import with POST /jobber/import-contacts; a job id is returned.
  3. Poll GET /jobber/import-status/:jobId until the import completes.
  4. 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.