OffGridSchedula / docs /gcal-verify.md
ParetoOptimal's picture
Initial Commit
0366d65
|
Raw
History Blame Contribute Delete
3.77 kB
# Verifying the Google Calendar connection end-to-end
> **Private-Space gotcha (the OAuth popup 404):** while the Space is private,
> `*.hf.space` URLs answer Hugging Face's 404 page for any request that lacks
> the signed access cookie. The app viewed EMBEDDED on huggingface.co
> authenticates its iframe with a short-lived signed URL, but the OAuth POPUP
> is a separate top-level window β€” when the subdomain cookie is missing or
> expired, **Connect opens a 404**. Fix: always open
> `https://paretooptimal-offgridschedula.hf.space` directly in its own tab
> (the redirect re-mints the cookie for the whole subdomain), then connect
> from there. Making the Space public would remove this entirely, at the cost
> of the deployed source tree becoming publicly browsable β€” deliberately NOT
> done (2026-06-12).
Two layers of verification exist:
1. **In-app, automatic** β€” on every page load, `wireGcal()` round-trips the stored
token to `POST /oauth2/check`, which makes one real (scope-compatible) Google
API call. The Step 2a row and the export-bar badge upgrade from
"βœ“ connected" to **"βœ“ connected Β· verified"** when Google answers; a
*definitive* rejection (revoked/invalid token) clears the stored token and
flips everything to "not connected". Transient problems (OAuth env unset,
network down, `SERVE=gradio` mode where FastAPI routes aren't served) never
destroy the token β€” the UI just stays at the local shape-check state.
2. **Scripted E2E** β€” `scripts/verify_gcal_e2e.py` proves the whole chain:
agent-extracted event β†’ real push β†’ API readback (title/location/start/
reminder) β†’ cleanup.
## Browser loop (manual)
1. Run locally with OAuth configured:
```
set GOOGLE_OAUTH_CLIENT_ID=... # a Google Cloud OAuth "Web application" client
set GOOGLE_OAUTH_CLIENT_SECRET=...
set SERVE=uvicorn
python app.py
```
2. Open http://localhost:7860, switch to **☁️ Online**, open Step 2a
**"πŸ”— Connect your calendar"** β†’ click **Connect** on the Google row β†’
consent in the popup. The row flips to "βœ“ connected", then upgrades to
**"βœ“ connected Β· verified"** within ~1s (the `/oauth2/check` round-trip).
3. Paste the appointment text (the CANON sample in `tests/test_agent.py`) β†’
**Run the agents** β†’ the export toolbar appears with the badge
**"Google: βœ“ connected Β· verified"** next to the three buttons.
4. Click **Add to Google Calendar** β†’ the status line shows the created event
link; open it: *Mon Jun 22 2026, 10:15–11:00, 112A West 72nd Street,
New York, NY 10023*, 60-minute reminder.
5. **Reload the page** β†’ still verified, no re-prompt (the acceptance test for
"never asks again").
### Negative paths
- Revoke access at https://myaccount.google.com/permissions β†’ reload β†’ the
check is definitive: token is cleared, every surface shows "not connected".
- Unset the OAuth env vars (or kill the network) β†’ reload β†’ stays at plain
"βœ“ connected" β€” transient failures never log the user out.
- Click **disconnect** in Step 2a β†’ flips everywhere instantly.
## Scripted loop
One-time: after connecting in the browser, copy the `gcal_token` value from
DevTools β†’ Application β†’ Local Storage into a file (e.g. `tok.json` β€” it's
gitignored territory; don't commit it).
```
python scripts/verify_gcal_e2e.py --token-file tok.json --check-only # liveness only
python scripts/verify_gcal_e2e.py --token-file tok.json # full E2E
```
The full run pushes the CANON event with a nonce in the title (`[e2e-xxxxxx]`),
reads it back through the API, asserts summary/location/start-instant/reminder,
and deletes it (use `--keep` to inspect it in the calendar first). Exit code 0
= all checks passed.