Skip to main content
These are developer notes for the Google Chat upstream connector: how Triage’s diagnostic runs as a Chat app, rendered with Cards v2 over the Chat API. The page documents the platform surface the Intake Gateway’s Google Chat renderer builds on. The gateway itself is described in Upstream connectors.
The Google Chat connector is on the roadmap. The Google Chat renderer ships in the reference implementation; the hosted transport is planned. Method names, scopes and field names on this page are taken from the Chat API v1 discovery document (revision 2026-08-15) and the pages listed under Developer references.

Platform at a glance

A Chat app configured in a Google Cloud project (Chat API configuration) and published to a Workspace organisation or the Marketplace. Base URL https://chat.googleapis.com, REST v1.
App authentication with a service account for the app’s own actions (scope chat.bot, or the granular chat.messages.create and chat.messages); user authentication with OAuth when acting for a person. Inbound deliveries carry a bearer JWT signed by chat@system.gserviceaccount.com with the audience set to the app’s project number, verified against Google’s published keys.
spaces.messages.create: POST /v1/{parent=spaces/*}/messages with a cardsV2 payload. An optional requestId makes the create idempotent: an existing request ID returns the message it already created instead of posting a second one. privateMessageViewer keeps a question visible to one named person, so a diagnostic can run inside a busy space.
spaces.messages.patch (PATCH /v1/{name=spaces/*/messages/*}) with updateMask=cardsV2 replaces the card in place, leaving an answered question with no buttons. A custom messageId at create time means the app can update or delete later without storing Chat’s own resource name.
Cards v2. A message carries a list of {cardId, card} pairs, each card at most 32 KB, built from textParagraph, decoratedText, buttonList and divider, plus textInput, selectionInput and dateTimePicker. Where one step needs several fields at once, the app answers actionResponse.type = DIALOG with a dialogAction.dialog.body card instead.
A button’s onClick.action names a function and parameters. Chat posts a CARD_CLICKED event back and the app reads commonEventObject.invokedFunction, .parameters and .formInputs.WIDGET_NAME. Typed events cover MESSAGE, ADDED_TO_SPACE, REMOVED_FROM_SPACE, CARD_CLICKED, WIDGET_UPDATED, APP_COMMAND, APP_HOME and SUBMIT_FORM.
An HTTPS endpoint, a Pub/Sub topic, or Apps Script. A synchronous reply must be posted within 30 seconds; anything slower answers asynchronously by calling the Chat API. spaces.spaceEvents.list replays typed history such as google.workspace.chat.message.v1.created, so a missed delivery is recovered by reading history. Quotas are per space and per project: 60 writes per minute per space, and an exceeded quota returns 429 to retry with backoff.
The acting person arrives as user on the event (name, displayName, email where the scope allows), which is what the gateway records as the requester.

How the diagnostic runs in Google Chat

Developer references

Google’s official developer documentation. The REST facts on this page come from the machine-readable discovery document, which is the same artefact Google’s own client libraries are generated from.
The Google Chat renderer and its contract tests live in upstream/google_chat_cards.py: the same gateway core as Teams, a different renderer. Locking is structural on this surface too: the answered card is replaced through updateMask=cardsV2 with a version that has no buttons. Upstream connectors explains how to run the reference implementation.

Next steps

Upstream connectors

The Intake Gateway, the card lifecycle and the hand-off to composerID.

Coverage and status

Every surface and destination with its registry status.