From 534c82ba4d68ef0b92be457052da339e09bfae0b Mon Sep 17 00:00:00 2001 From: Laszlo Mari Date: Mon, 6 Jul 2026 20:13:00 +0400 Subject: [PATCH] domain-skills: Google Cloud service accounts + Sheets sharing/API Deep links for SA creation and key download, the external-share double-confirm flow in the Sheets share dialog, and API-first patterns (data validation read, developer-metadata row tracking). Co-Authored-By: Claude Fable 5 --- domain-skills/google-cloud/service-accounts.md | 15 +++++++++++++++ domain-skills/google-sheets/sharing-and-api.md | 16 ++++++++++++++++ 2 files changed, 31 insertions(+) create mode 100644 domain-skills/google-cloud/service-accounts.md create mode 100644 domain-skills/google-sheets/sharing-and-api.md diff --git a/domain-skills/google-cloud/service-accounts.md b/domain-skills/google-cloud/service-accounts.md new file mode 100644 index 00000000..1a4d16d7 --- /dev/null +++ b/domain-skills/google-cloud/service-accounts.md @@ -0,0 +1,15 @@ +# Google Cloud Console — service accounts & API keys + +## Deep links (skip all menu navigation) + +- Enable an API: `https://console.cloud.google.com/apis/library/.googleapis.com?project=` — one `Enable` button, redirects to the API overview when done. +- Create a service account: `https://console.cloud.google.com/iam-admin/serviceaccounts/create?project=` +- Keys page for an SA: `https://console.cloud.google.com/iam-admin/serviceaccounts/details//keys?project=` — the unique id is shown as "OAuth 2 Client ID" in the SA list right after creation. + +## Traps + +- The console URL after login includes the currently selected project as `?project=...` — reuse it instead of asking the user which project to use for throwaway integrations. +- SA creation: typing the display name auto-fills the account ID; the resulting email is shown live under the ID field (`@.iam.gserviceaccount.com`). Grab it from there — you need it to share resources with the SA. +- "Create and close" (skip steps 2–3) is enough when access will be granted by sharing a resource (e.g. a Google Sheet) rather than IAM roles. +- Key creation: Add key → Create new key → JSON (preselected) → Create. The JSON downloads silently to `~/Downloads/-.json` — no save dialog. Poll `ls -t ~/Downloads/-*.json`. +- Sheets/Drive access for an SA needs NO project roles: just share the document with the SA's email as Editor. The SA can't accept invites; sharing is enough. diff --git a/domain-skills/google-sheets/sharing-and-api.md b/domain-skills/google-sheets/sharing-and-api.md new file mode 100644 index 00000000..c84e3d8f --- /dev/null +++ b/domain-skills/google-sheets/sharing-and-api.md @@ -0,0 +1,16 @@ +# Google Sheets — sharing dialog & API-first workflows + +## Share a sheet with a service account + +Share button (top right) → type the SA email → pick the autocomplete entry → chip appears with a role dropdown (defaults to Editor) → optionally uncheck "Notify people" (SAs can't read mail) → `Share`. + +- **Workspace orgs show an external-share interstitial** ("...is external to ... Share anyway?"). Click `Share anyway`, which returns you to the share dialog — you must click `Share` AGAIN. The dialog closing is the success signal. +- Trap: after the dialog closes, stray clicks land on the grid and put a cell into edit mode. If that happens press Escape (twice is safe) — verify the formula bar shows the original value before moving on. + +## Prefer the API over DOM scraping + +The Sheets grid is canvas-rendered — DOM selectors are useless for cell data. Once a service account (or OAuth token) exists, read/write via `sheets.googleapis.com/v4` with plain `fetch`; a service-account JWT is ~20 lines of `node:crypto`/`python` with scope `https://www.googleapis.com/auth/spreadsheets`, no SDK needed. + +- Read dropdown (data validation) options without clicking anything: `GET /v4/spreadsheets/?ranges=Sheet1!B2:B2&includeGridData=true&fields=sheets.data.rowData.values.dataValidation` → `ONE_OF_LIST` values. `strict: true` means unlisted values are rejected chips. +- Track "your" rows robustly with **row-level developer metadata** (`createDeveloperMetadata` on a ROWS dimensionRange, then `POST /developerMetadata:search`). Row numbers shift when humans sort/insert/delete; metadata moves with the row. `values.append` returns `updates.updatedRange` — parse the row number from it to tag the row you just appended. +- The sign-in wall (`accounts.google.com/v3/signin`) means the whole Chrome profile is logged out, not just Sheets — stop and ask the user; there may be no account chooser at all.