Google Calendar
Two-way sync bookings and appointments between the CRM and a Google Workspace calendar. Events created in either place appear in both within 30 seconds.
Before you start
- A Google Workspace account (works with personal Gmail too, but you will see the "unverified app" warning during OAuth). Workspace admins can pre-authorise the CRM to skip that.
- Access to the Google Cloud Console with permission to create a project. If you use Workspace at a large company, you may need IT to do steps 1-4.
- Know which calendar you want to sync. Most people want their primary calendar. If you use a shared "Bookings" calendar, that works too but you sync one calendar per user.
- 20 minutes for the Google Cloud setup. It is fiddly the first time.
Current UI limitation
The CRM currently pulls Google OAuth Client ID and Client Secret from constants in config/bootstrap.php. There is no self-serve UI for pasting them yet. Follow this whole guide to generate the credentials, then send Client ID and Client Secret to support (andrew@validusmedia.com) to install them for your instance. Once installed, connecting your own calendar is one click from the CRM.
Step 1: Create a Google Cloud project
- Go to console.cloud.google.com.
- Click the project selector in the top bar (says "Select a project"), then New project.
- Name it
Unavoidable CRM. Leave organisation as-is.
- Click Create. Wait 15 seconds for provisioning.
- Once created, click the project selector again and select the new project.
Step 2: Enable the Calendar API
- In the top search bar, type Google Calendar API.
- Click the result Google Calendar API.
- Click Enable.
- Wait until the API dashboard opens (about 10 seconds).
Step 3: Configure the OAuth consent screen
Google will not let you create OAuth credentials until you tell it what your app is called and what data you want to touch.
- Left nav: APIs and Services > OAuth consent screen.
- User type: External (unless you are on Workspace and only want internal users). Click Create.
- App information:
- App name:
Unavoidable CRM
- User support email: your own email
- App logo: optional, upload a 120x120 PNG if you want to remove the "unverified" grey icon
- App domain:
- Application home page: your CRM URL (e.g.
https://crm.example.com)
- Application privacy policy link:
https://crm.example.com/privacy-policy
- Application terms of service link:
https://crm.example.com/legal
- Authorized domains: add your CRM domain without
https:// or path (e.g. crm.example.com).
- Developer contact: your email.
- Click Save and continue.
- On the Scopes step, click Add or remove scopes. Tick
.../auth/calendar.events. Click Update then Save and continue.
- Skip Test users for now (add your own email if the app is in Testing mode).
- Click Back to dashboard.
Step 4: Create the OAuth client
- Left nav: APIs and Services > Credentials.
- Click + Create credentials then OAuth client ID.
- Application type: Web application.
- Name:
Unavoidable CRM web client.
- Authorized JavaScript origins: add
https://crm.example.com (your CRM origin).
- Authorized redirect URIs: add
https://crm.example.com/api/google-oauth. The path is exactly /api/google-oauth - not /api/google_oauth, not /api/google-oauth.php. The router handles both routes but the URI you register here must match what the CRM sends.
- Click Create.
- Copy the Client ID (looks like
1234567.apps.googleusercontent.com).
- Copy the Client secret (looks like
GOCSPX-abc123...).
Step 5: Send the credentials to support
Until the self-serve UI ships, email Client ID and Client Secret to andrew@validusmedia.com via an encrypted channel (Bitwarden Send or 1Password sharing). Do not paste them into a normal email or Slack DM.
Support will install them and confirm when done - usually within one business day.
Step 6: Connect your calendar
Once support confirms the OAuth client is installed:
- In the CRM go to Settings > Security and 2FA.
- Scroll to Connected accounts.
- Click Connect Google Calendar.
- Google's OAuth screen opens. Choose the Google account whose calendar you want to sync.
- If you see "Google has not verified this app", that means the OAuth consent screen is still in Testing status. Click Advanced then Go to Unavoidable CRM (unsafe). It is safe because it is your own app. To remove the warning permanently, submit the app for Google verification (7-day review).
- On the permissions screen, tick See, edit, share and permanently delete all the calendars you can access using Google Calendar (this is what the
calendar.events scope means). Click Continue.
- You are redirected back to the CRM with a green Google Calendar connected banner.
Step 7: Pick which calendar
If your Google account has multiple calendars (primary, work, holidays, family), the CRM defaults to your primary calendar. To change:
- In Settings > Security and 2FA > Connected accounts, click Change calendar next to the Google Calendar entry.
- Pick from the dropdown of calendars the connected account can access.
- Save.
How to test it works
- Create an appointment in the CRM: Appointments > + New, set a contact, a date and a time.
- Within 30 seconds, refresh Google Calendar in a new tab. The event should appear with the contact's name in the title.
- Create an event directly in Google Calendar for tomorrow at 10am, title "CRM test".
- Within 30 seconds, refresh the CRM appointments page. The event should appear.
- Edit the Google event to move it to 11am. Refresh the CRM. The time should update.
- Delete the Google event. The CRM entry should disappear (or be marked cancelled, depending on your setting).
Common problems
- OAuth returns "redirect_uri_mismatch"
- The Authorized redirect URI in Google Cloud Console does not match what the CRM actually sends. Look at the exact URL after the "&redirect_uri=" in the error page, and paste that exact string back into the Google credentials editor.
- OAuth returns "access_denied"
- You clicked "Cancel" on the Google permissions screen, or your Workspace admin has blocked third-party apps. If admin-blocked, only they can whitelist the CRM's Client ID.
- Calendar connects but events do not sync
- The chosen calendar is a subscribed public calendar (holidays, weather). Those are read-only. Switch to a calendar you own.
- Events sync one way but not the other
- Push notifications (webhooks from Google to CRM) require the CRM to be publicly reachable and use HTTPS. If your CRM is behind auth or on a private network, Google -> CRM push will not work; only the 15-minute poll will. Fix: make the CRM public via a reverse proxy, or accept the 15-minute lag.
- "Insufficient authentication scopes"
- The OAuth consent screen has
calendar.readonly ticked but not calendar.events. Re-do step 3.9 with the write scope, then disconnect and reconnect the calendar so the new scope is granted.
- Sync worked yesterday, broken today
- OAuth refresh token expired. Happens if you disconnected the app on Google's side, or the app is still in Testing status (test-mode refresh tokens expire after 7 days). Move the OAuth app to Production, then reconnect.
What this unlocks in the CRM
Every appointment shows in your Google Calendar so you get the reminders your phone already does. Booked calls from the AI Receptionist automatically appear in your calendar with the caller's number and a link back to the CRM contact. External events (Google Meet invites, holidays) appear in the CRM appointments view so you never double-book. And your team's shared calendar becomes the single source of availability for the booking widget on your public site.