Gmail realtime — the account lifecycle (administrator)
Once a Gmail mailbox has push enabled, MailDesk manages the whole lifecycle for you: it registers a Gmail watch, renews it before it expires, falls back to scheduled polling if a notification is ever missed, reflects deletes live in the open inbox, and gives you an honest, on-demand way to check the OAuth token is still valid. This page walks through that lifecycle end to end, so you know what each state means and what — if anything — you ever have to do.
Once a Gmail mailbox has push enabled, MailDesk manages the whole lifecycle for you: it registers a Gmail watch, renews it before it expires, falls back to scheduled polling if a notification is ever missed, reflects deletes live in the open inbox, and gives you an honest, on-demand way to check the OAuth token is still valid. This page walks through that lifecycle end to end, so you know what each state means and what — if anything — you ever have to do.
Available in: Pro. The realtime lifecycle is part of the MailDesk Pro module. Basic always uses scheduled background sync. The mailbox is connected with the same Gmail OAuth credentials used for normal sync — realtime push reuses that connection and asks for no new permissions.
Honest expectation on speed
With push enabled, new Gmail mail typically appears in MailDesk in about 3 to 8 seconds. This is genuine provider push — Google notifies MailDesk the moment mail arrives — but it is not instantaneous: the notification still has to travel to your server and trigger a short sync. MailDesk does not claim "instant" delivery.
The lifecycle at a glance
| Phase | What happens | Who does it |
|---|---|---|
| Connect | Mailbox connected over Gmail OAuth and syncing | Administrator (one time) |
| Watch registered | gmail.users.watch registered against your Pub/Sub topic |
Setup assistant |
| Active | Google publishes a notification on every inbox change; the webhook triggers a sync | Automatic |
| Renew | The watch is refreshed before its 7-day limit | Background job (~every 6 days) |
| Silence → fallback | If notifications stop, scheduled polling keeps mail flowing | Background job |
| Disconnect / revoke / delete | Token loss surfaces honestly; deletes reflect live in the inbox | Provider + MailDesk |
The rest of this page takes each phase in turn.
Connect — reuse the existing Gmail OAuth (no new scopes)
Realtime push does not introduce a new sign-in or a new permission prompt. It reuses the Gmail OAuth refresh token the mailbox already stored for normal sync.
- The watch is registered with the customer's existing Gmail OAuth token; the
gmail.modifyscope that already powers sync also coversgmail.users.watch. No additional consent is requested. - Before registering, MailDesk runs a readiness guard on the account. It confirms the account
is a Gmail account, has a connected OAuth server with a stored refresh token, and that the
token's scope set includes at least one of the Gmail scopes that allow
users.watch(https://mail.google.com/orgmail.modify). If any of these is missing, registration is refused with a clear reason rather than failing silently later.
If you have not connected the mailbox yet, start with Gmail OAuth setup. To turn on realtime, run the guided Gmail realtime push setup assistant on the mailbox account.
Administrator-only
Enabling Gmail realtime is restricted to MailDesk administrators (the Mailbox administrator access group). The assistant refuses to register a watch for a user without that access.
Watch registered — what gets stored
When you enable realtime, MailDesk calls Gmail's users.watch against the Pub/Sub topic in
your own Google Cloud project, scoped to the INBOX label. On success it records a single
push-subscription row for the account, with provider gmail:
- the topic resource name as the watched resource;
- Gmail's returned
historyIdas the subscription identifier (and as the lower bound for the first incremental fetch); - the watch expiration date;
- state active, with the last-error field cleared and the failure counter reset to zero.
MailDesk stores only non-secret identifiers — your project id, the fully-qualified topic name, and the signer service-account email — plus the settings its webhook needs to verify incoming notifications. No Google Cloud secret is ever stored on the MailDesk side.
Push shortens latency — it does not replace the engine
A push notification never carries the email itself. It only tells MailDesk "this inbox changed," which triggers the same incremental Gmail fetch the scheduled jobs use. Push makes mail arrive sooner; it does not change how messages are fetched, stored, or shown.
Active — how a single message arrives
While the watch is active, every change to the Gmail inbox produces one notification that travels Pub/Sub → MailDesk webhook → incremental sync → your screen:
- Google publishes a Pub/Sub notification to the topic in your project.
- Pub/Sub delivers it to MailDesk's webhook at
<web.base.url>/maildesk/push/gmail. The route is POST-only and public, and it accepts a body no larger than 64 KB. - The webhook verifies the notification's OIDC signature: it requires a
Authorization: Bearertoken (missing → HTTP 401), checks the token's audience matches your configured audience, and confirms the signer is on the saved allow-list. A bad signature is rejected as HTTP 403; missing audience or allow-list configuration returns HTTP 503. The token and body are never logged. - On a valid notification MailDesk runs its usual incremental Gmail fetch for just that
mailbox and returns a fast
202 Accepted. - The open MailDesk screen refreshes itself live over Odoo's websocket, so the new message appears for you and any teammate viewing the same mailbox once it is ingested.
Bodies are warmed in the background so messages open instantly — see Prefetch & cache.
Renew — automatic, well before the 7-day limit
A Gmail watch is valid for at most 7 days. You never renew it by hand.
- A background renewal job refreshes each active Gmail watch at about 6 days, leaving
roughly a day of headroom before the provider limit. It re-runs
users.watchagainst the same stored topic and updates the expiration, the last-renewal timestamp, and the state. - The renewal job selects subscriptions whose expiration falls within the next 24 hours, so a watch is always refreshed ahead of time.
- If a renewal call fails, MailDesk records the error on the subscription and increments a failure counter, then tries again on the next run — it does not give up after one failure.
Renewal is automatic
There is nothing to babysit. As long as the OAuth token stays valid and the topic still exists in your project, the watch is kept alive indefinitely without any administrator action.
Silence → fallback polling keeps mail flowing
Pub/Sub delivers at least once, not exactly once — a notification can occasionally be dropped. MailDesk treats that as a safety problem, not an outage, and the fallback is automatic.
- A silence detector runs in the renewal job. If an active subscription has received no notification within a 6-hour threshold, MailDesk marks it for recovery and stamps the account so the existing polling cron resyncs it on its next run.
- That fallback sync runs about every 2 minutes, so even if push goes completely quiet, new mail still surfaces within the normal scheduled interval. No mail is ever lost.
- Once notifications resume — or the catch-up sync has run — the subscription returns to its normal active state.
Push never blocks normal sync
Realtime push sits on top of scheduled background sync. If a notification is delayed or missed, MailDesk notices the silence and runs a catch-up sync automatically. Push only ever makes mail arrive sooner — it can never make it arrive late.
Disconnect, token revoke, and move-to-Bin
If the OAuth token is revoked or expires
A Gmail refresh token can stop working — the user revoked MailDesk at their Google account,
the OAuth client secret rotated, the token aged out, or the scopes no longer cover
users.watch. When that happens:
- New attempts to register or renew the watch fail with a typed, human-readable reason. A revoked or expired token surfaces as an OAuth invalid condition; a missing scope surfaces as a scope condition that tells you to reconnect and re-consent.
- Existing mail is never lost. Until you reconnect, the fallback polling described above keeps the inbox up to date on the scheduled interval, and realtime resumes automatically the next time a valid watch is registered.
- To fix it, reconnect the mailbox under Settings → Mailboxes and re-consent the Gmail sign-in, then re-open the realtime assistant. See the honest token status below for how to confirm the token state first.
If you disconnect the mailbox
Disconnecting the OAuth connection stops new push notifications from being actionable, because the watch can no longer be renewed without a valid token. Reconnecting the mailbox and re-running the assistant restores realtime. As always, scheduled sync covers the gap so the inbox stays current in the meantime.
Move to Bin — deletes reflect live
Deleting a message in Gmail (moving it to Bin) is itself an inbox change, so Google publishes a notification for it just like an arrival. MailDesk's incremental sync picks up the change and the open inbox refreshes live over Odoo's websocket — the deleted message disappears from the list for you and for teammates viewing the same mailbox, without a manual refresh. The same live-refresh path that surfaces new mail also reflects removals.
Honest token status and live "Verify token now"
MailDesk replaces Odoo's misleading token indicator with an honest one and adds a real, on-demand check — so you never trust a green badge that is lying.
- Neutral badge, not a false "valid". Stock Odoo shows a green "Token Valid" badge whenever a refresh-token row exists, even after the token has been revoked or expired. MailDesk replaces it with a neutral "token stored" badge that only states a token is present — it does not claim the token still works.
- Verify token now. A Verify token now button performs a real refresh exchange
against Google's token endpoint. The result is reported plainly:
- a fresh access token was issued → "Gmail token is valid - a fresh access token was issued.";
- no token is stored → a warning telling you to connect the mailbox;
- the exchange returned no access token, or failed → a warning that a reconnect is required.
- Reconnect Gmail. A clearly labelled Reconnect Gmail button (replacing Odoo's bare cog icon) starts the Google sign-in again. It is administrator-only and preflights the OAuth credentials, naming the exact missing fields if the app credentials are not configured.
Use Verify token now whenever push or sync looks stuck — it tells you in one click whether the problem is the token (reconnect) or something downstream (the realtime test below).
The realtime test timeline — the six checkpoints
After the watch is registered, the assistant offers a realtime test. Send a test email to the Gmail inbox from a safe sender, wait a few seconds, and click Re-check. The timeline confirms the message travelled the full pipeline, one checkpoint at a time. Each checkpoint shows observed, missing, or waiting:
| # | Checkpoint | What it proves |
|---|---|---|
| 1 | Pub/Sub delivered the notification to your webhook | Google published and Pub/Sub reached the MailDesk webhook |
| 2 | MailDesk verified the OIDC signature + audience | The notification was authentic — correct signature, audience, and an allow-listed signer |
| 3 | Gmail history sync triggered for the mailbox | The notification triggered the incremental Gmail fetch |
| 4 | Single-source-of-truth row created/updated | The message was ingested into MailDesk's mail store |
| 5 | Message body prefetched and cached | The body was warmed so the message opens instantly |
| 6 | Message visible in the MailDesk inbox | The message reached the inbox UI and is live on screen |
Reading the timeline tells you exactly where to look if realtime is not working: a stall at checkpoint 1 points at reachability or the Pub/Sub wiring; a stall at checkpoint 2 points at the audience or signer allow-list; later stalls point at sync or ingestion. Click Re-check to refresh the timeline, and Finish when you are done.
End state — what to expect
Once the lifecycle is running, here is the steady state you should see:
- New Gmail mail appears in about 3 to 8 seconds — near real-time, not instant.
- The mailbox account form shows realtime as Active, with a watch expiration date.
- The watch renews itself roughly every 6 days; you never touch it.
- If push ever pauses, fallback polling every ~2 minutes keeps mail flowing — nothing is lost.
- Deletes reflect live in the open inbox over the websocket, the same way arrivals do.
- The token status is honest: a neutral "token stored" badge, plus a one-click Verify token now that does a real refresh exchange.
There is nothing to schedule, watch, or maintain by hand. The only time you act is to reconnect a mailbox whose OAuth was revoked or expired — and even then, scheduled sync keeps the inbox current until you do.
Troubleshooting
| Symptom | Likely cause | What to do |
|---|---|---|
| Push worked, then went quiet | A notification was dropped (Pub/Sub is at-least-once) | The silence detector flags it and triggers a fallback resync automatically; mail still arrives on the ~2-minute schedule |
| Realtime shows an OAuth error | The Gmail token was revoked or expired | Click Verify token now; if it fails, Reconnect Gmail and re-consent, then re-open the assistant |
| "Verify token now" warns "no access token" | Token rejected by Google | Reconnect the mailbox under Settings → Mailboxes |
| Watch stopped renewing | Token invalid, or the Pub/Sub topic was deleted in your project | Confirm the token with Verify token now, confirm the topic still exists, then re-run the setup assistant |
| Test timeline stalls at checkpoint 1 | The webhook is not reachable, or Pub/Sub is mis-wired | Re-run preflight in the assistant; confirm the push URL returns HTTP 405 on a GET |
| Test timeline stalls at checkpoint 2 | The OIDC audience or signer allow-list does not match | Re-run validation so MailDesk re-aligns the audience and saves the signer |
| Deleted mail still shows | The open screen has not refreshed | The websocket normally updates it live; reload the view if it does not |
For the full symptom-by-symptom guide, see Realtime troubleshooting.
Related
- Gmail realtime push setup — the guided one-button assistant
- Realtime troubleshooting — symptom-by-symptom guide
- Prefetch & cache — why messages open instantly
- Realtime sync — what it means per provider
- Outlook realtime push setup
- Gmail OAuth setup — connect the mailbox first
- Mailbox setup
- Realtime & synchronization architecture — how push, sync, and prefetch fit together