google-chat-api

安装量: 317
排名: #2907

安装

npx skills add https://github.com/jezweb/claude-skills --skill google-chat-api

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 { 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 cardsV2 array Card schema must be exact - one wrong field breaks the whole card 3. Verify Bearer Tokens (Production Security) async function verifyToken(token: string): Promise { // 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 content buttonList - Buttons (text or icon) textInput - Text input field selectionInput - Dropdowns, checkboxes, switches dateTimePicker - Date/time selection divider - Horizontal line image - Images decoratedText - 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 bold and italic text with color" } }

// 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 item or 1. ordered for lists code block for multi-line code ~strikethrough~

Supported HTML (cards only):

bold, italic, underline colored link

Why Markdown matters: LLMs naturally output Markdown. Before Sept 2025, you had to convert Markdown→HTML. Now you can pass Markdown directly to Chat.

CRITICAL:

Max 100 widgets per card - silently truncated if exceeded Widget order matters - displayed top to bottom cardId must be unique - use timestamp or UUID Step 3: Handle User Interactions

When user clicks button or submits form:

export default { async fetch(request: Request): Promise { const event = await request.json()

// Check event type
if (event.type === 'MESSAGE') {
  // User sent message
  return handleMessage(event)
}

if (event.type === 'CARD_CLICKED') {
  // User clicked button
  const action = event.action.actionMethodName
  const params = event.action.parameters

  if (action === 'submitForm') {
    return handleFormSubmission(event)
  }
}

return Response.json({ text: "Unknown event" })

} }

Event Types:

ADDED_TO_SPACE - Bot added to space REMOVED_FROM_SPACE - Bot removed MESSAGE - User sent message CARD_CLICKED - User clicked button/submitted form Critical Rules Always Do

✅ Return valid JSON with cardsV2 array structure ✅ Set unique cardId for each card ✅ Verify bearer tokens for HTTP endpoints (production) ✅ Handle all event types (MESSAGE, CARD_CLICKED, etc.) ✅ Keep widget count under 100 per card ✅ Validate form inputs server-side

Never Do

❌ Store secrets in code (use Cloudflare Workers secrets) ❌ Exceed 100 widgets per card (silently fails) ❌ Return malformed JSON (breaks entire message) ❌ Skip bearer token verification (security risk) ❌ Trust client-side validation only (validate server-side) ❌ Use synchronous blocking operations (timeout risk)

Known Issues Prevention

This skill prevents 6 documented issues:

Issue #1: Bearer Token Verification Fails (401)

Error: "Unauthorized" or "Invalid credentials" Source: Google Chat API Documentation Why It Happens: Token not verified or wrong verification method Prevention: Template includes Web Crypto API verification (Cloudflare Workers compatible)

Issue #2: Invalid Card JSON Schema (400)

Error: "Invalid JSON payload" or "Unknown field" Source: Cards v2 API Reference Why It Happens: Typo in field name, wrong nesting, or extra fields Prevention: Use google-chat-cards library or templates with exact schema

Issue #3: Widget Limit Exceeded (Silent Failure)

Error: No error - widgets beyond 100 simply don't render Source: Google Chat API Limits Why It Happens: Adding too many widgets to single card Prevention: Skill documents 100 widget limit + pagination patterns

Issue #4: Form Validation Error Format Wrong

Error: Form doesn't show validation errors to user Source: Interactive Cards Documentation Why It Happens: Wrong error response format Prevention: Templates include correct error format:

{ "actionResponse": { "type": "DIALOG", "dialogAction": { "actionStatus": { "statusCode": "INVALID_ARGUMENT", "userFacingMessage": "Email is required" } } } }

Issue #5: Webhook "Unable to Connect" Error

Error: Chat shows "Unable to connect to bot" Source: Webhook Setup Guide Why It Happens: URL not publicly accessible, timeout, or wrong response format Prevention: Skill includes timeout handling + response format validation

Issue #6: Rate Limit Exceeded (429)

Error: "RESOURCE_EXHAUSTED" or 429 status code Source: Google Chat API Quotas Why It Happens: Exceeding per-project, per-space, or per-user request limits Prevention: Skill documents rate limits + exponential backoff pattern

Configuration Files Reference Cloudflare Worker (wrangler.jsonc) { "name": "google-chat-bot", "main": "src/index.ts", "compatibility_date": "2026-01-03", "compatibility_flags": ["nodejs_compat"],

// Secrets (set with: wrangler secret put CHAT_BOT_TOKEN) "vars": { "ALLOWED_SPACES": "spaces/SPACE_ID_1,spaces/SPACE_ID_2" } }

Why these settings:

nodejs_compat - Required for Web Crypto API (token verification) Secrets stored securely (not in code) Environment variables for configuration Common Patterns Pattern 1: Notification Bot (Webhook) // External service sends notification to Chat async function sendNotification(webhookUrl: string, message: string) { await fetch(webhookUrl, { method: 'POST', headers: { 'Content-Type': 'application/json' }, body: JSON.stringify({ text: message, cardsV2: [{ cardId: notif-${Date.now()}, card: { header: { title: "Alert" }, sections: [{ widgets: [{ textParagraph: { text: message } }] }] } }] }) }) }

When to use: CI/CD alerts, monitoring notifications, event triggers

Pattern 2: Interactive Form // Show form to collect data function showForm() { return { cardsV2: [{ cardId: "form-card", card: { header: { title: "Enter Details" }, sections: [{ widgets: [ { textInput: { name: "email", label: "Email", type: "SINGLE_LINE", hintText: "user@example.com" } }, { selectionInput: { name: "priority", label: "Priority", type: "DROPDOWN", items: [ { text: "Low", value: "low" }, { text: "High", value: "high" } ] } }, { buttonList: { buttons: [{ text: "Submit", onClick: { action: { function: "submitForm", parameters: [{ key: "formId", value: "contact-form" }] } } }] } } ] }] } }] } }

When to use: Data collection, approval workflows, ticket creation

Pattern 3: Dialog (Modal) // Open modal dialog function openDialog() { return { actionResponse: { type: "DIALOG", dialogAction: { dialog: { body: { sections: [{ header: "Confirm Action", widgets: [{ textParagraph: { text: "Are you sure?" } }, { buttonList: { buttons: [ { text: "Confirm", onClick: { action: { function: "confirm" } } }, { text: "Cancel", onClick: { action: { function: "cancel" } } } ] } }] }] } } } } } }

When to use: Confirmations, multi-step workflows, focused data entry

Using Bundled Resources Scripts (scripts/)

No executable scripts for this skill.

Templates (templates/)

Required for all projects:

templates/webhook-handler.ts - Basic webhook receiver templates/wrangler.jsonc - Cloudflare Workers config

Optional based on needs:

templates/interactive-bot.ts - HTTP endpoint with event handling templates/card-builder-examples.ts - Common card patterns templates/form-validation.ts - Input validation with error responses templates/bearer-token-verify.ts - Token verification utility

When to load these: Claude should reference templates when user asks to:

Set up Google Chat bot Create interactive cards Add form validation Verify bearer tokens Handle button clicks References (references/) references/google-chat-docs.md - Key documentation links references/cards-v2-schema.md - Complete card structure reference references/common-errors.md - Error troubleshooting guide

When Claude should load these: Troubleshooting errors, designing cards, understanding API

Advanced Topics Slash Commands

Register slash commands for quick actions:

// User types: /create-ticket Bug in login if (event.message?.slashCommand?.commandName === 'create-ticket') { const text = event.message.argumentText

return Response.json({ text: Creating ticket: ${text}, cardsV2: [/ ticket confirmation card /] }) }

Use cases: Quick actions, shortcuts, power user features

Thread Replies

Reply in existing thread:

return Response.json({ text: "Reply in thread", thread: { name: event.message.thread.name // Use existing thread } })

Use cases: Conversations, follow-ups, grouped discussions

Spaces API

Programmatically manage Google Chat spaces (rooms). Requires Chat Admin or App permissions.

Available Methods Method Description Scope Required spaces.create Create new space chat.spaces.create spaces.delete Delete a space chat.delete spaces.get Get space details chat.spaces.readonly spaces.list List spaces bot is in chat.spaces.readonly spaces.patch Update space settings chat.spaces spaces.search Search spaces by criteria chat.spaces.readonly spaces.setup Create space and add members chat.spaces.create spaces.findDirectMessage Find DM with specific user chat.spaces.readonly Create a Space async function createSpace(accessToken: string) { const response = await fetch('https://chat.googleapis.com/v1/spaces', { method: 'POST', headers: { 'Authorization': Bearer ${accessToken}, 'Content-Type': 'application/json' }, body: JSON.stringify({ spaceType: 'SPACE', // or 'GROUP_CHAT', 'DIRECT_MESSAGE' displayName: 'Project Team', singleUserBotDm: false, spaceDetails: { description: 'Team collaboration space', guidelines: 'Be respectful and on-topic' } }) }) return response.json() }

List Spaces (Bot's Accessible Spaces) async function listSpaces(accessToken: string) { const response = await fetch( 'https://chat.googleapis.com/v1/spaces?pageSize=100', { headers: { 'Authorization': Bearer ${accessToken} } } ) const data = await response.json() // Returns: { spaces: [...], nextPageToken: '...' } return data.spaces }

Search Spaces async function searchSpaces(accessToken: string, query: string) { const params = new URLSearchParams({ query: query, // e.g., 'displayName:Project' pageSize: '50' }) const response = await fetch( https://chat.googleapis.com/v1/spaces:search?${params}, { headers: { 'Authorization': Bearer ${accessToken} } } ) return response.json() }

Search Query Syntax:

displayName:Project - Name contains "Project" spaceType:SPACE - Only spaces (not DMs) createTime>2025-01-01 - Created after date Combine with AND/OR operators Members API

Manage space membership programmatically. Requires User or App authorization.

Available Methods Method Description Scope Required spaces.members.create Add member to space chat.memberships spaces.members.delete Remove member chat.memberships spaces.members.get Get member details chat.memberships.readonly spaces.members.list List all members chat.memberships.readonly spaces.members.patch Update member role chat.memberships Add Member to Space async function addMember(accessToken: string, spaceName: string, userEmail: string) { const response = await fetch( https://chat.googleapis.com/v1/${spaceName}/members, { method: 'POST', headers: { 'Authorization': Bearer ${accessToken}, 'Content-Type': 'application/json' }, body: JSON.stringify({ member: { name: users/${userEmail}, type: 'HUMAN' // or 'BOT' }, role: 'ROLE_MEMBER' // or 'ROLE_MANAGER' }) } ) return response.json() }

List Space Members async function listMembers(accessToken: string, spaceName: string) { const response = await fetch( https://chat.googleapis.com/v1/${spaceName}/members?pageSize=100, { headers: { 'Authorization': Bearer ${accessToken} } } ) return response.json() // Returns: { memberships: [...], nextPageToken: '...' } }

Update Member Role async function updateMemberRole( accessToken: string, memberName: string, // e.g., 'spaces/ABC/members/DEF' newRole: 'ROLE_MEMBER' | 'ROLE_MANAGER' ) { const response = await fetch( https://chat.googleapis.com/v1/${memberName}?updateMask=role, { method: 'PATCH', headers: { 'Authorization': Bearer ${accessToken}, 'Content-Type': 'application/json' }, body: JSON.stringify({ role: newRole }) } ) return response.json() }

Member Roles:

ROLE_MEMBER - Standard member (read/write messages) ROLE_MANAGER - Can manage space settings and members Reactions API

Add emoji reactions to messages. Added in 2025, supports custom workspace emojis.

Available Methods Method Description spaces.messages.reactions.create Add reaction to message spaces.messages.reactions.delete Remove reaction spaces.messages.reactions.list List reactions on message Add Reaction async function addReaction( accessToken: string, messageName: string, // e.g., 'spaces/ABC/messages/XYZ' emoji: string ) { const response = await fetch( https://chat.googleapis.com/v1/${messageName}/reactions, { method: 'POST', headers: { 'Authorization': Bearer ${accessToken}, 'Content-Type': 'application/json' }, body: JSON.stringify({ emoji: { unicode: emoji // e.g., '👍' or custom emoji code } }) } ) return response.json() }

List Reactions async function listReactions(accessToken: string, messageName: string) { const response = await fetch( https://chat.googleapis.com/v1/${messageName}/reactions?pageSize=100, { headers: { 'Authorization': Bearer ${accessToken} } } ) return response.json() // Returns: { reactions: [...], nextPageToken: '...' } }

Custom Emoji: Workspace administrators can upload custom emoji. Use the emoji's customEmoji.uid instead of unicode.

Rate Limits

Google Chat API enforces strict quotas to prevent abuse. Understanding these limits is critical for production apps.

Per-Project Quotas (Per Minute) Operation Limit Notes Read operations 3,000/min spaces.get, members.list, messages.list Membership writes 300/min members.create, members.delete Space writes 60/min spaces.create, spaces.patch Message operations 600/min messages.create, reactions.create Reactions 600/min Shared with message operations Per-Space Quotas (Per Second) Operation Limit Read operations 15/sec Write operations 1/sec Per-User Quotas

User-authenticated requests are also throttled per user:

60 requests/minute per user for most operations 10 requests/minute for space creation Handling Rate Limit Errors async function withRetry( fn: () => Promise, maxRetries = 3 ): Promise { for (let i = 0; i < maxRetries; i++) { try { return await fn() } catch (error: any) { if (error.status === 429) { // Rate limited - wait with exponential backoff const waitMs = Math.pow(2, i) * 1000 + Math.random() * 1000 await new Promise(r => setTimeout(r, waitMs)) continue } throw error } } throw new Error('Max retries exceeded') }

// Usage const spaces = await withRetry(() => listSpaces(accessToken))

Best Practices:

Cache read operations where possible Batch membership operations Use pagination efficiently (request larger pages, fewer requests) Implement exponential backoff for 429 errors Monitor quota usage in Google Cloud Console Dependencies

Required:

Cloudflare Workers account (free tier works) Google Cloud Project with Chat API enabled Public HTTPS endpoint (Workers provides this)

Optional:

google-chat-cards@1.0.3 - Type-safe card builder (unofficial) Web Crypto API (built into Cloudflare Workers) Official Documentation Google Chat API: https://developers.google.com/workspace/chat Cards v2 Reference: https://developers.google.com/workspace/chat/api/reference/rest/v1/cards Webhooks Guide: https://developers.google.com/workspace/chat/quickstart/webhooks Interactive Cards: https://developers.google.com/workspace/chat/dialogs Cloudflare Workers: https://developers.cloudflare.com/workers Package Versions (Verified 2026-01-09) { "dependencies": { "google-chat-cards": "^1.0.3" }, "devDependencies": { "@cloudflare/workers-types": "^4.20260109.0", "wrangler": "^4.58.0" } }

Note: No official Google Chat npm package - use fetch API directly.

Production Example

This skill is based on real-world implementations:

Community Examples: translatebot (Worker + Chat + Translate API) Official Samples: Multiple working examples in Google's documentation

Token Savings: ~65-70% (8k → 2.5k tokens) Errors Prevented: 6/6 documented issues Validation: ✅ Webhook handlers, ✅ Card builders, ✅ Token verification, ✅ Form validation, ✅ Rate limit handling

Troubleshooting Problem: "Unauthorized" (401) error

Solution: Implement bearer token verification (see templates/bearer-token-verify.ts)

Problem: Cards don't render / "Invalid JSON payload"

Solution: Validate card JSON against Cards v2 schema, ensure exact field names

Problem: Widgets beyond first 100 don't show

Solution: Split into multiple cards or use pagination

Problem: Form validation errors not showing to user

Solution: Return correct error format with actionResponse.dialogAction.actionStatus

Problem: "Unable to connect to bot"

Solution: Ensure URL is publicly accessible, responds within timeout, returns valid JSON

Complete Setup Checklist

Use this checklist to verify your setup:

Google Cloud project created Chat API enabled in project Chat app configured with webhook/HTTP endpoint URL Cloudflare Worker deployed and accessible Bearer token verification implemented (if using HTTP endpoint) Card JSON validated against schema Widget count under 100 per card Form validation returns correct error format Tested in Chat space successfully Error handling for all event types

Questions? Issues?

Check references/common-errors.md for troubleshooting Verify card JSON structure matches Cards v2 schema Check official docs: https://developers.google.com/workspace/chat Ensure bearer token verification is implemented for HTTP endpoints

返回排行榜