Google Chat
Google Workspace Chat via service-account JWT auth, with [email protected] signed inbound activities.
🟡 Outbound-ready via service-account, inbound JWT-verified. For Google Workspace deployments. Outbound mints a short-lived access token from a service-account JSON key; inbound verifies every POST is signed by
[email protected].
What you get
- Outbound text via
POST https://chat.googleapis.com/v1/{space}/messageswith{text}. Threads (thread.name) are supported. - Inbound webhook at
/webhooks/google-chat. Google signs every inbound with a bearer JWT issued by[email protected]. - Access-token cache with 1-hour TTL and 5-minute refresh headroom.
- Text only this PR. Cards v2, dialogs, slash commands, and attachment downloads are deferred.
- 4096-char text limit per message.
Setup
1. Create a Google Cloud project + service account
- In Google Cloud Console, pick (or create) a project for the Chat app
- "APIs & Services" → "Enable APIs" → enable Google Chat API
- "IAM & Admin" → "Service Accounts" → "Create Service Account".
Pick a name (e.g.
minara-chat-bot) - After creation, open the service account → "Keys" tab → "Add Key" → "JSON". Save the downloaded file.
2. Configure the Chat app
- Still in the Google Cloud project, navigate to Google Chat API → "Configuration" tab
- App name + Avatar URL + Description: anything sensible
- Functionality: "Receive 1:1 messages" + "Join spaces and group conversations"
- Connection settings: pick "App URL"; set the endpoint to
https://<your-host>/webhooks/google-chat - Authentication Audience: pick one and remember it
- "Project Number" → the audience will be the 12-digit GCP project number
- "HTTP endpoint URL" → the audience will be your endpoint URL
- Permissions: "Specific people and groups" or your domain
3. Move the service-account JSON into the sandbox
CLAUDE.md §4 requires service-account keys to live inside the data /
sandbox tree. Move the downloaded JSON to a path under
~/.minara/sandbox/ (or your MINARA_DATA_DIR equivalent):
mv ~/Downloads/<project>-<hash>.json ~/.minara/sandbox/google-chat-sa.json
chmod 600 ~/.minara/sandbox/google-chat-sa.json4. Find a default space
After adding the Chat app to a space (or DM-ing the bot from a test
user), grab the space resource name from the URL: it looks like
spaces/AAAA1234567. Save it as GOOGLE_CHAT_DEFAULT_SPACE_ID.
5. Configure Minara
minara auth messaging add
# pick `google_chat` from the list.Or set env vars:
GOOGLE_CHAT_SERVICE_ACCOUNT_JSON_PATH=/Users/you/.minara/sandbox/google-chat-sa.json
GOOGLE_CHAT_DEFAULT_SPACE_ID=spaces/AAAA1234567
GOOGLE_CHAT_AUDIENCE=1234567890GOOGLE_CHAT_AUDIENCE must match the Workspace console value
exactly. If you picked "Project Number" in the console, set it
to the digits. If you picked "HTTP endpoint URL", set it to the
URL including the trailing slash if your console showed one.
6. Test
minara auth messaging test google_chatInbound webhook
Google's inbound JWT carries:
| Claim | Expected value |
|---|---|
iss (issuer) | [email protected] |
aud (audience) | matches GOOGLE_CHAT_AUDIENCE |
| Signature | RS256, verified against Google's published X.509 certs at https://www.googleapis.com/service_accounts/v1/jwk/[email protected] |
| Clock skew | ±5 minutes |
JWKS is cached for 24 hours; rotation is handled automatically on a
kid miss.
Event types accepted: MESSAGE (a user posted in a space the app is
in). Other types (ADDED_TO_SPACE, REMOVED_FROM_SPACE,
CARD_CLICKED) are dropped.
Limits & caveats
GOOGLE_CHAT_AUDIENCEis byte-exact. The most common cause of 401 on inbound is the audience env value not matching the console setting. Both halves of "Project Number" must be the literal numeric string with no leading zeros.- Service-account JSON path lives in the sandbox. Per CLAUDE.md §4 (sandbox-only file references). The factory reads the file at boot; rotating the key requires a restart.
- One JSON, one audience model. If you change "Authentication
Audience" in the console you must update
GOOGLE_CHAT_AUDIENCEthe same hour. - No card support. Cards v2 messages and dialogs are not yet wired in either direction.
Troubleshooting
"401 Unauthorized on inbound"
GOOGLE_CHAT_AUDIENCEdoes not match the console. Open the Chat API Configuration page and copy the audience value verbatim.
"Missing required scope" on outbound
- The service account does not have
https://www.googleapis.com/auth/chat.botscope. The factory requests it automatically; check that the service account belongs to the same project that has the Chat API enabled.
"Service-account JSON not found"
GOOGLE_CHAT_SERVICE_ACCOUNT_JSON_PATHpoints outside the sandbox, or the file does not exist. Move it under~/.minara/sandbox/and update the env var.
Reference
- Env vars:
GOOGLE_CHAT_* - Outbound:
apps/agent/src/messaging/google_chat.ts - Inbound spec:
apps/agent/src/messaging/inbound/specs/google_chat.ts - JWT helper:
apps/agent/src/messaging/_shared/jwt-verify.ts - Verify requests: developers.google.com / Verify requests from Chat