Files
vercel__chat/packages/adapter-gchat
github-actions[bot] 3468cdfe0b chore(release): version packages (#767)
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/gchat@4.37.0

### Minor Changes

- c3b5a08: Bind Pub/Sub push verification to a specific identity with
the new pubsubServiceAccountEmail option, alongside the existing
audience check. Pushes are rejected unless the token email matches it.
Direct webhooks are unaffected.
- 7a19223: Bind Workspace Add-on webhook verification to a specific
identity with the new `workspaceAddOnServiceAccountEmail` option,
replacing a pattern match on the add-on service account email. Workspace
Add-on Chat apps must set it; standalone Chat apps are unaffected.

### Patch Changes

- Updated dependencies [2a2b2c5]
- Updated dependencies [4ac0455]
- Updated dependencies [0ec6a73]
- Updated dependencies [85e3d22]
  - chat@4.37.0
  - @chat-adapter/shared@4.37.0
## @chat-adapter/instagram@4.37.0

### Minor Changes

- 2a2b2c5: Add a native Instagram Direct Messages adapter with signed
webhooks, media, quick replies, story context, reactions, and typed Meta
API errors.

### Patch Changes

- Updated dependencies [2a2b2c5]
- Updated dependencies [4ac0455]
- Updated dependencies [0ec6a73]
- Updated dependencies [85e3d22]
  - chat@4.37.0
  - @chat-adapter/shared@4.37.0
## @chat-adapter/notion@4.37.0

### Minor Changes

- 0ec6a73: Add `@chat-adapter/notion` for Notion page and block comment
discussions: webhook HMAC verification, Post+Edit streaming,
conversation history, `message.subject` page metadata, plain-text
`@userName`/`@botUserId` mention detection, and File Uploads (up to 3
native attachments). Registers the adapter in the `chat/adapters`
catalog and `create-chat-sdk` CLI scaffold, and adds Notion emoji
platform support.

### Patch Changes

- Updated dependencies [2a2b2c5]
- Updated dependencies [4ac0455]
- Updated dependencies [0ec6a73]
- Updated dependencies [85e3d22]
  - chat@4.37.0
  - @chat-adapter/shared@4.37.0
## @chat-adapter/slack@4.37.0

### Minor Changes

- 4ac0455: Add message update and delete lifecycle callbacks, with Slack
message_changed and message_deleted dispatch support.

### Patch Changes

- 6f0d2f0: Resolve outgoing @name mentions on the Slack native streaming
path so streamed responses mention users consistently with the
post-and-edit fallback. Committed renderer text is resolved
incrementally, keeping fenced code literal and preserving the existing
ambiguity semantics.
- 4cc3445: Bound the length of bracketed URLs parsed from message text
in the link-unfurl fallback, avoiding a quadratic scan on adversarial
input. Valid links are unaffected.
- c311827: Preserve the Slack channel ID when converting labeled channel
tokens (`<#C123|general>` now becomes `#general (C123)`) so agents can
pass the ID to channel tools, and normalize the commonly hallucinated
`<label|url>` link order before Markdown conversion
- Updated dependencies [2a2b2c5]
- Updated dependencies [4ac0455]
- Updated dependencies [0ec6a73]
- Updated dependencies [85e3d22]
  - chat@4.37.0
  - @chat-adapter/shared@4.37.0
## @chat-adapter/whatsapp@4.37.0

### Minor Changes

- 6abf480: Add native WhatsApp LinkButton support

- A card whose only interactive element is a single `LinkButton` with a
non-empty label and an `http://` or `https://` URL is now sent as a
native `cta_url` interactive message, as long as the card has no header
image or image, table, chart, or inline link children and the post
carries no files or attachments.
- Link button URLs are now appended as `Label: url` lines to interactive
button message bodies and to media captions, instead of being dropped.
- Everything else is unchanged: non-matching cards keep the formatted
text fallback, and card + media posts keep the single captioned media
send.

- 16879fd: Fix the `WhatsAppInboundMessage.context` type to model all
documented webhook variants. The type previously declared `context?: {
from: string; id: string }`, but Meta's Cloud API sends mutually
exclusive context shapes: quoted replies carry `from`/`id`, forwarded
messages carry only `forwarded` or `frequently_forwarded` (no `id`), and
catalog product inquiries add `referred_product`. Code narrowed by the
old type could dereference `context.id` and crash at runtime on
forwarded messages. All context fields are now optional and the
forwarded/product-inquiry fields are included. Consumers that
dereference `context.from` or `context.id` without a guard will now see
a type error, surfacing what was already a latent crash on forwarded
messages.

### Patch Changes

- Updated dependencies [2a2b2c5]
- Updated dependencies [4ac0455]
- Updated dependencies [0ec6a73]
- Updated dependencies [85e3d22]
  - chat@4.37.0
  - @chat-adapter/shared@4.37.0
## chat@4.37.0

### Minor Changes

- 2a2b2c5: Add a native Instagram Direct Messages adapter with signed
webhooks, media, quick replies, story context, reactions, and typed Meta
API errors.
- 4ac0455: Add message update and delete lifecycle callbacks, with Slack
message_changed and message_deleted dispatch support.
- 0ec6a73: Add `@chat-adapter/notion` for Notion page and block comment
discussions: webhook HMAC verification, Post+Edit streaming,
conversation history, `message.subject` page metadata, plain-text
`@userName`/`@botUserId` mention detection, and File Uploads (up to 3
native attachments). Registers the adapter in the `chat/adapters`
catalog and `create-chat-sdk` CLI scaffold, and adds Notion emoji
platform support.
- 85e3d22: Close residual gaps in agent read-tool scoping.
`createChatTools`'s read guard now wraps modal, assistant-thread,
assistant-context, app-home, app-context, and member-joined dispatch so
tools built in those handlers inherit the active conversation, and it
logs a warning (instead of failing open silently) when a read runs with
no resolvable scope. Scoping stays channel-level by default, so a thread
scope still permits sibling threads in its channel. Pass the new
`strictScope: true` to confine a thread scope to that thread alone,
rejecting both sibling threads and the parent channel, which matters on
platforms where a channel is the widest read available (a GitHub channel
is an entire repo).

Note that reads inside those newly wrapped handlers were previously
unscoped. An agent built in an `onModalSubmit`, `onAppHomeOpened`, or
`onMemberJoinedChannel` handler that reads another channel will now be
rejected. Pass an explicit `scope`, or `scope: false` for intentionally
workspace-wide reads.
## create-chat-sdk@0.3.0

### Minor Changes

- 2a2b2c5: Add a native Instagram Direct Messages adapter with signed
webhooks, media, quick replies, story context, reactions, and typed Meta
API errors.
- 0ec6a73: Add `@chat-adapter/notion` for Notion page and block comment
discussions: webhook HMAC verification, Post+Edit streaming,
conversation history, `message.subject` page metadata, plain-text
`@userName`/`@botUserId` mention detection, and File Uploads (up to 3
native attachments). Registers the adapter in the `chat/adapters`
catalog and `create-chat-sdk` CLI scaffold, and adds Notion emoji
platform support.
## @chat-adapter/discord@4.37.0

### Patch Changes

- Updated dependencies [2a2b2c5]
- Updated dependencies [4ac0455]
- Updated dependencies [0ec6a73]
- Updated dependencies [85e3d22]
  - chat@4.37.0
  - @chat-adapter/shared@4.37.0
## @chat-adapter/github@4.37.0

### Patch Changes

- Updated dependencies [2a2b2c5]
- Updated dependencies [4ac0455]
- Updated dependencies [0ec6a73]
- Updated dependencies [85e3d22]
  - chat@4.37.0
  - @chat-adapter/shared@4.37.0
## @chat-adapter/linear@4.37.0

### Patch Changes

- Updated dependencies [2a2b2c5]
- Updated dependencies [4ac0455]
- Updated dependencies [0ec6a73]
- Updated dependencies [85e3d22]
  - chat@4.37.0
  - @chat-adapter/shared@4.37.0
## @chat-adapter/messenger@4.37.0

### Patch Changes

- Updated dependencies [2a2b2c5]
- Updated dependencies [4ac0455]
- Updated dependencies [0ec6a73]
- Updated dependencies [85e3d22]
  - chat@4.37.0
  - @chat-adapter/shared@4.37.0
## @chat-adapter/shared@4.37.0

### Patch Changes

- Updated dependencies [2a2b2c5]
- Updated dependencies [4ac0455]
- Updated dependencies [0ec6a73]
- Updated dependencies [85e3d22]
  - chat@4.37.0
## @chat-adapter/teams@4.37.0

### Patch Changes

- 4cc3445: Harden Teams HTML-to-text conversion to strip tags until the
output is stable, so nested or malformed markup can't leave a partial
tag behind. `stripHtmlTags` is now shared across the format and Graph
message converters.
- Updated dependencies [2a2b2c5]
- Updated dependencies [4ac0455]
- Updated dependencies [0ec6a73]
- Updated dependencies [85e3d22]
  - chat@4.37.0
  - @chat-adapter/shared@4.37.0
## @chat-adapter/telegram@4.37.0

### Patch Changes

- 629e655: Combine incoming Telegram media groups into one message with
ordered attachments and the shared caption.
- Updated dependencies [2a2b2c5]
- Updated dependencies [4ac0455]
- Updated dependencies [0ec6a73]
- Updated dependencies [85e3d22]
  - chat@4.37.0
  - @chat-adapter/shared@4.37.0
## @chat-adapter/twilio@4.37.0

### Patch Changes

- Updated dependencies [2a2b2c5]
- Updated dependencies [4ac0455]
- Updated dependencies [0ec6a73]
- Updated dependencies [85e3d22]
  - chat@4.37.0
  - @chat-adapter/shared@4.37.0
## @chat-adapter/web@4.37.0

### Patch Changes

- Updated dependencies [2a2b2c5]
- Updated dependencies [4ac0455]
- Updated dependencies [0ec6a73]
- Updated dependencies [85e3d22]
  - chat@4.37.0
  - @chat-adapter/shared@4.37.0
## @chat-adapter/x@4.37.0

### Patch Changes

- b674923: Restrict the X CRC challenge to the opaque token shape X
sends before signing it. The endpoint previously returned an HMAC over
any `crc_token`, which let a caller have an arbitrary webhook body
signed and replay that as `x-twitter-webhooks-signature` on a forged
POST. A webhook body is JSON and can no longer pass the token check, so
a CRC response can't double as a POST event signature.
- Updated dependencies [2a2b2c5]
- Updated dependencies [4ac0455]
- Updated dependencies [0ec6a73]
- Updated dependencies [85e3d22]
  - chat@4.37.0
  - @chat-adapter/shared@4.37.0
## @chat-adapter/state-ioredis@4.37.0

### Patch Changes

- Updated dependencies [2a2b2c5]
- Updated dependencies [4ac0455]
- Updated dependencies [0ec6a73]
- Updated dependencies [85e3d22]
  - chat@4.37.0
## @chat-adapter/state-memory@4.37.0

### Patch Changes

- Updated dependencies [2a2b2c5]
- Updated dependencies [4ac0455]
- Updated dependencies [0ec6a73]
- Updated dependencies [85e3d22]
  - chat@4.37.0
## @chat-adapter/state-pg@4.37.0

### Patch Changes

- Updated dependencies [2a2b2c5]
- Updated dependencies [4ac0455]
- Updated dependencies [0ec6a73]
- Updated dependencies [85e3d22]
  - chat@4.37.0
## @chat-adapter/state-redis@4.37.0

### Patch Changes

- Updated dependencies [2a2b2c5]
- Updated dependencies [4ac0455]
- Updated dependencies [0ec6a73]
- Updated dependencies [85e3d22]
  - chat@4.37.0
## @chat-adapter/tests@4.37.0

Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
2026-08-07 18:30:01 +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. Check Enable authentication and pick a service account. This is what signs the OIDC token on each push, and its email is the value you set as GOOGLE_CHAT_PUBSUB_SERVICE_ACCOUNT_EMAIL
  7. 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

Most options are auto-detected from environment variables when not provided. endpointUrl must be passed in config.

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
pubsubServiceAccountEmail No§ Service account your Pub/Sub push subscription authenticates as. Required to accept Pub/Sub pushes. Auto-detected from GOOGLE_CHAT_PUBSUB_SERVICE_ACCOUNT_EMAIL
googleChatProjectNumber No† GCP project number for direct webhook JWT verification when the Chat app's authentication audience is "Project number". Auto-detected from GOOGLE_CHAT_PROJECT_NUMBER
endpointUrl No† Public webhook URL for button click routing and direct webhook JWT verification when the Chat app's authentication audience is "HTTP endpoint URL". Must be passed in config
workspaceAddOnServiceAccountEmail No‡ Your own service-{projectNumber}@gcp-sa-gsuiteaddons.iam.gserviceaccount.com identity. Required to accept Workspace Add-on Chat app webhooks. Auto-detected from GOOGLE_CHAT_WORKSPACE_ADDON_SERVICE_ACCOUNT_EMAIL
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, endpointUrl, 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.

§Required alongside pubsubAudience. The audience is your public push endpoint, so anyone can have Google mint a validly signed token naming it from their own project. Only the email claim identifies the caller, which is why Google requires checking it in addition to aud. Without it, Pub/Sub pushes are rejected with HTTP 401 rather than trusted on their audience alone.

‡Only Workspace Add-on Chat apps need this. Their webhooks are signed by an add-on service identity rather than chat@system.gserviceaccount.com, and every add-on project shares the same service-{projectNumber}@gcp-sa-gsuiteaddons email shape — so the identity is only meaningful compared exactly. Without it, add-on tokens are rejected with HTTP 401 rather than trusted by shape. Standalone Chat apps are unaffected.

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 verifier or the explicit opt-out is required
GOOGLE_CHAT_PROJECT_NUMBER=123456789          # Direct webhooks with project-number audience
GOOGLE_CHAT_PUBSUB_AUDIENCE=https://your-domain.com/api/webhooks/gchat  # For Pub/Sub JWT verification
GOOGLE_CHAT_PUBSUB_SERVICE_ACCOUNT_EMAIL=pubsub@your-project.iam.gserviceaccount.com  # Push subscription identity
# Workspace Add-on Chat apps only — your own add-on service identity
GOOGLE_CHAT_WORKSPACE_ADDON_SERVICE_ACCOUNT_EMAIL=service-123456789@gcp-sa-gsuiteaddons.iam.gserviceaccount.com
# 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 when the Chat app's authentication audience is "Project number"
  • endpointUrl — direct webhooks when the Chat app's authentication audience is "HTTP endpoint URL"; also required for routing card button clicks in HTTP endpoint apps. Workspace Add-on Chat apps additionally need workspaceAddOnServiceAccountEmail, since their tokens are signed by an add-on identity instead of chat@system.gserviceaccount.com
  • pubsubAudience (or GOOGLE_CHAT_PUBSUB_AUDIENCE) — Pub/Sub push deliveries. Also set pubsubServiceAccountEmail (or GOOGLE_CHAT_PUBSUB_SERVICE_ACCOUNT_EMAIL) to the identity in your subscription's push auth settings, or pushes are rejected
  • 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 a direct-webhook verifier, 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 token with every webhook request. The expected JWT audience (aud claim) depends on the Chat app's Authentication audience setting:

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

Use googleChatProjectNumber when the setting is Project number. Find your project number in the GCP Console dashboard (it's different from the project ID).

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

Use endpointUrl when the setting is HTTP endpoint URL. Workspace Add-on Chat apps always use URL audience tokens. When both googleChatProjectNumber and endpointUrl are set, either token type is accepted.

The two modes carry different token types, and the adapter verifies each per Google's reference implementation: endpoint-URL tokens are standard Google OIDC ID tokens (checked against Google's public certs, plus the Chat service-account email claim with email_verified), while project-number tokens are JWTs self-signed by chat@system.gserviceaccount.com (checked against that service account's X.509 certificates with issuer chat@system.gserviceaccount.com). The configured endpointUrl must exactly match the URL registered in the Chat API console — a trailing-slash or scheme mismatch fails verification.

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