Skip to content

bug(gateway/googlechat): adapter silently drops events from docs-recommended HTTP endpoint URL setup #899

@sebastian-hsu

Description

@sebastian-hsu

Description

Following docs/google-chat.md end-to-end results in the bot never replying in either DM or Space contexts. Two independent bugs in openab-gateway 0.5.1 (the latest gateway release) make the documented HTTP endpoint URL connection mode unusable:

Bug 1: Envelope schema doesn't match HTTP endpoint URL payload

The googlechat adapter (gateway/src/adapters/googlechat.rs) only deserializes Pub/Sub-style envelopes (chat.messagePayload.message). Google's HTTP endpoint URL connection actually delivers a top-level shape (message, user, space, thread, common). The handler hits let Some(chat) = envelope.chat else { return empty_json_response(); } and silently returns 200, so Google sees "delivered OK" but no message ever reaches the agent.

Bug 2: JWT verification expects the wrong `email` claim

The JWT verifier (`GOOGLE_CHAT_EMAIL_SUFFIX` at line 135 on `main`) expects `email` to end with `@gcp-sa-gsuiteaddons.iam.gserviceaccount.com` (the Workspace Add-ons signer). Google Chat actually signs webhooks as `chat@system.gserviceaccount.com`. Result: setting `GOOGLE_CHAT_AUDIENCE` per docs returns `401` to every Chat webhook. The only way to receive anything is to leave `GOOGLE_CHAT_AUDIENCE` unset, which `docs/google-chat.md` explicitly labels insecure.

Together: following the docs verbatim gives you a 100% non-working bot, and even unsetting the audience gives you a silently broken one.

Steps to Reproduce

Follow `docs/google-chat.md` exactly:

  1. Create a Chat App in Google Cloud Console, Connection settings = App URL, Authentication Audience = HTTP Endpoint URL, App URL = `https:///webhook/googlechat`
  2. Deploy openab-gateway 0.5.1 with `GOOGLE_CHAT_ENABLED=true`, `GOOGLE_CHAT_AUDIENCE=https:///webhook/googlechat`, `GOOGLE_CHAT_SA_KEY_JSON=<sa.json>`
  3. Send the bot a 1:1 DM or @mention it in a Space

Observed (Bug 2): all webhooks rejected with `googlechat webhook JWT verification failed error=email claim mismatch: expected *@gcp-sa-gsuiteaddons.iam.gserviceaccount.com, got chat@system.gserviceaccount.com`. User sees "OpenAB not responding".

Workaround: unset `GOOGLE_CHAT_AUDIENCE`. Now Bug 1 manifests: gateway logs `googlechat webhook received (N bytes)` for every webhook and nothing further. No agent invocation. User sees nothing (Google considers webhook delivered because gateway returns 200).

Expected Behavior

  1. JWT verification should accept `chat@system.gserviceaccount.com` (the documented Google Chat signer).
  2. The envelope parser should accept both the Pub/Sub-wrapped format AND the top-level HTTP endpoint URL format, with the latter being what the docs explicitly recommend.

Environment

  • openab-gateway image: `ghcr.io/openabdev/openab-gateway:0.5.1` (latest gateway release as of 2026-05-22; gateway versions independently from the openab helm chart)
  • openab helm chart: `openab-0.8.3` (latest stable)
  • Connection mode: HTTP Endpoint URL (per `docs/google-chat.md` recommendation)
  • Workspace: Google Workspace Business
  • Tested contexts: 1:1 DM and Space @mention (both fail identically)

Screenshots / Logs

Real webhook body delivered by Google Chat (top-level shape, no `chat` wrapper):

Full body (sanitized)

```json
{
"type": "MESSAGE",
"eventTime": "2026-05-22T03:00:57.997391Z",
"message": {
"name": "spaces//messages/",
"sender": {"name": "users/", "displayName": "...", "email": "...", "type": "HUMAN"},
"createTime": "...",
"text": "test",
"argumentText": "test",
"thread": {"name": "spaces//threads/"},
"space": {"name": "spaces/", "type": "DM", "spaceType": "DIRECT_MESSAGE"}
},
"user": {"name": "users/", "type": "HUMAN", "email": "..."},
"space": {"name": "spaces/", "type": "DM", "spaceType": "DIRECT_MESSAGE"},
"thread": {"name": "spaces//threads/"},
"common": {"userLocale": "en", "hostApp": "CHAT", "timeZone": {"id": "Asia/Taipei"}}
}
```

Gateway log when audience set (Bug 2):

```
WARN googlechat webhook JWT verification failed error=email claim mismatch:
expected *@gcp-sa-gsuiteaddons.iam.gserviceaccount.com,
got chat@system.gserviceaccount.com
```

Gateway log when audience unset (Bug 1):

```
INFO googlechat webhook received (4527 bytes)
(nothing further — silent drop at `envelope.chat is None`)
```

Proposed Fix

Not sending a PR for now, but happy to if helpful:

  1. Bug 2: change the JWT email allow-list to `chat@system.gserviceaccount.com` (or accept both, for safety).
  2. Bug 1: extend `GoogleChatEnvelope` with optional top-level `message` / `user` / `space` fields, and have the handler use the wrapped form first then fall back to top-level. Existing v2 tests still pass; real HTTP webhooks now process correctly.

Locally patched version is running in production for me right now.

Metadata

Metadata

Assignees

No one assigned

    Type

    No type
    No fields configured for issues without a type.

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions