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.