Files
vercel__chat/packages/adapter-gchat
github-actions[bot] f84b5911e7 chore(release): version packages (#695)
This PR was opened by the [Changesets
release](https://github.com/changesets/action) GitHub action. When
you're ready to do a release, you can merge this and the packages will
be published to npm automatically. If you're not ready to do a release
yet, that's fine, whenever you add more changesets to main, this PR will
be updated.


# Releases
## @chat-adapter/discord@4.34.0

### Minor Changes

- 0fdb902: Add opt-in Discord Components v2 rendering for Chat SDK cards
via `contentFormat: DiscordContentFormat.ComponentsV2`.
- 5341f90: Ignore `@everyone`/`@here` pings by default in gateway mode.
Previously the legacy gateway listener treated global pings as bot
mentions, so the bot responded to announcements. A new
`respondToGlobalMentions` config option (default `false`) restores the
old behavior when enabled, and also lets forwarded gateway messages opt
in via the `mention_everyone` field.
- 6c2a391: Add support for renaming native Discord thread channels.

### Patch Changes

- Updated dependencies [5c926f1]
- Updated dependencies [2531a42]
- Updated dependencies [1721fa0]
- Updated dependencies [4717a38]
- Updated dependencies [6714efc]
  - chat@4.34.0
  - @chat-adapter/shared@4.34.0
## @chat-adapter/slack@4.34.0

### Minor Changes

- 1721fa0: Add support for Slack's Agent messaging experience
(`agent_view`).

- New core event `onAppContextChanged` with a normalized
`AppContextEntity[]` describing the user's active view (channel / canvas
/ list / message / unknown).
- `AppHomeOpenedEvent` now carries the folded active-view context as
`entities` and the opened `tab` (Slack: `"home"` / `"messages"`), so
handlers can tell a Home-tab open from the DM-open signal under
`agent_view`.
- Slack adapter: new `agentView` config flag (under `agent_view`,
`app_home_opened` is the DM-open signal regardless of tab and folded
context is surfaced), routing for the `app_context_changed` event, and a
`getAppContext(message)` helper to read the folded context on DM
messages.
- `setSuggestedPrompts` now accepts an optional thread reference
(agent_view lets prompts sit at the top of the agent conversation).
- Under `agentView`, DM (Messages-tab) messages are threaded per new
Slack's model — each user message is a thread root (`thread_ts ?? ts`).
Conversation-scoped threads returned by `openDM()` keep working: when
that thread is subscribed, incoming top-level DM messages route to it.
- `createSlackAdapter` env auth fallback (`SLACK_BOT_TOKEN` /
`SLACK_CLIENT_ID` / `SLACK_CLIENT_SECRET`) is now disabled only when an
auth or verification field (`botToken`, `clientId`, `clientSecret`,
`installationProvider`, `signingSecret`, `webhookVerifier`) is passed
explicitly, instead of by any config object — so `createSlackAdapter({
agentView: true })` still picks up env credentials, while
explicit-secret configs stay immune to ambient env vars.
- Bumped `@slack/web-api` to `^7.18.0` (adds the optional `thread_ts`
typing for `setSuggestedPrompts`).

- 4717a38: Add chart support and richer table rendering, with native
Slack data table and data visualization blocks.

- New core `ChartElement` and `Chart()` builder (JSX supported) with
pie, bar, area, and line charts, mirroring Slack's data visualization
model: pie charts take `segments`, series charts take named `series`
plotted against shared `categories` with optional `xLabel`/`yLabel`.
- `TableElement` / `Table()` gain optional `caption` (accessible table
description) and `pageSize` (rows per page) fields.
- Charts degrade gracefully on platforms without native chart support:
the underlying data renders as a text table via the shared card fallback
(new `chartElementToFallbackText` helper).
- Slack adapter: card tables now render as [data table
blocks](https://docs.slack.dev/reference/block-kit/blocks/data-table-block)
by default — paginated and sortable — instead of plain table blocks.
Header-only tables keep the plain table block; tables exceeding Slack
limits (100 data rows, 20 columns, 10,000 characters) fall back to ASCII
as before.
- Slack adapter: card charts render as [data visualization
blocks](https://docs.slack.dev/reference/block-kit/blocks/data-visualization-block).
Charts violating Slack constraints (50-character title, 12
segments/series, 20 categories, 20-character labels, one data point per
category, max 2 charts per message) fall back to a text rendering
instead of being rejected by the API.
- The `@chat-adapter/slack/blocks` subpath gets the same treatment:
`SlackChartElement` types, `chart` card children, data table rendering,
and matching limits.
- `postMessage` now surfaces Slack's per-block validation details when
the API rejects blocks (`invalid_blocks`), instead of the bare "An API
error occurred" message.

- 0f743c9: Add declarative agent-experience config and harden native
streaming:

- `suggestedPrompts` — a static payload or per-thread resolver, applied
automatically when an assistant/agent thread opens
(`assistant_thread_started` in legacy `assistant_view`, or a
Messages-tab `app_home_opened` under `agentView`, where prompts pin at
the top of the agent conversation without a `thread_ts`). The resolver
receives the thread context (`channelId`, `userId`, legacy
`threadTs`/`teamId`/`enterpriseId`, and active-view `entities` under
`agentView`); returning `null`/`undefined` skips the thread. Prompts
beyond Slack's 4-prompt limit are dropped with a warning, and
resolver/API failures are logged without failing the webhook.
- `loadingMessages` — default rotating status strings for the assistant
thinking indicator, used by `startTyping` and `setAssistantStatus` when
no explicit status/messages are passed.
- `nativeStreaming` config (default `true`). Set `false` on Slack
flavours without the `chat.startStream` family (e.g. GovSlack) to always
stream via post-and-edit.
- If the workspace rejects the first native streaming call, `stream()`
now falls back to throttled post-and-edit mid-stream instead of failing
the reply; already-consumed text is preserved. Permanent platform errors
(`unknown_method`, `method_deprecated`, `feature_not_enabled`) latch
native streaming off for subsequent streams on the adapter instance.
Structured chunks (`task_update` / `plan_update`) are skipped in
fallback mode.

- `feedbackButtons` — append Slack's native thumbs up/down
(`context_actions` + `feedback_buttons` block) to every streamed reply.
Pass `true` for defaults or an options object (`actionId`, labels,
values); clicks dispatch through `bot.onAction` with a positive/negative
value. A `buildFeedbackButtonsBlock(options?)` helper is exported for
attaching the block to non-streamed messages.

New exported types: `SlackFeedbackButtonsOptions`,
`SlackSuggestedPrompt`, `SlackSuggestedPrompts`,
`SlackSuggestedPromptsContext`, `SlackSuggestedPromptsOptions`.

### Patch Changes

- Updated dependencies [5c926f1]
- Updated dependencies [2531a42]
- Updated dependencies [1721fa0]
- Updated dependencies [4717a38]
- Updated dependencies [6714efc]
  - chat@4.34.0
  - @chat-adapter/shared@4.34.0
## @chat-adapter/telegram@4.34.0

### Minor Changes

- 8d7ccdb: Add Telegram media group uploads for multiple files and
attachments.

### Patch Changes

- 2531a42: Fix `detectMention` (and the Telegram adapter's
`isBotMentioned`) falsely matching `@bot` when `@bot-dev` is mentioned.
`\b` (word boundary) matches between a word character and a hyphen, so
`/@bot\b/` incorrectly matches `@bot-dev`. Replaced with `(?![\w-])` to
exclude hyphens.
- Updated dependencies [5c926f1]
- Updated dependencies [2531a42]
- Updated dependencies [1721fa0]
- Updated dependencies [4717a38]
- Updated dependencies [6714efc]
  - chat@4.34.0
  - @chat-adapter/shared@4.34.0
## @chat-adapter/web@4.34.0

### Minor Changes

- 6714efc: Support AI SDK v7 as a peer dependency.

- `chat` now accepts `ai@^6.0.182 || ^7.0.0` (`chat/ai` tools work with
both majors).
- `@chat-adapter/web` now accepts `ai@^6 || ^7`, `@ai-sdk/react@^3 ||
^4`, `@ai-sdk/svelte@^4 || ^5`, and `@ai-sdk/vue@^3 || ^4`.
- The `chat/ai` tool factories now declare explicit `Tool<Input,
Output>` return types instead of relying on inference, so the published
declarations no longer depend on `ai` internals that changed in v7. The
public type surface is unchanged.

### Patch Changes

- Updated dependencies [5c926f1]
- Updated dependencies [2531a42]
- Updated dependencies [1721fa0]
- Updated dependencies [4717a38]
- Updated dependencies [6714efc]
  - chat@4.34.0
  - @chat-adapter/shared@4.34.0
## @chat-adapter/whatsapp@4.34.0

### Minor Changes

- 2338a66: Add `sendTemplate()` for sending pre-approved template
messages, enabling business-initiated conversations outside the 24-hour
customer service window
- 8bd8a57: Implement outbound file and attachment sending for the
WhatsApp adapter.

Supports binary `FileUpload` uploads, typed `Attachment` payloads
(binary or HTTPS link passthrough), multi-file sequential sends, smart
MIME-to-message-type mapping, caption placement with audio/long-text
fallbacks, and card+file sequencing.

### Patch Changes

- Updated dependencies [5c926f1]
- Updated dependencies [2531a42]
- Updated dependencies [1721fa0]
- Updated dependencies [4717a38]
- Updated dependencies [6714efc]
  - chat@4.34.0
  - @chat-adapter/shared@4.34.0
## @chat-adapter/x@4.34.0

### Minor Changes

- 4bca64f: add image upload support to X posts and DMs via the chunked
media upload endpoints

### Patch Changes

- Updated dependencies [5c926f1]
- Updated dependencies [2531a42]
- Updated dependencies [1721fa0]
- Updated dependencies [4717a38]
- Updated dependencies [6714efc]
  - chat@4.34.0
  - @chat-adapter/shared@4.34.0
## chat@4.34.0

### Minor Changes

- 1721fa0: Add support for Slack's Agent messaging experience
(`agent_view`).

- New core event `onAppContextChanged` with a normalized
`AppContextEntity[]` describing the user's active view (channel / canvas
/ list / message / unknown).
- `AppHomeOpenedEvent` now carries the folded active-view context as
`entities` and the opened `tab` (Slack: `"home"` / `"messages"`), so
handlers can tell a Home-tab open from the DM-open signal under
`agent_view`.
- Slack adapter: new `agentView` config flag (under `agent_view`,
`app_home_opened` is the DM-open signal regardless of tab and folded
context is surfaced), routing for the `app_context_changed` event, and a
`getAppContext(message)` helper to read the folded context on DM
messages.
- `setSuggestedPrompts` now accepts an optional thread reference
(agent_view lets prompts sit at the top of the agent conversation).
- Under `agentView`, DM (Messages-tab) messages are threaded per new
Slack's model — each user message is a thread root (`thread_ts ?? ts`).
Conversation-scoped threads returned by `openDM()` keep working: when
that thread is subscribed, incoming top-level DM messages route to it.
- `createSlackAdapter` env auth fallback (`SLACK_BOT_TOKEN` /
`SLACK_CLIENT_ID` / `SLACK_CLIENT_SECRET`) is now disabled only when an
auth or verification field (`botToken`, `clientId`, `clientSecret`,
`installationProvider`, `signingSecret`, `webhookVerifier`) is passed
explicitly, instead of by any config object — so `createSlackAdapter({
agentView: true })` still picks up env credentials, while
explicit-secret configs stay immune to ambient env vars.
- Bumped `@slack/web-api` to `^7.18.0` (adds the optional `thread_ts`
typing for `setSuggestedPrompts`).

- 4717a38: Add chart support and richer table rendering, with native
Slack data table and data visualization blocks.

- New core `ChartElement` and `Chart()` builder (JSX supported) with
pie, bar, area, and line charts, mirroring Slack's data visualization
model: pie charts take `segments`, series charts take named `series`
plotted against shared `categories` with optional `xLabel`/`yLabel`.
- `TableElement` / `Table()` gain optional `caption` (accessible table
description) and `pageSize` (rows per page) fields.
- Charts degrade gracefully on platforms without native chart support:
the underlying data renders as a text table via the shared card fallback
(new `chartElementToFallbackText` helper).
- Slack adapter: card tables now render as [data table
blocks](https://docs.slack.dev/reference/block-kit/blocks/data-table-block)
by default — paginated and sortable — instead of plain table blocks.
Header-only tables keep the plain table block; tables exceeding Slack
limits (100 data rows, 20 columns, 10,000 characters) fall back to ASCII
as before.
- Slack adapter: card charts render as [data visualization
blocks](https://docs.slack.dev/reference/block-kit/blocks/data-visualization-block).
Charts violating Slack constraints (50-character title, 12
segments/series, 20 categories, 20-character labels, one data point per
category, max 2 charts per message) fall back to a text rendering
instead of being rejected by the API.
- The `@chat-adapter/slack/blocks` subpath gets the same treatment:
`SlackChartElement` types, `chart` card children, data table rendering,
and matching limits.
- `postMessage` now surfaces Slack's per-block validation details when
the API rejects blocks (`invalid_blocks`), instead of the bare "An API
error occurred" message.

- 6714efc: Support AI SDK v7 as a peer dependency.

- `chat` now accepts `ai@^6.0.182 || ^7.0.0` (`chat/ai` tools work with
both majors).
- `@chat-adapter/web` now accepts `ai@^6 || ^7`, `@ai-sdk/react@^3 ||
^4`, `@ai-sdk/svelte@^4 || ^5`, and `@ai-sdk/vue@^3 || ^4`.
- The `chat/ai` tool factories now declare explicit `Tool<Input,
Output>` return types instead of relying on inference, so the published
declarations no longer depend on `ai` internals that changed in v7. The
public type surface is unchanged.

### Patch Changes

- 5c926f1: Preserve markdown structural whitespace when extracting
normalized message text.
- 2531a42: Fix `detectMention` (and the Telegram adapter's
`isBotMentioned`) falsely matching `@bot` when `@bot-dev` is mentioned.
`\b` (word boundary) matches between a word character and a hyphen, so
`/@bot\b/` incorrectly matches `@bot-dev`. Replaced with `(?![\w-])` to
exclude hyphens.
## @chat-adapter/gchat@4.34.0

### Patch Changes

- Updated dependencies [5c926f1]
- Updated dependencies [2531a42]
- Updated dependencies [1721fa0]
- Updated dependencies [4717a38]
- Updated dependencies [6714efc]
  - chat@4.34.0
  - @chat-adapter/shared@4.34.0
## @chat-adapter/github@4.34.0

### Patch Changes

- Updated dependencies [5c926f1]
- Updated dependencies [2531a42]
- Updated dependencies [1721fa0]
- Updated dependencies [4717a38]
- Updated dependencies [6714efc]
  - chat@4.34.0
  - @chat-adapter/shared@4.34.0
## @chat-adapter/linear@4.34.0

### Patch Changes

- Updated dependencies [5c926f1]
- Updated dependencies [2531a42]
- Updated dependencies [1721fa0]
- Updated dependencies [4717a38]
- Updated dependencies [6714efc]
  - chat@4.34.0
  - @chat-adapter/shared@4.34.0
## @chat-adapter/messenger@4.34.0

### Patch Changes

- Updated dependencies [5c926f1]
- Updated dependencies [2531a42]
- Updated dependencies [1721fa0]
- Updated dependencies [4717a38]
- Updated dependencies [6714efc]
  - chat@4.34.0
  - @chat-adapter/shared@4.34.0
## @chat-adapter/shared@4.34.0

### Patch Changes

- Updated dependencies [5c926f1]
- Updated dependencies [2531a42]
- Updated dependencies [1721fa0]
- Updated dependencies [4717a38]
- Updated dependencies [6714efc]
  - chat@4.34.0
## @chat-adapter/teams@4.34.0

### Patch Changes

- Updated dependencies [5c926f1]
- Updated dependencies [2531a42]
- Updated dependencies [1721fa0]
- Updated dependencies [4717a38]
- Updated dependencies [6714efc]
  - chat@4.34.0
  - @chat-adapter/shared@4.34.0
## @chat-adapter/twilio@4.34.0

### Patch Changes

- Updated dependencies [5c926f1]
- Updated dependencies [2531a42]
- Updated dependencies [1721fa0]
- Updated dependencies [4717a38]
- Updated dependencies [6714efc]
  - chat@4.34.0
  - @chat-adapter/shared@4.34.0
## @chat-adapter/state-ioredis@4.34.0

### Patch Changes

- Updated dependencies [5c926f1]
- Updated dependencies [2531a42]
- Updated dependencies [1721fa0]
- Updated dependencies [4717a38]
- Updated dependencies [6714efc]
  - chat@4.34.0
## @chat-adapter/state-memory@4.34.0

### Patch Changes

- Updated dependencies [5c926f1]
- Updated dependencies [2531a42]
- Updated dependencies [1721fa0]
- Updated dependencies [4717a38]
- Updated dependencies [6714efc]
  - chat@4.34.0
## @chat-adapter/state-pg@4.34.0

### Patch Changes

- Updated dependencies [5c926f1]
- Updated dependencies [2531a42]
- Updated dependencies [1721fa0]
- Updated dependencies [4717a38]
- Updated dependencies [6714efc]
  - chat@4.34.0
## @chat-adapter/state-redis@4.34.0

### Patch Changes

- Updated dependencies [5c926f1]
- Updated dependencies [2531a42]
- Updated dependencies [1721fa0]
- Updated dependencies [4717a38]
- Updated dependencies [6714efc]
  - chat@4.34.0
## @chat-adapter/tests@4.34.0

Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
2026-07-13 16:41:59 +01:00
..
2026-06-16 08:48:38 +01:00
2026-02-20 13:25:09 -08:00

Google Chat adapter for Chat SDK

@chat-adapter/gchat

npm package: @chat-adapter/gchat

Agent Stack MIT License

Google Chat adapter for Chat SDK. Configure with service account authentication and optional Pub/Sub.

Documentation: chat-sdk.dev/adapters/official/gchat · Guides: vercel.com/kb/chat-sdk

Installation

pnpm add @chat-adapter/gchat

Scaffold with the CLI

To scaffold a new Google Chat bot with this adapter preselected:

npx create-chat-sdk@latest my-bot --adapter gchat memory

Visit the adapters directory to see other available official and vendor-official adapters.

Usage

The adapter auto-detects credentials from GOOGLE_CHAT_CREDENTIALS or GOOGLE_CHAT_USE_ADC environment variables:

import { Chat } from "chat";
import { createGoogleChatAdapter } from "@chat-adapter/gchat";

const bot = new Chat({
  userName: "mybot",
  adapters: {
    gchat: createGoogleChatAdapter(),
  },
});

bot.onNewMention(async (thread, message) => {
  await thread.post("Hello from Google Chat!");
});

Google Chat setup

1. Create a GCP project

  1. Go to console.cloud.google.com
  2. Click the project dropdown then New Project
  3. Enter project name and click Create

2. Enable required APIs

Go to APIs & Services then Library and enable:

  • Google Chat API
  • Google Workspace Events API (for receiving all messages)
  • Cloud Pub/Sub API (for receiving all messages)

3. Create a service account

  1. Go to IAM & Admin then Service Accounts
  2. Click Create Service Account
  3. Enter name and description
  4. Click Create and Continue
  5. Skip the optional steps, click Done

4. Create service account key

  1. Click on your service account
  2. Go to Keys tab
  3. Click Add Key then Create new key
  4. Select JSON and click Create
  5. Copy the entire JSON content as GOOGLE_CHAT_CREDENTIALS

Note: If your organization has the iam.disableServiceAccountKeyCreation constraint enabled, you need to relax it or add an exception for your project in IAM & Admin then Organization Policies.

5. Configure Google Chat app

  1. Go to the Chat API configuration
  2. Click Configuration and fill in:
    • App name: Your bot's display name
    • Avatar URL: URL to your bot's avatar
    • Description: What your bot does
    • Interactive features: Enable Receive 1:1 messages and Join spaces and group conversations
    • Connection settings: Select App URL
    • App URL: https://your-domain.com/api/webhooks/gchat
    • Visibility: Choose who can discover your app
  3. Click Save

6. Add bot to a space

  1. Open Google Chat
  2. Create or open a Space
  3. Click the space name then Manage apps & integrations
  4. Click Add apps, search for your app, and click Add

Pub/Sub for all messages (optional)

By default, Google Chat only sends webhooks for @mentions. To receive all messages in a space, set up Workspace Events with Pub/Sub.

createGoogleChatAdapter({
  pubsubTopic: process.env.GOOGLE_CHAT_PUBSUB_TOPIC,
  impersonateUser: process.env.GOOGLE_CHAT_IMPERSONATE_USER,
});

GOOGLE_CHAT_PUBSUB_TOPIC and GOOGLE_CHAT_IMPERSONATE_USER are also auto-detected from env vars, so you can omit them from config if the env vars are set.

1. Create Pub/Sub topic

  1. Go to Pub/Sub then Topics
  2. Click Create Topic
  3. Enter topic ID (e.g., chat-events)
  4. Uncheck Add a default subscription
  5. Click Create
  6. Copy the full topic name as GOOGLE_CHAT_PUBSUB_TOPIC (format: projects/your-project-id/topics/chat-events)

2. Grant Chat service account access

  1. Go to your Pub/Sub topic
  2. Click Permissions tab
  3. Click Add Principal
  4. Enter chat-api-push@system.gserviceaccount.com
  5. Select role Pub/Sub Publisher
  6. Click Save

3. Create push subscription

  1. Go to Pub/Sub then Subscriptions
  2. Click Create Subscription
  3. Select your topic
  4. Set Delivery type to Push
  5. Set Endpoint URL to https://your-domain.com/api/webhooks/gchat
  6. Click Create

4. Enable domain-wide delegation

Domain-wide delegation is required for creating Workspace Events subscriptions and initiating DMs.

Step 1 — Enable delegation on the service account:

  1. Go to IAM & Admin then Service Accounts
  2. Click on your service account
  3. Check Enable Google Workspace Domain-wide Delegation and save
  4. Copy the Client ID (a numeric ID, not the email)

Step 2 — Authorize in Google Admin Console:

  1. Go to Google Admin Console
  2. Go to Security then Access and data control then API controls
  3. Click Manage Domain Wide Delegation then Add new
  4. Enter the numeric Client ID from Step 1
  5. Add OAuth scopes (comma-separated, on one line):
    https://www.googleapis.com/auth/chat.spaces.readonly,https://www.googleapis.com/auth/chat.messages.readonly,https://www.googleapis.com/auth/chat.spaces,https://www.googleapis.com/auth/chat.spaces.create
    
  6. Click Authorize

Step 3 — Set environment variable:

Set GOOGLE_CHAT_IMPERSONATE_USER to an admin user email in your domain (e.g., admin@yourdomain.com).

Configuration

All options are auto-detected from environment variables when not provided.

Option Required Description
credentials No* Service account credentials JSON. Auto-detected from GOOGLE_CHAT_CREDENTIALS
useApplicationDefaultCredentials No Use Application Default Credentials. Auto-detected from GOOGLE_CHAT_USE_ADC
pubsubTopic No Pub/Sub topic for Workspace Events. Auto-detected from GOOGLE_CHAT_PUBSUB_TOPIC
pubsubAudience No† Expected JWT audience for Pub/Sub webhook verification. Auto-detected from GOOGLE_CHAT_PUBSUB_AUDIENCE
googleChatProjectNumber No† GCP project number for direct webhook JWT verification. Auto-detected from GOOGLE_CHAT_PROJECT_NUMBER
disableSignatureVerification No† Disable JWT verification entirely (development only). Auto-detected from GOOGLE_CHAT_DISABLE_SIGNATURE_VERIFICATION=true
impersonateUser No User email for domain-wide delegation. Auto-detected from GOOGLE_CHAT_IMPERSONATE_USER
auth No Custom auth object (advanced)
apiUrl No Override the Google Chat API base URL. Auto-detected from GOOGLE_CHAT_API_URL
logger No Logger instance (defaults to ConsoleLogger("info"))

*Either credentials, GOOGLE_CHAT_CREDENTIALS env var, useApplicationDefaultCredentials, or GOOGLE_CHAT_USE_ADC=true is required.

†One of googleChatProjectNumber, pubsubAudience, or disableSignatureVerification: true is required — the constructor throws otherwise. Configure the verifier(s) for each transport you actually receive; requests of a shape whose verifier is unconfigured are rejected with HTTP 401.

Environment variables

GOOGLE_CHAT_CREDENTIALS={"type":"service_account",...}

# Optional: for receiving all messages
GOOGLE_CHAT_PUBSUB_TOPIC=projects/your-project/topics/chat-events
GOOGLE_CHAT_IMPERSONATE_USER=admin@yourdomain.com

# Webhook verification — at least one of the three is required
GOOGLE_CHAT_PROJECT_NUMBER=123456789          # For direct webhook JWT verification
GOOGLE_CHAT_PUBSUB_AUDIENCE=https://your-domain.com/api/webhooks/gchat  # For Pub/Sub JWT verification
# GOOGLE_CHAT_DISABLE_SIGNATURE_VERIFICATION=true  # Escape hatch for local dev only

# Optional: override the Google Chat API base URL
GOOGLE_CHAT_API_URL=...

Webhook verification

The adapter supports JWT verification for both webhook types. When configured, the adapter validates the Authorization: Bearer <JWT> header on incoming requests using Google's public keys. Requests with missing or invalid tokens are rejected with HTTP 401.

Verification is required. The constructor throws ValidationError unless one of the following is set:

  • googleChatProjectNumber (or GOOGLE_CHAT_PROJECT_NUMBER) — direct webhooks
  • pubsubAudience (or GOOGLE_CHAT_PUBSUB_AUDIENCE) — Pub/Sub push deliveries
  • disableSignatureVerification: true (or GOOGLE_CHAT_DISABLE_SIGNATURE_VERIFICATION=true) — explicit opt-out, intended for local development only

The two transports share one HTTP endpoint, so each verifier only covers its own request shape. If you only configure googleChatProjectNumber, incoming Pub/Sub-shaped requests are rejected with HTTP 401, and vice versa — configure both if you receive both.

Direct webhooks (Google Chat API)

Google Chat sends a signed JWT with every webhook request. The JWT audience (aud claim) is your GCP project number.

createGoogleChatAdapter({
  googleChatProjectNumber: "123456789",
});

Find your project number in the GCP Console dashboard (it's different from the project ID).

Pub/Sub push messages

Google Cloud Pub/Sub sends a signed OIDC JWT with push deliveries. The JWT audience is whatever you configured on the push subscription.

createGoogleChatAdapter({
  pubsubAudience: "https://your-domain.com/api/webhooks/gchat",
});

To enable authenticated push on your Pub/Sub subscription:

  1. Go to Pub/Sub then Subscriptions
  2. Edit your push subscription
  3. Enable Authentication
  4. Select a service account with the Service Account Token Creator role
  5. Set the Audience to your webhook URL
  6. Use the same URL as GOOGLE_CHAT_PUBSUB_AUDIENCE

Features

Messaging

Feature Supported
Post message Yes
Edit message Yes
Delete message Yes
File uploads No
Streaming Post+Edit fallback

Rich content

Feature Supported
Card format Google Chat Cards
Buttons Yes
Link buttons Yes
Select menus Yes
Tables ASCII
Fields Yes
Images in cards Yes
Modals No

Conversations

Feature Supported
Slash commands No
Mentions Yes
Add reactions Yes (via Workspace Events)
Remove reactions Yes (via Workspace Events)
Typing indicator No
DMs Yes (requires delegation)
Ephemeral messages Yes (native)

Message history

Feature Supported
Fetch messages Yes
Fetch single message No
Fetch thread info Yes
Fetch channel messages Yes
List threads Yes
Fetch channel info Yes
Post channel message Yes

Limitations

  • Typing indicators: Not supported by Google Chat API. startTyping() is a no-op.
  • Adding reactions: The Google Chat API doesn't support service account (app) authentication for adding reactions. To use addReaction() or removeReaction(), you need domain-wide delegation with impersonateUser configured — but the reaction appears as coming from the impersonated user, not the bot.

Message history (fetchMessages)

Fetching message history requires domain-wide delegation with the impersonateUser config option set. The impersonated user must have access to the spaces you want to read from. See the Pub/Sub setup above for configuring delegation and OAuth scopes.

Troubleshooting

401 Unauthorized on webhooks

  • For direct webhooks: verify GOOGLE_CHAT_PROJECT_NUMBER matches your GCP project number (not project ID)
  • For Pub/Sub: verify GOOGLE_CHAT_PUBSUB_AUDIENCE matches the audience configured on your push subscription
  • Check that authentication is enabled on your Pub/Sub push subscription
  • Ensure the service account used for push authentication has the Service Account Token Creator role

No webhook received

  • Verify the App URL is correct in Google Chat configuration
  • Check that the Chat API is enabled
  • Ensure the service account has the necessary permissions

Pub/Sub not working

  • Verify chat-api-push@system.gserviceaccount.com has Pub/Sub Publisher role
  • Check that the push subscription URL is correct
  • Verify domain-wide delegation is configured with correct scopes
  • Check GOOGLE_CHAT_IMPERSONATE_USER is a valid admin email

"Permission denied" for Workspace Events

  • Ensure domain-wide delegation is configured
  • Verify the OAuth scopes are exactly as specified
  • Check that the impersonated user has access to the spaces

"Insufficient Permission" for DMs

  • DMs require domain-wide delegation with chat.spaces and chat.spaces.create scopes
  • Scope changes can take up to 24 hours to propagate

Button clicks not received

  • Verify Interactive features is enabled in the Google Chat app configuration
  • Check that the App URL is correctly set and accessible
  • Button clicks go to the same webhook URL as messages

AI Coding Agents

If you use an AI coding agent such as OpenAI Codex, Claude Code, or Cursor, install the Chat SDK skill so it knows the SDK APIs, adapter patterns, and project conventions before writing code.

npx skills add vercel/chat

The skill references bundled documentation in node_modules/chat/docs, plus adapter guides and starter templates in the published package.

You can also install the Vercel Plugin for a broader agent toolkit — it includes the Chat SDK skill alongside specialist agents, agent slash commands, and more:

npx plugins add vercel/vercel-plugin

The plugin is optional; the skill alone is enough to build with Chat SDK.

For agent-readable documentation, see chat-sdk.dev/llms.txt (page index) or chat-sdk.dev/llms-full.txt (full text).

License

MIT