google-chat-api
from jezweb/claude-skills
Skills for Claude Code CLI such as full stack dev Cloudflare, React, Tailwind v4, and AI integrations.
npx skills add https://github.com/jezweb/claude-skills --skill google-chat-apiSKILL.md
Google Chat API
Status: Production Ready Last Updated: 2026-01-09 (Added: Spaces API, Members API, Reactions API, Rate Limits) Dependencies: Cloudflare Workers (recommended), Web Crypto API for token verification Latest Versions: Google Chat API v1 (stable), Cards v2 (Cards v1 deprecated), wrangler@4.54.0
Quick Start (5 Minutes)
1. Create Webhook (Simplest Approach)
# No code needed - just configure in Google Chat
# 1. Go to Google Cloud Console
# 2. Create new project or select existing
# 3. Enable Google Chat API
# 4. Configure Chat app with webhook URL
Webhook URL: https://your-worker.workers.dev/webhook
Why this matters:
- Simplest way to send messages to Chat
- No authentication required for incoming webhooks
- Perfect for notifications from external systems
- Limited to sending messages (no interactive responses)
2. Create Interactive Bot (Cloudflare Worker)
export default {
async fetch(request: Request, env: Env): Promise<Response> {
const event = await request.json()
// Respond with a card
return Response.json({
text: "Hello from bot!",
cardsV2: [{
cardId: "unique-card-1",
card: {
header: { title: "Welcome" },
sections: [{
widgets: [{
textParagraph: { text: "Click the button below" }
}, {
buttonList: {
buttons: [{
text: "Click me",
onClick: {
action: {
function: "handleClick",
parameters: [{ key: "data", value: "test" }]
}
}
}]
}
}]
}]
}
}]
})
}
}
CRITICAL:
- Must respond within timeout (typically 30 seconds)
- Always return valid JSON with
cardsV2array - Card schema must be exact - one wrong field breaks the whole card
3. Verify Bearer Tokens (Production Security)
async function verifyToken(token: string): Promise<boolean> {
// Verify token is signed by chat@system.gserviceaccount.com
// See templates/bearer-token-verify.ts for full implementation
return true
}
Why this matters:
- Prevents unauthorized access to your bot
- Required for HTTP endpoints (not webhooks)
- Uses Web Crypto API (Cloudflare Workers compatible)
The 3-Step Setup Process
Step 1: Choose Integration Type
Option A: Incoming Webhook (Notifications Only)
Best for:
- CI/CD notifications
- Alert systems
- One-way communication
- External service → Chat
Setup:
- Create Chat space
- Configure incoming webhook in Space settings
- POST JSON to webhook URL
No code required - just HTTP POST:
curl -X POST 'https://chat.googleapis.com/v1/spaces/.../messages?key=...' \
-H 'Content-Type: application/json' \
-d '{"text": "Hello from webhook!"}'
Option B: HTTP Endpoint Bot (Interactive)
Best for:
- Interactive forms
- Button-based workflows
- User input collection
- Chat → Your service → Chat
Setup:
- Create Google Cloud project
- Enable Chat API
- Configure Chat app with HTTP endpoint
- Deploy Cloudflare Worker
- Handle events and respond with cards
Requires code - see templates/interactive-bot.ts
Step 2: Design Cards (If Using Interactive Bot)
IMPORTANT: Use Cards v2 only. Cards v1 was deprecated in 2025. Cards v2 matches Material Design on web (faster rendering, better aesthetics).
Cards v2 structure:
{
"cardsV2": [{
"cardId": "unique-id",
"card": {
"header": {
"title": "Card Title",
"subtitle": "Optional subtitle",
"imageUrl": "https://..."
},
"sections": [{
"header": "Section 1",
"widgets": [
{ "textParagraph": { "text": "Some text" } },
{ "buttonList": { "buttons": [...] } }
]
}]
}
}]
}
Widget Types:
textParagraph- Text contentbuttonList- Buttons (text or icon)textInput- Text input fieldselectionInput- Dropdowns, checkboxes, switchesdateTimePicker- Date/time selectiondivider- Horizontal lineimage- ImagesdecoratedText- Text with icon/button
Text Formatting (NEW: Sept 2025 - GA):
Cards v2 supports both HTML and Markdown formatting:
// HTML formatting (traditional)
{
textParagraph: {
text: "This is <b>bold</b> and <i>italic</i> text with <font color='#ea9999'>color</font>"
}
}
// Markdown formatting (NEW - better for AI agents)
{
textParagraph: {
text: "This is **bold** and *italic* text\n\n- Bullet list\n- Second item\n\n```\ncode block\n```"
}
}
Supported Markdown (text messages and cards):
**bold**or*italic*`code`for inline code- list itemor1. orderedfor lists```code block```for multi-line code~strikethrough~
Supported HTML (card
...