- Install flow now assumes one admin-distributed service account JSON shared across the team. Each user creates their own Google Sheet and shares it with the SA email; per-user GCP project setup is gone. - DEPLOY.md: a step-by-step walkthrough for non-technical users following along with an AI agent (Terminal basics, screenshots-worth of expected output, common-error table). - scripts/append_row.py: sheet_id field accepts either a bare ID or a full Google Sheets URL; normalize_sheet_id() extracts the ID via regex. - scripts/setup.md: rewritten as an admin guide (one-time GCP setup, key rotation) plus a troubleshooting reference. - LICENSE: MIT (previously "private — internal use"). README license sections updated to match. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
5.9 KiB
Admin setup + troubleshooting
End users follow the 4-step install in the main README (or the gentler DEPLOY.md). This page covers two things they don't see:
- Admin setup — what you do once, before anyone can install
- Troubleshooting — the errors users will report back to you
Part A — Admin setup (one time)
The shared-key model: you create one Google Cloud service account and distribute its JSON key + email address to every user. Each user creates their own Google Sheet and shares it with that one service-account email. The service account can only write to sheets that have been explicitly shared with it.
A.1 — Create the Google Cloud project + service account
- Go to https://console.cloud.google.com/ and create a new project (e.g.
autoacct). - In the top search bar, search Google Sheets API → click the result → Enable.
- Left menu: IAM & Admin → Service Accounts → + Create Service Account.
- Name:
AutoACCT(any name works) - Click Create and Continue → Done (skip the optional IAM role step — the service account doesn't need any GCP roles, since it gains write access per-sheet via sheet-level sharing).
- Name:
- Click the new service account → Keys tab → Add Key → Create new key → JSON → Create.
A
.jsonkey file downloads to your browser's Downloads folder. - Copy the service account's email (e.g.
autoacct@<project>.iam.gserviceaccount.com). - Rename the downloaded file to
autoacct-sa.json(recommended — DEPLOY.md assumes this name).
A.2 — Distribute the key + email to users
The JSON is a private key. Use a secure channel:
| Channel | Verdict |
|---|---|
| Password manager shared vault (1Password, Bitwarden, Vaultwarden) | Recommended. Easy to revoke, no copies floating in inboxes. |
| Encrypted email / Signal / private DM | OK for small teams. |
| Cloud drive with strict per-user ACLs | OK if your org already uses one. |
| Plain email | Do not. |
| Git repo (even private) | Do not — .gitignore already excludes *-sa.json. |
Tell each user:
- The JSON file (attach / share)
- The service-account email (so they know who to share their sheet with)
- Pointer to
DEPLOY.mdif they want hand-holding, orREADME.mdif they're comfortable with the terminal
A.3 — Verify your own install first
Before sending the JSON to anyone, run through the user-side install yourself (Steps 1–11 of DEPLOY.md) to confirm everything works end-to-end. It's also a chance to catch any GCP-side misconfiguration before users hit it.
A.4 — Key rotation (when you need to)
Rotate the JSON key when:
- A user leaves the team (so you stop trusting their copy of the key)
- You suspect a leak
- Every 6–12 months as routine hygiene
To rotate:
- In GCP Console → Service Accounts → keys → Add Key (creates a new one) → download.
- Delete the old key in the same panel. (After deletion, any existing copies stop working.)
- Re-distribute the new JSON to all current users via your secure channel.
- Users replace their
~/.config/gcp/autoacct-sa.jsonwith the new file. No other changes needed —config.json, sheet sharing, etc. all stay intact.
Part B — Troubleshooting (user errors you'll see)
HTTP 403 / The caller does not have permission
The user forgot to share their sheet with the service-account email, or typed the email wrong. Tell them to re-do Step 8 in DEPLOY.md (or Step 3.5 in README.md). Confirm the email you sent them matches exactly.
HTTP 400: Unable to parse range
The worksheet value in config.json doesn't match the actual tab name. Most common cause: user has Chinese Sheets UI → tab is 工作表1, but they wrote "worksheet": "Sheet1". Fix the config.
HTTP 404 / Requested entity was not found
sheet_id in config.json is wrong. Tell user to re-copy the long string from /d/.../edit in their browser's URL bar.
FileNotFoundError ... autoacct-sa.json
The JSON file isn't where config.json expects. Common causes:
- User saved with a different filename (e.g.
autoacct-project-12345.json) and never renamed it. - User skipped the
mvstep and the file is still in Downloads.
Run ls -la ~/.config/gcp/ to check.
ImportError: No module named 'googleapiclient'
Python deps not installed. Run pip install google-api-python-client google-auth. If pip is missing, try pip3 or python3 -m pip install ....
config.json not found
User skipped the cp config.example.json config.json step. They need to be inside the skill directory when running it.
JSON parse error (Expecting value / Extra data)
Smart quotes from TextEdit, or a stray comma. Fix in plain-text mode, or have an AI agent repair the file.
Authorization or quota errors at scale
The shared SA shares one GCP project's quota. The default Sheets API quota (300 req/min per project) is generous for receipts — you would have to log thousands per minute to hit it. If you do hit quota, request an increase in the GCP console.
Part C — When to abandon the shared-key model
The shared-key model is right for trusted internal teams (you know everyone with a copy of the JSON). Move to a different model if any of these happen:
- You're distributing to strangers / customers. They can write to each other's sheets if the JSON leaks. Move to OAuth (each user authenticates with their own Google account).
- You can't trust users to keep the JSON private. Same answer.
- You need per-user audit trails. Sheets API logs only "the SA wrote" — you can't tell from GCP which user did it. (Sheet revision history still shows it, since each user has their own sheet.)
In those cases, see the git history for an earlier Apps Script–based variant, or design a small backend that holds the key server-side and exposes a per-user-authenticated endpoint.