Teams usually do not get stuck on the first webhook. They get stuck when someone asks two practical questions: which person was allowed to wake the agent, and why did a message that looked like an @mention produce no reply?
The answer sits in two identity layers. Google Chat sends the human sender in the interaction event. OpenClaw uses the configured Chat app credentials when it posts a reply. This tutorial keeps those layers separate, then adds a small acceptance test for direct messages, spaces, and mentions. The current OpenClaw documentation describes Google Chat as an official plugin that uses Google Chat API webhooks, while Google's user reference documents stable users/<id> resources for people and apps. See the OpenClaw Google Chat documentation and Google's user identity reference.
Scope: The procedure below is documentation-based. It is not a report of a live test against your Gateway. The two-user checks later in the article are proposed acceptance tests.
Start with the identity map
Write down the rule for each layer before opening the Google Cloud console. A display name is useful to a person reading Chat. It is a poor access-control key.
| Question | OpenClaw setting | Rule to verify |
|---|---|---|
| Who posts the reply? | serviceAccountFile | The Google Chat app, not the human who triggered it. |
| Who may use direct messages? | dmPolicy and allowFrom | Pair unknown users or allow stable users/<id> values. |
| Which spaces are enabled? | groupPolicy and groups | Use stable spaces/<spaceId> keys. |
| What wakes the agent in a space? | requireMention and botUser | Require a real Google Chat USER_MENTION annotation. |
| Should DMs share context? | session.dmScope | Choose the session boundary instead of inheriting it accidentally. |
OpenClaw's routing documentation also says that replies return to the channel where the message arrived. Spaces receive per-space sessions and replies go back to the message thread. That makes the space ID and the sender ID operational data, not decoration.
Prerequisites
- A running OpenClaw Gateway with a configured model provider.
- A Google Cloud project where you can enable the Google Chat API.
- A service account and a protected credential location on the Gateway host.
- A public HTTPS URL for the Google Chat webhook. Keep the Gateway dashboard private.
- One test space and two human Google Chat accounts, so you can test both an approved and an unapproved sender.
- Permission to configure the Chat app visibility for the people or Google Group who will test it.
Use a disposable or low-risk space for the first run. Google says an app using app authentication must be a member of a space to read or create resources there. A successful service-account setup therefore does not remove the separate step of adding the app to the intended space. Google's service-account authentication guide documents that membership requirement.
Install the plugin and expose one endpoint
Google Chat is installed as its own OpenClaw plugin:
openclaw plugins install @openclaw/googlechatThe current plugin documentation describes an HTTP endpoint implementation only. It does not use Pub/Sub for this channel. Configure the Google Chat app to send events to the public path used by the Gateway, normally /googlechat.
Expose only that path. The OpenClaw documentation gives this Caddy shape for a Gateway listening locally:
your-domain.example { reverse_proxy /googlechat* localhost:18789 }Requests to the dashboard and other Gateway paths should not become public just because Google Chat needs one webhook. If you use Tailscale Funnel or Cloudflare Tunnel, apply the same boundary: route /googlechat to OpenClaw and give unrelated paths a private route or a 404.
For the simplest authentication-audience choice, use audienceType: 'app-url' and make audience the exact HTTPS webhook URL, including /googlechat. OpenClaw also supports project-number, where the audience is the Cloud project number. Google sends a bearer token with HTTPS interaction requests, and the audience determines how that token is verified. Google's request verification guide explains the token and 401 failure path.
Configure the Google Chat app
- In Google Cloud, create or select a project and enable the Google Chat API.
- Create a service account. Give it only the access needed for this Chat app.
- Create a JSON key if that is the credential form your deployment uses, then place it on the Gateway host with restrictive file permissions. Google warns that exported private keys should not be stored in an insecure location such as source control.
- Open the Google Chat API configuration page and enter the app name, avatar, and description.
- Enable interactive features, allow the app to join spaces and group conversations, and choose HTTP endpoint URL as the connection setting.
- Choose a common HTTP endpoint for the triggers and enter the same public URL used by OpenClaw, such as
https://your-domain.example/googlechat. - Set visibility for the test people or Google Group. When the configuration is ready, set the app status to live and save again.
Google's interaction-events guide describes the HTTP endpoint and visibility fields. The OpenClaw setup page adds a detail that is easy to miss with private apps: search for the configured app name in Google Chat instead of expecting it in the Marketplace browse list. Add it to the test space and to any direct-message conversation you intend to use.
Make the OpenClaw policy explicit
Use a small, readable configuration. The IDs below are placeholders; replace them with values from your own Chat events.
{ channels: { googlechat: { enabled: true, serviceAccountFile: '/var/lib/openclaw/googlechat-service-account.json', audienceType: 'app-url', audience: 'https://your-domain.example/googlechat', webhookPath: '/googlechat', botUser: 'users/12345678901234567890', dmPolicy: 'pairing', allowFrom: ['users/11111111111111111111'], groupPolicy: 'allowlist', groups: { 'spaces/AAA...': { enabled: true, requireMention: true, users: ['users/11111111111111111111', 'users/22222222222222222222'] } } } } }This example makes five choices visible:
serviceAccountFileidentifies the credential used by the Chat app for API calls.dmPolicy: 'pairing'requires an unknown direct-message sender to complete the pairing flow.allowFromrecords an approved human using a stable Chat user resource.groupPolicy: 'allowlist'prevents an unlisted space from becoming an active agent surface.- The space entry requires a mention and limits eligible senders to the listed user IDs.
The current OpenClaw page says the root defaults are pairing for DMs and allowlist for groups, but writing the values out is useful for a team handoff. It prevents a later editor from treating an omitted setting as an intentional policy. Group keys should be stable space IDs. Display names are deprecated as group keys in the current documentation.
For an outbound smoke test, OpenClaw's message command accepts spaces/<spaceId> and users/<userId> targets for Google Chat. It does not make a display name a stable routing key. The OpenClaw message CLI reference lists those target formats.
Keep human identity separate from app identity
Google creates a User resource for each Chat user. Its name is formatted as users/{user} and represents a unique, stable identifier. For a message event, Google documents two useful locations: Event.user.name and spaces.messages.sender.name. Use that value when building an allowlist or explaining an audit entry. Keep displayName for the readable label.
An email address is a different choice. The OpenClaw security advisory for Google Chat describes why matching a mutable email can weaken identity binding when an organization changes its identity records. The advisory lists OpenClaw versions through 2026.2.13 as affected and 2026.2.14 and later as fixed. Current documentation keeps raw email matching as a break-glass compatibility option behind dangerouslyAllowNameMatching, and treats users/<email> as deprecated rather than as an email allowlist entry. Use numeric stable user resources for a new team policy. Read the OpenClaw Google Chat spoofing advisory before carrying forward an older configuration.
The same separation applies to replies. Google says a service account acts as the Chat app's identity. If the workflow must take action on behalf of a specific employee, that is a user-authentication design question, not something to solve by putting the employee's email into serviceAccountFile. The current OpenClaw Google Chat plugin also documents that reaction actions and outbound attachment upload are not exposed through its service-account model.
Check the DM session boundary as well. The current OpenClaw channel page says DMs collapse into the agent's main session by default and points to session.dmScope for per-peer DM sessions. If several employees will use direct messages for separate work, make that choice explicit before the rollout.
Make mention gating a real rule
In a group space, access and activation are separate checks. The group policy decides whether the space and sender are allowed. requireMention then decides whether an allowed message should wake the agent. A mention should not bypass the group allowlist.
Google Chat represents a user mention with a USER_MENTION annotation containing the mentioned user's resource. OpenClaw's current documentation says group mentions are detected from annotations targeting the app and recommends setting botUser to the app's Chat user resource when detection needs help. Use Chat's actual mention picker in the test message. Typing plain @OpenClaw text is not a reliable substitute for an annotation. That last point is an operational inference from Google's annotation model, so confirm it with the event received by your own Gateway.
Leave requireMention: true on for a busy team space. If you deliberately want an always-on room, change that value only after deciding what ambient messages may enter the agent context. OpenClaw's group documentation distinguishes trigger authorization from context visibility, so turning off mention gating is a wider behavior change than simply making the bot more talkative.
Run a two-user acceptance test
Run these checks in order. Record the expected result beside the observed result; do not treat a green status line as proof that the end-to-end flow works.
- Check the plugin and channel. Run
openclaw plugins list | grep googlechat,openclaw channels status, andopenclaw channels status --probe. The channel should be enabled and configured, and the probe should not report a missing audience or authentication error. - Test an unknown DM sender. Have user A message the app. With pairing enabled, the documented behavior is a pairing code for an unknown sender. Approve it with
openclaw pairing approve googlechat <CODE>, then send a second message. Record A's stableusers/<id>value in the approved policy. - Test the space without a mention. Have an allowlisted user post a normal sentence. With
requireMention: true, it should not be treated as an agent request. The group rules describe unmentioned traffic as context-only unless another activation rule applies. - Test a real mention. Have the same user select the Chat app from the mention picker and ask a small, harmless question. Watch
openclaw logs --follow. Check that the inbound event targets the configuredbotUserand that the reply returns in the originating thread. - Test the second sender. Have user B repeat the mention. If B is absent from the space's
userslist, the group allowlist should block the trigger even though the app was mentioned. - Check the displayed sender. The expected outbound actor is the Chat app configured in Google Cloud. Compare the visible app name with the triggering human's name. This verifies the identity boundary; it does not prove that every model action is safe.
Google documents that HTTP interaction requests can be retried after a timeout, network failure, or non-2xx response. OpenClaw's current channel documentation describes durable queuing for message events before acknowledgement, but it also says delivery remains at least once across the queue-to-agent handoff. Treat a successful HTTP response as receipt by the Gateway, not as proof that a model reply completed exactly once.
Failure paths and a safe rollback
A 405 Method Not Allowed in Google Cloud Logs usually means the handler is not registered. Check the channel config with openclaw config get channels.googlechat, verify the plugin with openclaw plugins list | grep googlechat, restart the Gateway with openclaw gateway restart, and confirm openclaw channels status reports Google Chat as enabled and configured. These are the recovery checks in the current OpenClaw documentation.
A 401 points toward request verification. Check that the Chat app URL, webhookPath, and audience are identical, and that the endpoint is reachable over HTTPS. A space send can also fail when the app is not a member of that space. If no event arrives at all, check the Chat app's trigger and visibility settings before changing model or routing configuration.
If direct messages stop after a credential or policy change, repeat the pairing check and compare the event's stable sender ID with allowFrom. If only group mentions fail, inspect requireMention, the space key, and botUser. Do not loosen every policy at once; that removes the evidence needed to find the mismatch.
To pause one room without removing the direct-message setup, set that space entry to enabled: false, restart the Gateway if required by your reload mode, and re-run the channel status check. To stop all group triggers, use groupPolicy: 'disabled'. Keep the credential file out of Git and rotate or revoke it through Google Cloud if it has been exposed.
The smallest reliable team rollout is one test space, two known human IDs, pairing for DMs, and real mention annotations for group activation. Once those rules are visible in configuration and pass the acceptance test, adding another space becomes a controlled copy of a known policy rather than a guess about who the bot will answer.
Sources
- OpenClaw documentation: Google Chat channel. Accessed 2026-09-13.
- OpenClaw documentation: channel configuration. Accessed 2026-09-13.
- OpenClaw documentation: groups and mention gating. Accessed 2026-09-13.
- OpenClaw documentation: message CLI. Accessed 2026-09-13.
- Google for Developers: authenticate as a Google Chat app. Accessed 2026-09-13.
- Google for Developers: identify and specify Google Chat users. Accessed 2026-09-13.
- Google for Developers: receive and respond to interaction events. Accessed 2026-09-13.
- Google for Developers: verify requests from Google Chat. Accessed 2026-09-13.
- Google for Developers: format messages and mentions. Accessed 2026-09-13.
- OpenClaw security advisory: Google Chat mutable email allowlists. Published 2026-02-16; accessed 2026-09-13.
Reference Trail
Sources and further reading
- OpenClaw Google Chat documentationgithub.com
- user identity referencedevelopers.google.com
- service-account authentication guidedevelopers.google.com
- request verification guidedevelopers.google.com
- interaction-events guidedevelopers.google.com