Gmail integration
The technical detail behind Selyf's Gmail access: scope, sync, and live updates.
See Authentication for the OAuth flow that grants this access, and Privacy & Data Usage for what happens to this data once it is synced.
Scope
Selyf requests the gmail.readonly scope only (see Authentication). This scope does not permit sending, deleting, or modifying mail — that boundary is enforced by Google at the API level, not by application logic alone.
What gets synced
A sync fetches inbox message metadata — subject, sender, a short snippet, timestamps, unread status — in bounded, paginated batches (GET /api/mail/threads, limit 1-100, default 20). Message bodies are fetched on demand, only for a thread that is actually opened (GET /api/mail/threads/:threadId), and are never bulk-fetched for storage.
Live updates
A Gmail watch notifies the API of inbox changes via a Google Cloud Pub/Sub pull subscription. The API polls that subscription; it does not expose a public webhook that Google or anyone else calls directly. A missed or expired notification falls back to a full resync, so updates never silently stop.
Idempotent, resumable sync
A sync always resumes from the API's own last-known Gmail history checkpoint, never from a notification's own payload, so a duplicate or out-of-order notification is harmless and re-running a sync never creates duplicate data. Sync requests are also guarded per account against concurrent overlap.
Disconnecting
POST /auth/google/disconnect (see Authentication) revokes access with Google and cancels the Gmail watch immediately, rather than letting it continue receiving notifications until its natural expiration.