| summary | read_when | ||
|---|---|---|---|
Gmail watch + Pub/Sub push in gog |
|
Goal: Gmail push → Pub/Sub → gog HTTP handler → downstream webhook.
- Create a Pub/Sub topic (GCP project).
- Create a push subscription targeting your
gog gmail watch serveendpoint. - Configure push auth:
- Preferred: OIDC JWT from a service account.
- Fallback/dev: shared token header
x-gog-tokenor?token=.
- Start watch:
gog gmail watch start \
--topic projects/<project>/topics/<topic> \
--label INBOX
- Run handler:
gog gmail watch serve \
--bind 127.0.0.1 \
--port 8788 \
--path /gmail-pubsub \
--token <shared> \
--hook-url http://127.0.0.1:18789/hooks/agent
gog gmail watch start --topic <gcp-topic> [--label <idOrName>...] [--ttl <sec|duration>]
gog gmail watch status
gog gmail watch renew [--ttl <sec|duration>]
gog gmail watch stop
gog gmail watch serve \
--bind 127.0.0.1 --port 8788 --path /gmail-pubsub \
[--verify-oidc] [--oidc-email <svc@...>] [--oidc-audience <aud>] \
[--token <shared>] \
[--hook-url <url>] [--hook-token <token>] \
[--include-body] [--max-bytes <n>] [--exclude-labels <id,id,...>] [--save-hook]
gog gmail history --since <historyId> [--max <n>] [--page <token>]
Notes:
watch startstores{historyId, expirationMs, topic, labels}for account.watch renewreuses stored topic/labels.watch stopcalls Gmail stop + clears state.watch serveuses stored hook if--hook-urlnot provided.watch serve --exclude-labelsdefaults toSPAM,TRASH; set to an empty string to disable.- Exclude label IDs are matched exactly (case-sensitive opaque IDs).
Path (per account):
~/.config/gogcli/state/gmail-watch/<account>.json
Schema (v1):
{
"account": "you@gmail.com",
"topic": "projects/…/topics/…",
"labels": ["INBOX"],
"historyId": "12345",
"expirationMs": 1730000000000,
"providerExpirationMs": 1730000000000,
"renewAfterMs": 1730000001000,
"updatedAtMs": 1730000001000,
"hook": {
"url": "http://127.0.0.1:18789/hooks/agent",
"token": "...",
"includeBody": false,
"maxBytes": 20000
}
}{
"source": "gmail",
"account": "you@gmail.com",
"historyId": "...",
"messages": [
{
"id": "...",
"threadId": "...",
"from": "...",
"to": "...",
"subject": "...",
"date": "...",
"snippet": "...",
"body": "...",
"bodyTruncated": true,
"labels": ["INBOX"]
}
]
}- Default: headers + snippet only.
--include-body: include text/plain body (first matching part).--max-bytes: hard cap on body bytes (default20000).- If over cap: truncate + set
bodyTruncated=true.
Preferred:
- Pub/Sub push with OIDC JWT.
- Verify JWT audience + email (service account).
Fallback (dev only):
- Shared token via
x-gog-tokenheader or?token=.
- Stale historyId: fall back to
messages.list(last N) + reset historyId. - Watch expired:
watch renewerror; rerunwatch start. - Hook failures: log and still advance historyId to avoid replay storms.