claude-channel-google-chat
v0.2.0
Published
Claude Code Channel plugin for Google Chat - bridges Google Chat to persistent Claude Code CLI sessions with multi-session routing
Maintainers
Readme
Claude Channel for Google Chat
A Claude Code Channel plugin that bridges Google Chat to persistent Claude Code CLI sessions. One bot, multiple machines, multiple spaces -- each routed to the right session automatically.
How It Works
Google Chat Space
↓
Pub/Sub Topic (shared)
↓
Cloud Function (router)
↓
Firestore lookup: space → session
↓
Per-Session Pub/Sub Topic
↓
Claude Code (on your machine)
↓
Reply via Chat API
↓
Google Chat SpaceNo public endpoints needed -- all connections are outbound from your machine.
Features
- Multi-session routing -- different Google Chat spaces connect to different Claude Code sessions
- Auto-session identity -- each session gets a unique ID from hostname + working directory (zero config)
- Auto-subscription -- Pub/Sub topics and subscriptions created automatically on startup
- Cloud Function router -- central routing via Firestore, offline detection
- Message durability -- messages queue during offline periods (7-day Pub/Sub retention)
- Access control -- sender-based allowlist with pairing flow
- Permission relay -- approve/deny Claude's tool calls from Google Chat
- Threading -- replies maintain thread context
- Markdown conversion -- Claude's Markdown renders correctly in Google Chat
Prerequisites
- Claude Code v2.1.80+ with claude.ai login
- Bun runtime
Employee Quick Start
If your admin has already set up the GCP infrastructure, you only need 3 steps:
1. Get the service account key from your admin and place it:
mkdir -p ~/.claude/channels/google-chat
mv ~/Downloads/service-account.json ~/.claude/channels/google-chat/
chmod 600 ~/.claude/channels/google-chat/service-account.json2. Create .mcp.json in your project directory:
cat > .mcp.json << 'EOF'
{
"mcpServers": {
"google-chat": {
"command": "bunx",
"args": ["claude-channel-google-chat"],
"env": {
"GOOGLE_CHAT_USER_CWD": "${PWD}",
"GOOGLE_CHAT_PROJECT_ID": "claude-channel-gchat",
"GOOGLE_CHAT_ROUTING_MODE": "cloud-function"
}
}
}
}
EOF3. Start Claude Code:
claude --dangerously-load-development-channels server:google-chatThat's it. No git clone, no install. To connect a Google Chat space, add the bot and run claim space spaces/AAAA in Claude Code.
Admin Setup
The following sections are for admins who need to set up the GCP infrastructure (one-time).
Prerequisites
- gcloud CLI installed and authenticated
- Google Cloud project with billing enabled (free tier is sufficient)
Step 1: Clone this repository
git clone https://github.com/techdivision-rnd/claude-channel-google-chat.git
cd claude-channel-google-chatStep 2: GCP Infrastructure (one-time)
Set your project ID and run all commands:
PROJECT_ID=your-project-id # ← replace this
gcloud config set project $PROJECT_ID
# Enable required APIs
gcloud services enable \
chat.googleapis.com \
pubsub.googleapis.com \
cloudfunctions.googleapis.com \
cloudbuild.googleapis.com \
firestore.googleapis.com \
run.googleapis.com \
eventarc.googleapis.com \
artifactregistry.googleapis.com
# Create Pub/Sub topic for Google Chat events
gcloud pubsub topics create claude-channel-chat
# Allow Google Chat to publish to the topic
gcloud pubsub topics add-iam-policy-binding claude-channel-chat \
--member="serviceAccount:[email protected]" \
--role="roles/pubsub.publisher"
# Create service account for Claude Code sessions
gcloud iam service-accounts create claude-channel-sa \
--display-name="Claude Channel for Google Chat"
gcloud projects add-iam-policy-binding $PROJECT_ID \
--member="serviceAccount:claude-channel-sa@$PROJECT_ID.iam.gserviceaccount.com" \
--role="roles/pubsub.editor"
gcloud projects add-iam-policy-binding $PROJECT_ID \
--member="serviceAccount:claude-channel-sa@$PROJECT_ID.iam.gserviceaccount.com" \
--role="roles/datastore.user"
# Download service account key
gcloud iam service-accounts keys create credentials.json \
--iam-account=claude-channel-sa@$PROJECT_ID.iam.gserviceaccount.com
# Create Firestore database
gcloud firestore databases create --location=eur3
# Create dedicated Cloud Function service account
gcloud iam service-accounts create claude-channel-fn \
--display-name="Claude Channel Router"
gcloud projects add-iam-policy-binding $PROJECT_ID \
--member="serviceAccount:claude-channel-fn@$PROJECT_ID.iam.gserviceaccount.com" \
--role="roles/datastore.user"
gcloud projects add-iam-policy-binding $PROJECT_ID \
--member="serviceAccount:claude-channel-fn@$PROJECT_ID.iam.gserviceaccount.com" \
--role="roles/pubsub.publisher"Step 3: Deploy Cloud Function (one-time)
# Deploy the router
gcloud functions deploy claude-channel-router \
--gen2 --runtime=nodejs22 --region=europe-west1 \
--source=./cloud-function --entry-point=routeMessage \
--trigger-topic=claude-channel-chat \
--memory=256Mi --timeout=30s \
--ingress-settings=internal-only \
--service-account=claude-channel-fn@$PROJECT_ID.iam.gserviceaccount.com
# Grant the function SA permission to invoke Cloud Run
gcloud run services add-iam-policy-binding claude-channel-router \
--region=europe-west1 \
--member="serviceAccount:claude-channel-fn@$PROJECT_ID.iam.gserviceaccount.com" \
--role="roles/run.invoker"Step 4: Configure Google Chat App (one-time)
- Go to Google Cloud Console > APIs & Services > Google Chat API > Configuration
- Do NOT check "Build this Chat app as a Google Workspace add-on" (this is irreversible!)
- Enter app name (e.g., "Claude"), avatar URL, and description
- Check "Join spaces and group conversations" and "Receive 1:1 messages"
- Connection settings: select Cloud Pub/Sub
- Topic name:
projects/YOUR_PROJECT_ID/topics/claude-channel-chat - Set visibility to your users or domain
- Set App status to LIVE (commonly missed -- the bot won't appear without this!)
Step 5: Set Up a Machine (one-time per machine)
# Install the plugin
git clone https://github.com/techdivision-rnd/claude-channel-google-chat.git \
"$HOME/.claude-channel-google-chat"
cd "$HOME/.claude-channel-google-chat" && bun install
# Copy credentials
mkdir -p "$HOME/.claude/channels/google-chat"
cp /path/to/credentials.json "$HOME/.claude/channels/google-chat/service-account.json"
chmod 600 "$HOME/.claude/channels/google-chat/service-account.json"
# Create shared config
cat > "$HOME/.claude/channels/google-chat/.env" << 'EOF'
GOOGLE_CHAT_PROJECT_ID=your-project-id
GOOGLE_CHAT_ROUTING_MODE=cloud-function
EOF
chmod 600 "$HOME/.claude/channels/google-chat/.env"Step 6: Start a Claude Code Session
In your project directory, create a .mcp.json (one-time per project) and start:
# Create .mcp.json (one-time)
cat > .mcp.json << EOF
{"mcpServers":{"google-chat":{"command":"bun","args":["run","--cwd","$HOME/.claude-channel-google-chat","--shell=bun","--silent","start"],"env":{"GOOGLE_CHAT_USER_CWD":"\${PWD}"}}}}
EOF
# Start Claude Code with the channel
claude --dangerously-load-development-channels server:google-chatStep 7: Connect a Google Chat Space
- In Google Chat: create a space (or open an existing one) and add the Claude bot
- The bot posts:
To connect, run: claim space spaces/AAAA - In your Claude Code session, type:
claim space spaces/AAAA(use the ID from the message) - The bot confirms in Google Chat:
Connected! @mention me to interact. - Team members can now
@Claudein that space
Multi-Session Routing
Open multiple Claude Code sessions in different directories -- each automatically gets a unique identity and can claim different spaces.
~/projects/website → Session "macbook-website-a3f2" → Space "Dev - Website"
~/projects/api → Session "macbook-api-b7c1" → Space "Dev - API"
~/sales/kundex → Session "macbook-kundex-d4e9" → Space "Sales - KundeX"Session identity is generated from hostname-dirname-hash(cwd) -- deterministic and stable across restarts. Each session auto-creates its own Pub/Sub topic and subscription. The Cloud Function routes messages to the correct session via the Firestore routing table.
When a session goes offline, Pub/Sub queues messages for up to 7 days. They are delivered automatically when the session restarts.
Managing Spaces
In any Claude Code session, tell Claude:
| Command | Description |
|---------|-------------|
| claim space spaces/AAAA | Connect a Google Chat space to this session |
| release space spaces/AAAA | Disconnect a space from this session |
| list spaces | Show session name, claimed spaces, and status |
Configuration Reference
Shared config at ~/.claude/channels/google-chat/.env:
| Variable | Required | Default | Description |
|----------|----------|---------|-------------|
| GOOGLE_CHAT_PROJECT_ID | Yes | -- | Your GCP project ID |
| GOOGLE_CHAT_ROUTING_MODE | Yes | local | Set to cloud-function |
| GOOGLE_CHAT_SESSION_NAME | No | auto | Override auto-generated session name |
| GOOGLE_CHAT_HANDLE_DMS | No | true | Handle DM pairing (set false on secondary sessions) |
| GOOGLE_CHAT_TOPIC_NAME | No | claude-channel-chat | Shared Pub/Sub topic name |
| GOOGLE_CHAT_SERVICE_ACCOUNT_KEY | No | ~/.claude/channels/google-chat/service-account.json | Path to service account key |
File layout:
~/.claude/channels/google-chat/
.env # Shared config (all sessions)
service-account.json # Shared credentials
sessions/
macbook-website-a3f2/ # Per-session state (auto-created)
access.json # Claimed spaces, allowlistArchitecture
Google Chat → Pub/Sub Topic (shared)
|
Cloud Function (router)
|
Firestore (space → session mapping)
|
+---------+---------+
| | |
Per-session Per-session Per-session
Pub/Sub topic Pub/Sub topic Pub/Sub topic
| | |
Session A Session B Session C- Cloud Function receives all messages from the shared topic, looks up the space-to-session mapping in Firestore, and publishes to the correct per-session topic
- Sessions pull from their per-session topic via REST long-poll (Bun-compatible, ~0ms latency when messages arrive)
- Firestore stores session registrations (
sessions/), space claims (spaces/), and DM routing config (config/global) - All infrastructure costs are within GCP free tier for typical usage
Known Limitations
- Claude Code Channels is a research preview (v2.1.80+)
- Must use
server:mode with.mcp.jsonper project directory (plugin:mode has a known bug) - Requires claude.ai login (API keys not supported for channels)
License
Apache-2.0
