Documentation
Google Workspace
Service account setup, Calendar sync, Drive folders and Gmail send + tracking.
How it works
BillBoy uses one Google service account with domain-wide delegation. For every API call it signs a JWT with the CRM user’s google_workspace_email as the subject, so Google sees the action as that user: events land in their calendar, files in their Drive, emails go out from their Gmail. No per-user OAuth dance, no SDK — plain HTTP.
Setup
- In Google Cloud, create a project, enable the Calendar, Drive and Gmail APIs, and create a service account. Download its JSON key.
- In the Workspace admin console (Security → API controls → Domain-wide delegation), authorise the service account’s client id with the scopes:
https://www.googleapis.com/auth/calendar https://www.googleapis.com/auth/drive https://www.googleapis.com/auth/gmail.send https://www.googleapis.com/auth/gmail.readonly - Place the JSON key outside the web root and point
GOOGLE_SA_JSONto it in.admin/.env. - For each CRM user, fill Google Workspace email (and optionally a calendar id other than
primary). - Keep the cron running: it drains the job queue every minute and polls calendars every five minutes.
Calendar
CRM → Calendar lists events with a Sync state (Local, Synced, RemoteDeleted, Conflict). Creating an event in BillBoy pushes it to Google; changes made in Google Calendar are pulled with incremental sync tokens. Events can be linked to a contact and an activity, and the activity’s Google event field opens it in Google Calendar.
Drive
Each contact gets a folder {Company}/{Contact}/ under the user’s Drive root, created the first time it is needed. Files uploaded from the contact’s Files tab or the Drive browser go straight to Google Drive; the CRM stores the file id, web link, name, type and size. Quote and invoice PDFs are saved to the same tree. Use Share / Copy link on a file to make it public.
Gmail
From a contact’s Emails tab, or when sending a quote or invoice, compose from an email template. The message is sent through the user’s Gmail (so it appears in their Sent folder) and recorded with its Gmail message and thread ids. A tracking pixel and rewritten links record opens, clicks and bounces as email events; a reply creates a threaded follow-up. Incoming mail can also be matched to activities on the contact.
Troubleshooting
- 401 / unauthorized_client: the client id is not authorised for that scope in the admin console, or the user’s Workspace email is wrong.
- Nothing syncs: check that the cron runs and look at Settings → Job queue for Failed rows — the last error is stored on each job.
- Conflicts: an event edited on both sides between polls shows Conflict; open it and choose which version to keep.