Files
Cortex-Inara/docs/GOOGLE_CHAT_BOT.md
Scott Idem ddf5dd6338 docs: add Google Chat setup guide, update NC Talk for per-user routing
- docs/GOOGLE_CHAT_BOT.md: new step-by-step guide covering channels.json,
  Google Cloud Console config, JWT audience, and troubleshooting
- docs/NEXTCLOUD_TALK_BOT.md: updated for per-user endpoints
  (/webhook/nextcloud/{username}), channels.json config, removed old
  server-level .env references, updated Multi-User note

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-03-29 13:24:36 -04:00

4.0 KiB

Google Chat Bot Integration

Cortex connects to Google Chat as a Workspace Add-on — each Cortex user gets their own webhook endpoint routed to their chosen persona.

Status: Live and confirmed working (2026-03-27)


Prerequisites

  • A Google Cloud project with Google Chat API enabled
  • The Cortex server reachable at a public HTTPS URL
  • The user pre-registered in Cortex (manage_passwords.py invite or google-add)

Per-User Setup

1. Create the user's channels.json

Create home/{username}/channels.json on the Cortex server:

{
  "google_chat": {
    "persona": "inara",
    "audience": "https://cortex.dgrzone.com/channels/google-chat/{username}",
    "backend": "claude",
    "timeout": 25
  }
}
  • persona — which persona responds (must exist under home/{username}/persona/)
  • audience — must exactly match the HTTP endpoint URL you set in Google Cloud Console (Google uses this as the JWT aud claim)
  • backend"claude" recommended; Google Chat requires a response within 30s
  • timeout — keep at 25 (Google's hard limit is 30s; this leaves a 5s buffer)

2. Configure Google Chat API in Google Cloud Console

  1. Go to console.cloud.google.com and select the project
  2. APIs & Services → Enabled APIs & services → Google Chat API
  3. Click the Configuration tab
  4. Fill in Application info:
    • App name: Cortex (or your persona name)
    • Avatar URL: optional
    • Description: optional
  5. Under Interactive features:
    • Enable "Join spaces and group conversations" if you want the bot in group chats, or leave it off for DM-only
  6. Under Connection settings:
    • Select HTTP endpoint URL
    • Enter: https://cortex.dgrzone.com/channels/google-chat/{username}
  7. Under Visibility:
    • Add the specific Google accounts that should be able to use this bot
    • For One Sky IT Workspace users: add individuals or the whole domain
  8. Click Save

Important: The URL in step 6 must exactly match the audience value in channels.json. Google includes this URL as the JWT aud claim on every request, and Cortex rejects any request where they don't match.


How It Works

  1. User sends a message in Google Chat → Google POSTs a signed JSON payload to /channels/google-chat/{username}
  2. Cortex reads the user's channels.json, verifies the JWT systemIdToken from authorizationEventObject
  3. Sets the persona context, builds the system prompt, calls the LLM
  4. Returns the response wrapped in hostAppDataAction → chatDataAction → createMessageAction

The response must be returned synchronously (Google Chat does not support async/background replies like NC Talk does). The 25s timeout is a hard constraint.


JWT Verification

Google Chat Workspace Add-ons send a systemIdToken in the request body at: body["authorizationEventObject"]["systemIdToken"]

Claims verified by Cortex:

  • iss = https://accounts.google.com
  • aud = the value of audience in channels.json

If audience is empty, verification is skipped (useful for local testing, never in production).


Nginx

The /channels/ prefix is already public in auth_middleware.py — no Nginx changes needed if you're already proxying all traffic to Cortex. Verify the path isn't blocked by basic auth or IP restrictions.


Troubleshooting

Symptom Cause Fix
404 on the webhook channels.json missing or no google_chat key Create/check home/{username}/channels.json
401 Invalid token audience in channels.json doesn't match the endpoint URL Make them identical — copy the URL exactly
401 Missing token No systemIdToken in request Bot may not be a Workspace Add-on; check connection settings type
Timeout / no response LLM too slow backend: "claude" recommended; reduce context tier if needed
Bot not receiving messages Visibility not configured Add the user's Google account under Visibility in Cloud Console