Skip to main content

Gmail Pub/Sub -> Fased

Recommended flow: Gmail watch -> Pub/Sub push -> gog gmail watch serve -> Fased webhook This keeps the message content off the public internet as much as possible and fits Fased’s private-ingress model.

What you need

  • gcloud installed and logged in
  • gog / gogcli installed and authorized for the Gmail account
  • Fased webhook ingress enabled
  • tailscale logged in if you want the supported public HTTPS path
Supported public endpoint pattern:
  • Tailscale Funnel
Tailscale Funnel is the documented baseline. Other tunnel providers are advanced DIY setups.

Minimal webhook config

To push Gmail summaries into a chat surface, override the preset with a mapping:
Notes:
  • channel: "last" reuses the last route known to the target Agent/session
  • if you want deterministic delivery, set both channel and to
  • Gmail hook content is wrapped with external-content safety boundaries by default
  • to disable that wrapper, set hooks.gmail.allowUnsafeExternalContent: true only for tightly controlled environments
Optional Gmail-specific model overrides:
Resolution order:
  1. mapping-level model / thinking
  2. hooks.gmail.model / hooks.gmail.thinking
  3. normal agent defaults
Use a model that is already configured for the target Agent. Set or review that model in Agent > Models before pinning a Gmail mapping to a specific provider/model ref. For the simplest setup, omit the mapping-level model and let the target Agent use its configured primary/fallback model.
What it does:
  • enables the Gmail webhook preset
  • writes the hooks.gmail config used by fased webhooks gmail run
  • prefers Tailscale Funnel for the public push endpoint
Path note:
  • when tailscale.mode is enabled, Fased sets hooks.gmail.serve.path to /
  • the public path stays at hooks.gmail.tailscale.path, default /gmail-pubsub
  • if you need the backend to keep the prefixed path, set hooks.gmail.tailscale.target to a full URL like http://127.0.0.1:8788/gmail-pubsub
Platform note:
  • on macOS the helper can install gcloud, gogcli, and tailscale via Homebrew
  • on Linux, install them yourself first

Gateway auto-start

When these are set:
  • hooks.enabled = true
  • hooks.gmail.account is configured
the gateway starts gog gmail watch serve on boot and keeps the watch renewed. Opt out:
Run either gateway auto-start or the manual daemon. Running both at the same time can hit a port bind conflict. Manual runner:

One-time Google Cloud setup

  1. Select the GCP project that owns the OAuth client used by gog
  1. Enable the required APIs
  1. Create the Pub/Sub topic
  1. Let Gmail publish into that topic
Important:
  • the Pub/Sub topic must live in the same GCP project as the OAuth client used for the Gmail watch

Start the Gmail watch

Keep the returned history_id if you want a clean debugging baseline.

Run the push handler directly

Notes:
  • --token protects the push endpoint seen by Pub/Sub
  • --hook-url should point at your Fased webhook mapping such as /hooks/gmail
  • --include-body and --max-bytes control how much message content reaches Fased
For most setups, fased webhooks gmail run is the cleaner wrapper.

Non-Tailscale public ingress

You can expose the Gmail push handler through another tunnel, but that is an advanced, unsupported path. Example:
Then bind the generated URL in the subscription:
If you move to a stronger production edge, use Pub/Sub OIDC verification and:

Test the flow

Send a message to the watched inbox:
Inspect status and history:

Troubleshooting

  • Invalid topicName
    • the topic lives in the wrong project
  • User not authorized
    • the Gmail push service account is missing publisher access
  • empty messages
    • Gmail push only carries historyId; fetch message details through gog gmail history

Cleanup