feat(gateway): add Google Chat adapter#718
Conversation
|
All PRs must reference a prior Discord discussion to ensure community alignment before implementation. Please edit the PR description to include a link like: This PR will be automatically closed in 3 days if the link is not added. |
There was a problem hiding this comment.
Pull request overview
Adds a new Google Chat adapter to the Custom Gateway so Google Chat DMs/Spaces can be bridged into OAB via the existing WebSocket event/reply flow.
Changes:
- Introduces
GoogleChatAdapterwith webhook ingestion, (optional) JWT verification, and reply sending (including token refresh + message splitting). - Wires the adapter into the gateway runtime (state + reply routing + webhook route mounting) and documents configuration.
- Extends Helm chart values/templates/tests and repo docs to support deploying/configuring the Google Chat adapter.
Reviewed changes
Copilot reviewed 12 out of 13 changed files in this pull request and generated 2 comments.
Show a summary per file
| File | Description |
|---|---|
gateway/src/adapters/googlechat.rs |
New adapter implementation: webhook parsing, JWT verification, token refresh, reply posting + splitting, unit tests |
gateway/src/adapters/mod.rs |
Exposes the new googlechat adapter module |
gateway/src/main.rs |
Adds adapter initialization, webhook route registration, and reply routing for platform="googlechat" |
gateway/README.md |
Documents gateway env vars + endpoint for Google Chat |
docs/google-chat.md |
Adds operator setup guide for Google Chat |
docs/config-reference.md |
Adds googlechat to supported gateway platform values |
config.toml.example |
Updates example gateway platform values |
charts/openab/values.yaml |
Adds gateway.googleChat configuration block |
charts/openab/templates/gateway.yaml |
Injects Google Chat env vars into the gateway Deployment when configured |
charts/openab/templates/gateway-secret.yaml |
Adds Google Chat secrets (SA key JSON / access token) to the unified Secret |
charts/openab/tests/gateway_test.yaml |
Adds Helm rendering tests for Google Chat env vars + secret keys |
README.md |
Updates top-level docs/diagram to mention Google Chat support via Custom Gateway |
Cargo.lock |
Lockfile updates associated with dependency graph/version changes |
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
| | `GOOGLE_CHAT_AUDIENCE` | (optional) | JWT audience for webhook verification (webhook URL or project number) | | ||
| | `GOOGLE_CHAT_PROJECT_NUMBER` | (optional) | GCP project number — fallback audience for JWT verification | |
| - Validate `email == chat@system.gserviceaccount.com` (proves the token came from Google Chat, not another Google service) | ||
|
|
||
| If `GOOGLE_CHAT_AUDIENCE` is not set, the gateway logs a warning and accepts all requests (insecure — for local development only). | ||
|
|
||
| > **Note:** The "Project Number" Authentication Audience mode is not supported. It uses a different JWT issuer (`chat@system.gserviceaccount.com`) and JWKS endpoint that this adapter does not implement. Use the default "HTTP Endpoint URL" mode. |
OpenAB PR ScreeningThis is auto-generated by the OpenAB project-screening flow for context collection and reviewer handoff.
Screening report## IntentPR #718 adds Google Chat as a supported Custom Gateway platform so OpenAB agents can receive and reply to messages from Google Chat DMs and Spaces. The operator-visible problem is that OpenAB currently supports other chat surfaces but not Google Chat, leaving Google Workspace deployments without a native gateway adapter. The PR attempts to close that gap with webhook intake, outbound replies, authentication, Helm config, and operator docs. FeatFeature. The change introduces a Who It ServesPrimary beneficiaries:
Rewritten PromptImplement Google Chat support for the OpenAB Custom Gateway. Add a Include Helm configuration for enabling Google Chat, secret-backed service account key injection, docs for Google Chat setup and security expectations, and tests covering webhook parsing, JWT rejection behavior, message splitting, bot filtering, and Helm rendering. Keep unsupported features explicit: attachments, reactions, and rich card rendering are out of scope for the first merge. Merge PitchThis is worth advancing because Google Chat is a major enterprise messaging surface and fits OpenAB’s gateway strategy: users should be able to reach agents from the collaboration tools they already use. Risk profile is moderate to high. The feature touches gateway runtime routing, auth/security validation, Helm secret handling, and adds a large new adapter file. The main reviewer concern should be whether JWT verification, token handling, and reply routing are implemented consistently with existing gateway adapters and whether the adapter introduces hidden operational risk through skipped verification, secret exposure, or self-echo loops. Best-Practice ComparisonRelevant OpenClaw principles:
Relevant Hermes Agent principles:
Best-practice gap to check during follow-up: the PR should make failure modes observable. Token refresh failures, JWT verification failures, unsupported event types, and outbound post failures should produce useful logs without leaking secrets. Implementation OptionsOption 1: Conservative adapter merge Merge a minimal Google Chat adapter focused only on text DMs and Space thread replies. Require Option 2: Balanced production adapter Accept the core PR but harden it before merge: enforce JWT verification in production-like deployments, add structured logs for auth and delivery failures, add retry/backoff for transient Google API send failures, verify secret handling in Helm, and ensure adapter behavior matches Teams/Feishu patterns. Option 3: Gateway platform abstraction cleanup first Before merging Google Chat, extract common adapter concerns across Teams, Feishu, and Google Chat: token caching, outbound message splitting, request verification hooks, bot filtering, and reply routing. Then land Google Chat on top of the shared abstraction. Option 4: Ambitious durable delivery model Add Google Chat support with a durable outbound message queue, retry/backoff, delivery logs, and idempotency keys for webhook events. This would align more closely with OpenClaw-style durable gateway operations but is significantly larger than a platform adapter PR. Comparison Table
RecommendationAdvance with Option 2: balanced production adapter. The PR’s intent is strong and the feature is valuable, but the next review should focus on production hardening rather than expanding scope. Masami or Pahud should verify JWT enforcement semantics, service account secret handling, outbound error behavior, self-message filtering, and consistency with existing gateway adapters. Suggested sequencing:
|
🟢 Looks good — solid additionVerdict: Clean, well-structured Google Chat adapter that follows existing patterns (Teams, Feishu, LINE). No new dependencies. Comprehensive docs, Helm tests, and unit tests. No blocking issues — all items below are NITs. 四問框架 Review1. What problem does this solve?Adds Google Chat as the 5th gateway adapter platform. Users can chat with OAB agents via Google Chat DMs and Spaces, using the same Custom Gateway architecture as Telegram/LINE/Teams/Feishu. 2. How does it solve it?
3. What alternatives were considered?
4. Is this the best approach?Yes — follows established patterns, no new crates, clean separation. A few NITs below. Traffic Light🟢 INFO — Done well
🟡 NIT — Non-blocking suggestions
🔴 SUGGESTED CHANGESNone — no blocking issues found. |
📊 Prior Art Analysis — Google Chat in Open-Source AI Agent FrameworksSurveyed the major open-source AI agent frameworks for Google Chat support:
This PR would make OpenAB the first open-source AI agent framework with a working Google Chat adapter. Notably, the |
chaodu-agent
left a comment
There was a problem hiding this comment.
Approved — clean, additive Google Chat adapter following established gateway patterns.
Review summary (3/4 monks concur, no blocking issues):
- Pure additive change — no core code modified
- Custom Gateway + Webhook architecture, consistent with Telegram/LINE/Teams/Feishu adapters
- JWT verification correctly implements Google Workspace Add-on OIDC flow (v2 envelope)
- SA key auth with token auto-refresh — addresses the exact failure point that broke OpenClaw's Google Chat support (openclaw/openclaw#9945)
- Comprehensive docs, Helm tests, and unit tests
- First working Google Chat adapter among open-source AI agent frameworks (OpenClaw broken, Hermes/Armis unsupported)
NITs for future improvement (non-blocking):
split_textbyte-based limit vs Google Chat's character-based 4096 limit (CJK splits earlier than necessary)- No inter-chunk delay for
send_message(per-space write quota: 1 req/sec) - Cargo.lock version bump 0.8.1→0.8.3 appears unrelated
- Two separate
reqwest::Clientinstances could be shared - JWKS cache TTL hardcoded at 1 hour (could respect Cache-Control headers)
Add webhook handler for Google Chat MESSAGE events and reply dispatcher. Phase 1 delivers text-only MVP with dry-run mode when no credentials are set. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Google Chat sends events in a nested envelope structure with data under chat.messagePayload, not at the top level as documented in v1 API docs. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Add messageReplyOption query parameter so replies go into the original message thread instead of appearing as top-level messages. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
… responding"
Google Chat requires a non-empty JSON response body from webhook endpoints.
Returning an empty 200 caused the "not responding" indicator to appear in the
chat UI. Changed all webhook returns to respond with `{}` and Content-Type:
application/json.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Add docs/google-chat.md with full setup instructions covering Google Cloud configuration, service account token generation, gateway/OAB config, and troubleshooting. Update README architecture diagram, gateway README env vars and endpoints table, and config.toml.example platform options. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
…efresh for Google Chat - Filter bot messages at gateway level (skip user_type=BOT) to prevent self-echo loops - Split long replies at 4096-char boundary with UTF-8 safe newline/space breaking (matches feishu adapter pattern) - Add GoogleChatTokenCache with JWT-based service account token auto-refresh (via GOOGLE_CHAT_SA_KEY_JSON or GOOGLE_CHAT_SA_KEY_FILE) - Fall back to static GOOGLE_CHAT_ACCESS_TOKEN if no SA key configured - Improve send error logging with status code and response body Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
- Update docs/google-chat.md: document GOOGLE_CHAT_SA_KEY_JSON and GOOGLE_CHAT_SA_KEY_FILE env vars, remove manual token generation section, update feature list with bot filtering/splitting/auto-refresh - Update gateway/README.md env var table with new SA key options - Add 18 unit tests covering: webhook JSON parsing (DM, Space, thread, bot, missing fields, invalid JSON), argument_text preference, sender name parsing, message ID extraction, split_text (short, exact, over limit, newline/space break, Chinese UTF-8, empty), token cache validation, and bot filtering logic Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Validates inbound webhook requests using Google's JWKS public keys. Set GOOGLE_CHAT_PROJECT_NUMBER to enable (audience check against GCP project number). Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
…ation Google Chat webhooks use `https://accounts.google.com` as JWT issuer (not `chat@system.gserviceaccount.com`) and the audience is the webhook URL (not just the project number). Add GOOGLE_CHAT_AUDIENCE env var for explicit audience configuration with PROJECT_NUMBER as fallback. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Follows Teams/Feishu pattern — replaces 3 loose AppState fields with a single `google_chat: Option<GoogleChatAdapter>` and moves handle_reply into an adapter method. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
- Webhook verifier now requires `email == chat@system.gserviceaccount.com` in JWT claims, closing the gap where any Google-signed ID token could pass. - Remove GOOGLE_CHAT_PROJECT_NUMBER env var fallback — the verifier never supported Project Number mode (different iss/JWKS), so advertising it was a footgun. - Update docs and Helm chart to match: only HTTP Endpoint URL mode supported. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
- Helm `$hasGoogleChat` now ORs `audience` so users can deploy a JWT-verifying receive-only gateway (no reply credentials). Aligns with the existing Telegram/LINE pattern: any GC-related field triggers GOOGLE_CHAT_ENABLED=true. - Add 5 deployment-rendering and 3 secret-rendering test cases covering: audience-only, saKeyJson, accessToken, webhookPath, and the "no GC fields" baseline; secret resource only renders when actual secret data exists. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Google Chat webhooks use `service-{PROJECT}@gcp-sa-gsuiteaddons.iam.gserviceaccount.com`,
not `chat@system.gserviceaccount.com`. Check the email suffix instead of
an exact match.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
- Remove GOOGLE_CHAT_PROJECT_NUMBER from gateway README (code no longer supports it) - Fix email claim verification description: suffix check on @gcp-sa-gsuiteaddons.iam.gserviceaccount.com - Simplify Project Number mode note Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
e10d435 to
fa023a5
Compare
Summary
Adds Google Chat support to the Custom Gateway. Users can chat with OAB agents via Google Chat DMs and Spaces.
Changes
gateway/src/adapters/googlechat.rsgateway/src/adapters/mod.rspub mod googlechatgateway/src/main.rsgateway/README.md/webhook/googlechatendpointdocs/google-chat.mddocs/config-reference.md"googlechat"to gateway platform valuescharts/openab/values.yamlgoogleChatconfig block undergatewaycharts/openab/templates/gateway.yamlcharts/openab/templates/gateway-secret.yamlgoogle-chat-sa-key-jsonandgoogle-chat-access-tokento unified Secretcharts/openab/tests/gateway_test.yamlREADME.mdKey Design Decisions
JWT verification via Google OIDC — Webhook requests are signed by
https://accounts.google.com(notchat@system.gserviceaccount.com). Verification uses Google's public JWKS atgoogleapis.com/oauth2/v3/certs, validates issuer, audience (webhook URL), and email suffix (@gcp-sa-gsuiteaddons.iam.gserviceaccount.com).Service Account key auth — Google Chat doesn't support client credentials flow (unlike Teams/Feishu). The adapter signs JWTs with the SA private key to obtain access tokens, with automatic refresh before expiry.
GoogleChatAdapter struct — Encapsulates
token_cache,access_token,jwt_verifier, andclientin a single struct, following the same pattern as Teams and Feishu adapters.Audience-based JWT verification —
GOOGLE_CHAT_AUDIENCEenv var (full webhook URL) is used as the expected JWTaudclaim. If unset, verification is skipped with a warning (for local dev only).Message splitting — Replies exceeding 4096 chars are split at newline/space boundaries to comply with Google Chat API limits.
Testing
Verified end-to-end on k3s with Helm chart deployment:
cargo test— 91 gateway tests passedConfiguration
Not Yet Supported
Test plan
cargo testpasses🤖 Generated with Claude Code