Connecting OpenClaw to Google Chat: webhooks, service accounts, and the honest limits
Google Chat needs a Cloud project, a service account, and a public HTTPS webhook. Its API won't let a bot upload files or react. The full setup, plus what to expect.
Google Chat works with OpenClaw through the official @openclaw/googlechat plugin, but it’s the heaviest channel setup in the catalog: a Google Cloud project, a service account, a Chat app configured in the console, and, unlike Telegram or Matrix, a public HTTPS webhook your server must expose. It works, with real limits inherited from Google’s API: the bot can’t upload files and can’t react to messages. If your team lives in Google Chat it’s worth the hour; if you’re just picking a first channel, pick almost anything else.
What you’re building
Google Chat doesn’t do bot long-polling; it delivers events by calling your endpoint. So the shape is: OpenClaw’s plugin listens on a webhook path (/googlechat by default), you publish exactly that path to the internet over HTTPS, and a Google Chat app you configure in the Cloud console points at it. The docs’ recommended exposure recipes are Tailscale Funnel, a Caddy reverse proxy, or Cloudflare Tunnel, and their advice is worth honoring precisely: expose only that path, never the whole Gateway (which must stay private).
The setup path
openclaw plugins install @openclaw/googlechat
Then restart the gateway, and do the Google side, all in the Cloud console: create (or pick) a project and enable the Google Chat API; create a service account (no roles needed) and download its JSON key; then configure the Chat app itself: interactive features on, “Join spaces and group conversations” checked, the HTTP endpoint URL set to your public webhook (choose HTTP endpoint, not Pub/Sub), visibility granted to the people who should see it, status flipped to Live. OpenClaw’s side is a small config block:
channels: {
googlechat: {
enabled: true,
serviceAccountFile: "~/keys/chat-app.json",
audienceType: "app-url",
audience: "https://your-domain.example/googlechat",
},
}The audience must match what you entered in Google’s console: the URL effectively appears in two places, and mismatches are the classic silent failure.
Access control
The plugin follows OpenClaw’s standard model: DMs are pairing-gated by default (approve with openclaw pairing approve googlechat <code>), and group spaces require an @-mention. One Chat-specific tip from the docs: set the botUser option to your app’s numeric users/<id> identity so mention detection is reliable, and prefer numeric IDs in allowlists. Display-name matching is deprecated and gated behind a key that literally starts with dangerously.
The limits
- The bot cannot send files. Google Chat’s attachment upload requires user authentication; the plugin authenticates as a service account, so outbound uploads simply aren’t possible. Inbound, the first attachment per message is processed (20MB default cap).
- No reactions: same user-authentication restriction. Even the typing-indicator-as-reaction mode falls back to a placeholder message.
- Replies in spaces thread properly; DM conversations collapse into the agent’s main session.
- Delivery is durably queued for message events (Google retries on failure), a nice reliability detail, but only for messages, not other event types.
Should you?
If your working life is Google Workspace and you want the agent where your team already talks, this is the supported way, and it holds up in production once configured. If you’re choosing a first channel for a personal agent, Telegram takes five minutes with no exposed endpoint and no cloud console. The contrast is the clearest argument in OpenClaw’s whole channel catalog for “start simple, add the corporate ones later.”