@openclaw/googlechat plugin: DMs and spaces through Google Chat API webhooks (HTTP endpoint only, no Pub/Sub).
Install
Quick setup (beginner)
- Create a Google Cloud project and enable the Google Chat API.
- Go to: Google Chat API Credentials
- Enable the API if it is not already enabled.
- Create a Service Account:
- Press Create Credentials > Service Account.
- Name it whatever you want (e.g.,
openclaw-chat). - Leave permissions and principals blank (Continue, then Done).
- Create and download the JSON key:
- Click the new service account > Keys tab > Add Key > Create new key > JSON > Create.
- Store the downloaded JSON file on your gateway host (e.g.,
~/.openclaw/googlechat-service-account.json). - Create a Google Chat app in the Google Cloud Console Chat Configuration:
- Fill in Application info (app name, avatar URL, description).
- Enable Interactive features.
- Under Functionality, check Join spaces and group conversations.
- Under Connection settings, select HTTP endpoint URL.
- Under Triggers, select Use a common HTTP endpoint URL for all triggers and set it to your public gateway URL followed by
/googlechat(see Public URL). - Under Visibility, check Make this Chat app available to specific people and groups in
<Your Domain>and enter your email address. - Click Save.
- Enable the app status: refresh the page, find App status, set it to Live - available to users, and Save again.
- Configure OpenClaw with the service account and the webhook audience (must match the Chat app config):
- Env:
GOOGLE_CHAT_SERVICE_ACCOUNT_FILE=/path/to/service-account.json(default account only), or - Config: see Config highlights.
openclaw channels add --channel googlechatalso accepts--audience-type,--audience,--webhook-path, and--webhook-url.
- Env:
- Start the gateway. Google Chat will POST to your webhook path (default
/googlechat).
Add to Google Chat
Once the gateway is running and your email is on the visibility list:- Go to Google Chat.
- Click the + (plus) icon next to Direct Messages.
- Search for the App name you configured in the Google Cloud Console.
- The bot does not appear in the Marketplace browse list because it is a private app. Search for it by name.
- Select the bot, click Add or Chat, and send a message.
Public URL (Webhook-only)
Google Chat webhooks require a public HTTPS endpoint. For security, expose only the/googlechat path to the internet and keep the OpenClaw dashboard and other endpoints private.
Option A: Tailscale Funnel (Recommended)
Use Tailscale Serve for the private dashboard and Funnel for the public webhook path.-
Check what address your gateway is bound to:
Note the IP (e.g.,
127.0.0.1,0.0.0.0, or a Tailscale100.x.x.xaddress). -
Expose the dashboard to the tailnet only (port 8443):
-
Expose only the webhook path publicly:
- If prompted, visit the authorization URL shown in the output to enable Funnel for this node.
-
Verify:
https://<node-name>.<tailnet>.ts.net/googlechat. The dashboard stays tailnet-only at https://<node-name>.<tailnet>.ts.net:8443/. Use the public URL (without :8443) in the Google Chat app config.
Note: This configuration persists across reboots. Remove it later withtailscale funnel resetandtailscale serve reset.
Option B: Reverse Proxy (Caddy)
Proxy only the webhook path:your-domain.com/ are ignored or 404, while your-domain.com/googlechat routes to OpenClaw.
Option C: Cloudflare Tunnel
Configure the tunnel ingress rules to route only the webhook path:- Path:
/googlechat->http://localhost:18789/googlechat - Default rule: HTTP 404 (Not Found)
How it works
- Google Chat POSTs JSON to the gateway webhook path (POST only, JSON content type required, per-IP rate limited).
- OpenClaw authenticates every request before dispatch:
- Chat app events carry
Authorization: Bearer <token>. The token is verified before the full body is parsed. - Google Workspace Add-on events carry the token in the body (
authorizationEventObject.systemIdToken). OpenClaw reads them under a stricter pre-auth budget (16 KB, 3 s) before verification.
- Chat app events carry
- The token is checked against
audienceType+audience:audienceType: "app-url"→ audience is your HTTPS webhook URL.audienceType: "project-number"→ audience is the Cloud project number.- Add-on tokens under
app-urladditionally requireappPrincipalset to the app’s numeric OAuth 2.0 client ID (21 digits, not an email). Otherwise verification fails with a logged warning.
- Messages route by space:
- Spaces get per-space sessions
agent:<agentId>:googlechat:group:<spaceId>. Replies go to the message thread. - DMs collapse into the agent’s main session by default. Set
session.dmScopefor per-peer DM sessions (see Session).
- Spaces get per-space sessions
- DM access is pairing by default. Unknown senders receive a pairing code. Approve with:
openclaw pairing approve googlechat <code>
- Group spaces require @-mention by default. Mentions are detected from Chat
USER_MENTIONannotations targeting the app. SetbotUser(e.g.,users/1234567890) if detection needs the app’s user resource name. - When an exec or plugin approval starts from Google Chat and a stable
users/<id>approver is configured, OpenClaw posts a native approval card (cardsV2) in the originating space or thread. Card buttons carry opaque callback tokens. The manual/approve <id> <decision>prompt appears only when native delivery is unavailable.
Inbound durability
After request authentication, OpenClaw removes the add-on authorization object from storage and durably queues Google ChatMESSAGE events before returning 200. A persistence failure returns 503, allowing Google Chat to retry instead of acknowledging an event that could be lost. A durably queued 200 carries x-openclaw-delivery-accepted: durable. Non-message action acks and error responses omit the marker, so reverse proxies can require it to distinguish durable acceptance from a generic 200.
Pending or retryable messages survive a Gateway restart, remain serialized per space, and use the Google Chat message resource name to suppress duplicate queue entries while the active or retained completion record exists. Non-message actions keep their existing detached webhook path and do not receive this durable-queue guarantee. Delivery remains at least once across the queue-to-agent boundary, so a crash during handoff can replay a turn.
Targets
Use these identifiers for delivery and allowlists:- Direct messages:
users/<userId>(recommended). - Spaces:
spaces/<spaceId>. - Raw email
name@example.comis mutable and only used for allowlist matching whenchannels.googlechat.dangerouslyAllowNameMatching: true. - Deprecated:
users/<email>is treated as a user id, not an email allowlist entry. - Prefixes
googlechat:,google-chat:, andgchat:are accepted and stripped.
Config highlights
- Service account credentials:
serviceAccountFile(path) orserviceAccount(inline JSON string, object, or env/file/exec/store SecretRef). Env varsGOOGLE_CHAT_SERVICE_ACCOUNT(inline JSON) andGOOGLE_CHAT_SERVICE_ACCOUNT_FILE(path) apply to the default account only. Multi-account setups usechannels.googlechat.accounts.<id>with the same keys, including per-accountserviceAccountSecretRefs. - Omitted account
dmPolicyandgroupPolicyinherit the channel root. Explicit account policies win. The root defaults topairingandallowlistrespectively. Shared settings fromaccounts.defaulthave lower precedence than the root. Its credentials,enabled, anddangerouslyAllowNameMatchingare not inherited by named accounts. - Default webhook path is
/googlechatwhenwebhookPathis unset.webhookUrlcan supply the path instead. - Group keys must be stable space ids (
spaces/<spaceId>). Display-name keys are deprecated and logged as such. dangerouslyAllowNameMatchingre-enables mutable email principal matching for allowlists (break-glass compatibility mode). Doctor warns about email entries.- Google Chat reaction actions are not exposed. The plugin uses service-account authentication, while Google Chat reaction endpoints require user authentication. Remove unsupported legacy reaction settings with
openclaw doctor --fix. - Native approval cards use Google Chat
cardsV2button clicks, not reaction events. Approvers come fromallowFromordefaultToand must be stable numericusers/<id>values. - Message actions expose text
sendonly. Google Chat attachment upload requires user authentication, while this plugin uses service-account authentication, so outbound file upload is not exposed. typingIndicator:message(default) posts a_<Bot> is typing..._placeholder and edits it into the first reply.nonedisables it.reactionrequires user OAuth and currently falls back tomessagewith a logged error under service-account auth.- OpenClaw downloads the first inbound attachment per message through the Chat API into the media pipeline.
mediaMaxMbcaps that download (default 20). Google Drive files are not downloaded. The agent receives an unavailable-attachment notice asking for a direct file upload instead. Other unsupported attachment sources receive the same upload guidance. Messages with multiple attachments include a counted notice for the additional attachments that were not processed. Oversize attachments retain their size-limit notice. - Bot-authored messages are ignored by default. With
allowBots: true, accepted bot messages use shared bot loop protection: configurechannels.defaults.botLoopProtection, then override withchannels.googlechat.botLoopProtectionorchannels.googlechat.groups.<space>.botLoopProtection.
customEmojis.list endpoint requires user authentication with the chat.customemojis or chat.customemojis.readonly scope. This plugin authenticates exclusively as a service account with the chat.bot scope, which cannot access that endpoint.
Secrets reference details: Secrets Management.
Troubleshooting
405 Method Not Allowed
If Google Cloud Logs Explorer shows errors like:-
Channel not configured: the
channels.googlechatsection is missing. Verify with:If it returns “Config path not found”, add the configuration (see Config highlights). -
Plugin not enabled: check plugin status:
If it shows “disabled”, run
openclaw plugins enable googlechatand check the application result. - Configuration not applied: check hot reload status and Gateway logs. Start the Gateway if it is offline. If you changed the service environment, restart the Gateway to load it.
Other issues
openclaw channels status --probesurfaces auth errors and missing audience config (audienceandaudienceTypeare both required).- If no messages arrive, confirm the Chat app’s webhook URL and trigger configuration.
- If mention gating blocks replies, set
botUserto the app’s user resource name and checkrequireMention. openclaw logs --followwhile sending a test message shows whether requests reach the gateway.
Related
- Channels Overview — all supported channels
- Channel routing — session routing for messages
- Gateway configuration
- Groups — group chat behavior and mention gating
- Pairing — DM authentication and pairing flow
- Security — access model and hardening