Google Drive Sync (Service Account)
Quick Answer
Use this guide to run and operate the Google Drive service-account sync flow, including configuration, schedule behavior, and verification.
This guide covers a production flow that continuously syncs files from a Google Drive folder into Breyta blob storage, and writes per-file metadata docs (KV-backed-by-Firestore) for querying.
Why service account auth (not user OAuth)
Google OAuth user auth is not suitable for continuous, unattended syncing (e.g. every 2 hours), because it requires the user to re-authenticate periodically. For this integration we use a Google service account (SA) so the flow can mint OAuth access tokens on a schedule without user interaction.
Flow + schedule
| Item | Value |
|---|---|
| Flow slug | google-drive-folder-sync |
| Trigger | Schedule every 2 hours (cron: 0 */2 * * *, timezone: UTC) |
| Folder input | Drive folder URL or raw folder id |
| Archive slot | :archive (:blob-storage) |
Required secret
The flow uses :auth {:type :google-service-account ...} on :http steps.
| Secret setting | Value |
|---|---|
| Secret slot / ref | google-drive-service-account |
| Secret value | Full JSON service account key payload |
Configure it on the draft target:
| Step | Action |
|---|---|
| 1 | Save service account JSON to ./secrets/google-drive-sa.json (local only; do not commit). |
| 2 | breyta flows configure google-drive-folder-sync --set google-drive-service-account.secret=@./secrets/google-drive-sa.json |
| 3 | breyta flows run google-drive-folder-sync --input '{"folder":"https://drive.google.com/drive/folders/<id>?usp=sharing","cursor_key":"google-drive-sync:cursor"}' --wait --pretty |
Required storage setup
The flow also declares a blob-storage slot :archive.
That slot always requires the installer to choose a storage root.
Recommended setup values:
| Setting | Example |
|---|---|
| Connection binding | platform |
| Storage root | gdrive |
If you change the storage root, persisted files and runtime resource pickers both move to that new storage location automatically.
Run now (manual)
Incremental run (uses the shared cursor)
This is the safest way to “run now”, because it uses the same cursor the schedule uses.
breyta flows run \
google-drive-folder-sync \
--input '{"folder":"https://drive.google.com/drive/folders/<id>?usp=sharing","cursor_key":"google-drive-sync:cursor"}' \
--wait --pretty
Isolated/forced scan (separate cursor)
Use a unique cursor_key to force a “fresh” scan without disturbing the schedule cursor.
breyta flows run \
google-drive-folder-sync \
--input '{"folder":"https://drive.google.com/drive/folders/<id>?usp=sharing","cursor_key":"google-drive-sync:cursor:manual-check:20260101T000000Z"}' \
--wait --pretty
Notes:
| Mode | When to use | Cursor behavior |
|---|---|---|
| Incremental run | Safe manual run aligned with schedule state | Uses shared cursor (google-drive-sync:cursor) |
| Isolated/forced scan | One-off fresh scan without affecting schedule cursor | Uses unique cursor_key |
| Note | Guidance |
|---|---|
| Singleton flow run ids | Repeated manual starts may reuse stable workflow id; verify by timestamps in runs list/runs show. |
--installation-id on manual runs | Avoid unless you explicitly need a specific installation target KV namespace. |
What gets written
Blobs
Downloads are persisted through the :archive slot.
The slot contributes the configured storage root, and the step contributes the folder id:
- configured root:
gdriveby default :path "<folder-id>":filename "<name>.<ext>"
Resulting runtime path shape:
workspaces/<ws>/storage/<root>/<folder-id>/<name>.<ext>
Google Docs/Sheets are exported to:
| Source type | Export type |
|---|---|
| Docs | text/plain (.txt) |
| Sheets | xlsx |
| Other Google-apps types | pdf |
Per-file metadata docs (KV-backed-by-Firestore)
For each downloaded file the flow writes a KV doc:
| Item | Shape |
|---|---|
| Key format | google-drive-sync:meta:<folder-id>:<file-id> |
| Value fields | :folder-id, :file-id, :blob-filename, plus Drive fields like :name, :mimeType, :modifiedTime, :size, :driveId |
How to verify a run
After a run completes:
| Check | Expected signal |
|---|---|
download-files step | successes / failures counts match expectations. |
meta-<file-id> KV writes | Entries show {:success true, :key "...", :created? ...}. |
Cursor write step (set-cursor) | Updates google-drive-sync:cursor (or your custom cursor key). |