Skip to main content

Installation

npm install @chat-adapter/gchat

Environment Variables

Create a Google Chat app in the Google Cloud Console.
VariableRequiredDescription
GOOGLE_CHAT_CREDENTIALSService AccountJSON service account key (entire contents)
GOOGLE_CHAT_USE_ADCADC/Workload IdentitySet to true to use Application Default Credentials
GOOGLE_CHAT_PUBSUB_TOPICOptionalPub/Sub topic for Workspace Events (format: projects/my-project/topics/my-topic)
GOOGLE_CHAT_IMPERSONATE_USERDM creationUser email for domain-wide delegation

Configuration Options

interface GoogleChatAdapterConfig {
  /** Service account credentials JSON (use OR useApplicationDefaultCredentials) */
  credentials?: ServiceAccountCredentials;
  /** Use Application Default Credentials (ADC) */
  useApplicationDefaultCredentials?: boolean;
  /** Custom auth client (e.g., Vercel OIDC) */
  auth?: GoogleAuth;
  /** HTTP endpoint URL for button click actions */
  endpointUrl?: string;
  /** User email to impersonate (domain-wide delegation) */
  impersonateUser?: string;
  /** Logger instance */
  logger: Logger;
  /** Pub/Sub topic for receiving all messages */
  pubsubTopic?: string;
  /** Override bot username */
  userName?: string;
}

Setup

Use a JSON service account key:
import { Chat } from 'chat';
import { createGoogleChatAdapter } from '@chat-adapter/gchat';
import { MemoryState } from '@chat-adapter/state-memory';

const chat = new Chat({
  userName: 'my-bot',
  adapters: {
    gchat: createGoogleChatAdapter({
      credentials: JSON.parse(process.env.GOOGLE_CHAT_CREDENTIALS!),
      pubsubTopic: process.env.GOOGLE_CHAT_PUBSUB_TOPIC,
    }),
  },
  state: new MemoryState(),
});

await chat.initialize();

Webhook Handler

app.post('/webhooks/gchat', async (req, res) => {
  const response = await gchat.handleWebhook(req, {
    waitUntil: (promise) => {/* handle async work */},
  });
  res.status(response.status).send(await response.text());
});
Why Workspace Events? Direct webhooks only fire for @mentions. Workspace Events delivers ALL messages via Pub/Sub, enabling background processing and better UX.
1

Create Pub/Sub topic

gcloud pubsub topics create gchat-events \
  --project=my-project
2

Configure adapter

Set pubsubTopic in your adapter config:
pubsubTopic: 'projects/my-project/topics/gchat-events'
3

Enable domain-wide delegation

Required for creating subscriptions:
  1. Go to Google Workspace Admin Console
  2. Security → API Controls → Domain-wide Delegation
  3. Add your service account client ID
  4. Authorize scopes:
    • https://www.googleapis.com/auth/chat.bot
    • https://www.googleapis.com/auth/chat.messages.readonly
Set impersonateUser to a user email in your workspace:
impersonateUser: '[email protected]'
4

Create Pub/Sub push subscription

Point subscription to your webhook endpoint:
gcloud pubsub subscriptions create gchat-webhook \
  --topic=gchat-events \
  --push-endpoint=https://your-app.com/webhooks/gchat
5

Subscribe to threads

When bot joins a space or a thread is subscribed, the adapter auto-creates a Workspace Events subscription:
// Subscriptions are created automatically when:
await thread.subscribe(async (msg) => {
  // This triggers Workspace Events subscription creation
});

Features

Supported Events

  • MESSAGE - Messages in spaces (via direct webhook or Pub/Sub)
  • ADDED_TO_SPACE - Bot added to a space
  • REMOVED_FROM_SPACE - Bot removed from a space
  • CARD_CLICKED - Button clicks in cards
  • message.v1.created (Pub/Sub) - All messages via Workspace Events
  • reaction.v1.created / reaction.v1.deleted (Pub/Sub) - Reactions

Cards v2

Google Chat uses Cards v2 format:
import { Card, Section, Button } from 'chat/cards';

await thread.post(
  <Card title="Deployment Status">
    <Section text="Build #42 ready to deploy" />
    <Button actionId="deploy" style="primary">Deploy Now</Button>
    <Button actionId="cancel">Cancel</Button>
  </Card>
);
HTTP Endpoint Apps: Cards require endpointUrl config (auto-detected from webhook URL). Button clicks route via this URL.

Reactions

Add/remove emoji reactions:
await thread.addReaction(messageId, { name: 'thumbs_up' });
await thread.removeReaction(messageId, { name: 'thumbs_up' });
Supported emojis: Standard Unicode emoji (👍, ❤️, 🎉, etc.)

Ephemeral Messages

Send private messages visible only to one user:
await thread.postEphemeral(userId, 'This is only visible to you');

File Attachments

File uploads are not yet supported. Use external links or Google Drive attachments instead.

Thread IDs

Google Chat thread IDs encode space and thread names:
gchat:{spaceName}:{base64(threadName)}
Examples:
  • DM (no thread): gchat:spaces/AAAAxxxx:
  • Space thread: gchat:spaces/AAAAxxxx:dGhyZWFkcy95eXl5
For DMs, thread name is omitted to treat the entire DM as one subscription target.

Opening DMs

Create a 1:1 conversation with a user:
const dmThreadId = await gchat.openDM(userId);
await chat.getThread(dmThreadId).post('Hello!');
Requires domain-wide delegation with impersonateUser configured.

Message History

Fetch message history (requires domain-wide delegation):
const { messages, nextCursor } = await thread.fetchMessages({
  limit: 100,
  direction: 'backward',
});

Platform Limits

  • Message length: 4,096 characters
  • Cards per message: 100 cards
  • Widgets per card: 100 widgets
  • Rate limits: Google Chat quotas

Code Examples

chat.onNewMention(async (event) => {
  await event.thread.post(`Hi ${event.message.author.userName}!`);
});

Troubleshooting

  • Enable Workspace Events (Pub/Sub) to receive all messages
  • Without Pub/Sub, Google Chat only sends @mention events
  • Enable domain-wide delegation in Workspace Admin Console
  • Set impersonateUser to a user in your workspace
  • Grant service account https://www.googleapis.com/auth/chat.bot scope
  • Ensure Pub/Sub topic exists and is accessible
  • For HTTP Endpoint apps: ensure endpointUrl is configured
  • Verify webhook URL is publicly accessible (HTTPS required)
  • Check Google Cloud Console logs for errors
  • Requires domain-wide delegation with impersonateUser
  • Service account needs chat.spaces.create scope
  • User must be in same Workspace

Required Scopes

Add these OAuth scopes to your service account: Bot Scopes:
  • https://www.googleapis.com/auth/chat.bot - Core bot functionality
  • https://www.googleapis.com/auth/chat.messages.readonly - Read messages
  • https://www.googleapis.com/auth/chat.messages.reactions.create - Add reactions
  • https://www.googleapis.com/auth/chat.messages.reactions - Read/remove reactions
  • https://www.googleapis.com/auth/chat.spaces.create - Create DMs (with domain-wide delegation)
See Google Chat scopes for details.

Next Steps

Message Handling

Process messages and build conversation flows

Cards v2

Create interactive UIs with Google Chat cards

Workspace Events

Learn about Workspace Events API

State Management

Persist subscriptions and data