Google Chat Setup Guide
August 13, 2026 · View on GitHub
This guide walks you through connecting cc-connect to Google Chat, so you can chat with your local Claude Code from a Google Chat space or DM.
cc-connect uses a registered Google Chat app whose Cloud Pub/Sub connection publishes events to a topic. cc-connect pulls that topic locally (native Go, no extra binaries) and replies through the Chat REST API as the app's service account. This means:
- No public IP / domain / reverse proxy — events arrive over a Pub/Sub pull.
- No subscription expiry or per-restart resource leak — the Pub/Sub subscription is fixed (unlike the Workspace Events API, whose subscriptions expire and are recreated each run).
Prerequisites
- A Google Workspace account. The Google Chat API is only available to Workspace users; consumer
@gmail.comaccounts cannot configure a Chat app. (This applies to every Chat-app/REST integration, not just cc-connect.) - A Google Cloud project (billing enabled).
gcloudCLI installed and authenticated (for the one-time GCP setup below).- Claude Code installed and configured.
ℹ️ One Chat app per project. Google Cloud allows exactly one Chat app configuration per project. To run multiple Chat apps, use separate projects.
Architecture
┌──────────────────────────────────────────────────────────────┐
│ Google Chat │
│ │
│ Your message ─→ Chat app (Cloud Pub/Sub connection) │
│ │ │
│ ▼ │
│ Cloud Pub/Sub topic ──→ subscription │
└───────────────────────────────────────┼──────────────────────┘
│ streaming pull (no public IP)
▼
┌──────────────────────────────────────────────────────────────┐
│ Your Local Machine │
│ │
│ cc-connect ◄──► Claude Code CLI ◄──► Your Project Code │
│ │ │
│ └─ reply: Chat REST API as service account (chat.bot) │
└──────────────────────────────────────────────────────────────┘
Both directions are native Go and authenticate with the same service-account key (chat.bot scope):
- Receive: cc-connect opens a streaming pull on the subscription via the Cloud Pub/Sub client. The service account needs
roles/pubsub.subscriberon the subscription. - Send: cc-connect posts to the Chat REST API as the service account, so replies appear as the bot.
Step 1: Enable APIs
In your Google Cloud project, enable:
- Google Chat API (
chat.googleapis.com) - Cloud Pub/Sub API (
pubsub.googleapis.com)
gcloud services enable chat.googleapis.com pubsub.googleapis.com --project YOUR_PROJECT_ID
Step 2: Create the Pub/Sub topic and subscription
Create a topic, allow Google Chat to publish to it, and create a pull subscription that cc-connect will read.
PROJECT_ID=YOUR_PROJECT_ID
# Topic the Chat app publishes events to
gcloud pubsub topics create cc-connect-chat --project "$PROJECT_ID"
# Allow Google Chat's system service account to publish
gcloud pubsub topics add-iam-policy-binding cc-connect-chat --project "$PROJECT_ID" \
--member='serviceAccount:chat-api-push@system.gserviceaccount.com' \
--role='roles/pubsub.publisher'
# Pull subscription cc-connect reads
gcloud pubsub subscriptions create cc-connect-chat-sub --topic cc-connect-chat --project "$PROJECT_ID"
The subscription resource name is projects/YOUR_PROJECT_ID/subscriptions/cc-connect-chat-sub — you'll put this in config.toml.
Step 3: Create a service account
cc-connect uses one service account for both pulling events and replying.
gcloud iam service-accounts create cc-connect-bot --project "$PROJECT_ID" \
--display-name "cc-connect Chat bot"
# Allow the service account to pull from the subscription
gcloud pubsub subscriptions add-iam-policy-binding cc-connect-chat-sub --project "$PROJECT_ID" \
--member="serviceAccount:cc-connect-bot@${PROJECT_ID}.iam.gserviceaccount.com" \
--role="roles/pubsub.subscriber"
# Download a JSON key (this is a secret — store it safely, e.g. ~/.config/cc-connect/)
mkdir -p ~/.config/cc-connect
gcloud iam service-accounts keys create ~/.config/cc-connect/cc-connect-bot-key.json \
--iam-account="cc-connect-bot@${PROJECT_ID}.iam.gserviceaccount.com" \
--project "$PROJECT_ID"
chmod 600 ~/.config/cc-connect/cc-connect-bot-key.json
⚠️ The key file grants the bot's identity — keep it private and never commit it.
- Send: no project-level role is needed — a service account calling the Chat API with the
chat.botscope acts as the configured Chat app. - Receive: the
roles/pubsub.subscriberbinding above (on the subscription) is what lets the service account pull events.
Step 4: Configure the Chat app
Go to Chat API → Configuration (select your project) and set:
| Section | Setting |
|---|---|
| App status | Live — available to users (the app must be LIVE or it cannot send replies) |
| Build as a Workspace add-on | Unchecked (Cloud Pub/Sub connection requires the classic app model; do not convert to add-on — it's one-way) |
| Application info | App name (e.g. Claude), Avatar URL (HTTPS square image), Description |
| Interactive features | Enable |
| Functionality | ☑ Receive 1:1 messages (for DM use) and/or ☑ Join spaces and group conversations (for @mention in spaces) |
| Connection settings | Cloud Pub/Sub → topic projects/YOUR_PROJECT_ID/topics/cc-connect-chat |
| Visibility | Make available to specific people → enter your own email only (keeps the app private to you; up to 5 people or a group) |
Click Save.
Step 5: Configure cc-connect
Add a googlechat platform to your config.toml:
[[projects]]
name = "my-project"
[projects.agent]
type = "claudecode"
[projects.agent.options]
work_dir = "/path/to/your/project" # must be a real directory
mode = "default"
[[projects.platforms]]
type = "googlechat"
[projects.platforms.options]
# Pub/Sub subscription the Chat app publishes to (required)
subscription = "projects/YOUR_PROJECT_ID/subscriptions/cc-connect-chat-sub"
# Service-account key, used to pull events AND reply as the bot (chat.bot) (required)
credentials_file = "/Users/you/.config/cc-connect/cc-connect-bot-key.json"
# Allowed sender IDs (e.g. "users/1234567890"); "*" = everyone (default).
allow_from = "*"
# "space" (default) | "thread" | "user"
session_scope = "space"
Options reference
| Option | Required | Purpose |
|---|---|---|
subscription | ✅ | Pub/Sub subscription the Chat app publishes to |
credentials_file | ✅ | Service-account JSON key, used to pull events and reply (chat.bot) |
allow_from | — | Comma-separated allowed sender IDs; * = all |
session_scope | — | space (default) / thread / user |
Step 6: Start cc-connect
cc-connect
# or: cc-connect --config /path/to/config.toml
You should see:
level=INFO msg="googlechat: started" subscription=projects/.../cc-connect-chat-sub scope=space
Step 7: Start chatting
- DM: in Google Chat, search for your app name, open a DM, and send a message. Every message in the DM reaches the bot.
- Space: add the app to a space and @mention it (in spaces, a Chat app only receives messages that @mention it).
The bot replies in-thread as the app.
💡 Find your own sender ID for
allow_fromby running with[log] level = "debug"and sending a message — the log showssender=users/<id>. Then restrictallow_fromto that ID.
Key facts
- The Chat app must be Live. If App status is not Live, the app neither receives events nor sends replies. Set it to Live — available to users in the Chat API Configuration tab.
- One service account does both. The key in
credentials_filepulls events (needsroles/pubsub.subscriberon the subscription) and posts replies (chat.bot). - Fixed subscription = no expiry, no leak. Unlike the Workspace Events API, the Chat app's Pub/Sub connection uses one stable topic/subscription, so there is no subscription to renew and nothing is recreated on restart.
- One Chat app per Google Cloud project.
FAQ
Q: I sent a message but the bot doesn't respond at all.
- Is the Chat app App status = Live? (required for both receiving and sending)
- Is
cc-connectrunning? Check the log forgooglechat: started. - Does the service account have
roles/pubsub.subscriberon the subscription? (receive path) - Is
work_dira real directory? The agent can't start otherwise. - Give the agent a few seconds on the first message (cold start).
Q: It receives but never replies.
- Is
credentials_filereadable and a service-account key in the same project? - Check logs for
googlechat: send: status ....
Q: "Google Chat app is inactive" error when sending.
Set App status to Live — available to users in the Chat API Configuration tab.
Q: "Google Chat API is only available to Google Workspace users."
You're signed in with a consumer account. Use a Google Workspace account.
Q: Connection settings has no "Cloud Pub/Sub" option.
The "Build this Chat app as a Google Workspace add-on" checkbox is on. Cloud Pub/Sub is available in the classic model — clear that checkbox (or keep the add-on model, which also supports Pub/Sub but is configured differently).
References
- Configure the Google Chat API
- Build a Google Chat app behind a firewall with Pub/Sub
- Authenticate as a Chat app (service account)