MINARA

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}/messages with {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

  1. In Google Cloud Console, pick (or create) a project for the Chat app
  2. "APIs & Services" → "Enable APIs" → enable Google Chat API
  3. "IAM & Admin" → "Service Accounts" → "Create Service Account". Pick a name (e.g. minara-chat-bot)
  4. After creation, open the service account → "Keys" tab → "Add Key" → "JSON". Save the downloaded file.

2. Configure the Chat app

  1. Still in the Google Cloud project, navigate to Google Chat API → "Configuration" tab
  2. App name + Avatar URL + Description: anything sensible
  3. Functionality: "Receive 1:1 messages" + "Join spaces and group conversations"
  4. Connection settings: pick "App URL"; set the endpoint to https://<your-host>/webhooks/google-chat
  5. 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
  6. 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.json

4. 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=1234567890

GOOGLE_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_chat

Inbound webhook

Google's inbound JWT carries:

ClaimExpected value
iss (issuer)[email protected]
aud (audience)matches GOOGLE_CHAT_AUDIENCE
SignatureRS256, 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_AUDIENCE is 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_AUDIENCE the same hour.
  • No card support. Cards v2 messages and dialogs are not yet wired in either direction.

Troubleshooting

"401 Unauthorized on inbound"

  • GOOGLE_CHAT_AUDIENCE does 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.bot scope. 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_PATH points outside the sandbox, or the file does not exist. Move it under ~/.minara/sandbox/ and update the env var.

Reference

On this page