← Back to Plugins
Tools

Googlechatpubsub

teyou By teyou ⭐ 2 stars 👁 14 views ▲ 0 votes

Openclaw plugin - Chat to your bot in google chat space without @mention

Homepage GitHub

Install

openclaw plugins install @teyou/openclaw-googlechatpubsub

Configuration Example

{
  // Register the plugin
  "plugins": {
    "allow": ["googlechatpubsub"]
  },

  // Channel config (standard convention since v0.2.0)
  "channels": {
    "googlechatpubsub": {
      "enabled": true,
      "projectId": "your-gcp-project",
      "topicId": "openclaw-chat-events",
      "subscriptionId": "openclaw-chat-events-sub",
      "pollIntervalSeconds": 3,
      "renewalBufferMinutes": 30,
      "oauth": {
        "clientId": "YOUR_OAUTH_CLIENT_ID",
        "clientSecret": "YOUR_OAUTH_CLIENT_SECRET",
        "tokensFile": "/home/you/gchat-tokens.json"
      },
      "bindings": [
        {
          "space": "spaces/ABC123example",
          "replyInThread": true,
          "threadSessionIsolation": true,
          "agents": [
            { "agentId": "chief-of-staff", "alwaysListen": true },
            { "agentId": "engineer", "mentionKeyword": "eng" },
            { "agentId": "designer", "mentionKeyword": "design" }
          ]
        }
      ]
    }
  },

  // Route each agent to its own session
  "bindings": [
    { "agentId": "chief-of-staff", "match": { "channel": "googlechatpubsub", "accountId": "chief-of-staff" } },
    { "agentId": "engineer", "match": { "channel": "googlechatpubsub", "accountId": "engineer" } },
    { "agentId": "designer", "match": { "channel": "googlechatpubsub", "accountId": "designer" } }
  ]
}

README

# googlechatpubsub โ€” OpenClaw Channel Plugin

> **[๐Ÿ“– Visual Setup Guide](https://teyou.github.io/openclaw-googlechatpubsub-plugin/)** โ€” step-by-step installation with screenshots

Listen to Google Chat spaces via **Workspace Events API + Cloud Pub/Sub** โ€” no `@mention` required.

Messages arrive through Pub/Sub, get routed to one or more agents by keyword or always-listen rules, processed through the OpenClaw pipeline, and replied via the Google Chat API. Thread-first replies and per-thread session isolation are supported.

> **Status:** Alpha (v0.2.0). Works in production but APIs may change.

## How It Works

```
Google Chat Space
       โ”‚
       โ–ผ
Workspace Events API โ”€โ”€โ–บ Cloud Pub/Sub Topic
                              โ”‚
                              โ–ผ
                    โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”
                    โ”‚  googlechatpubsub   โ”‚
                    โ”‚  (OpenClaw plugin)  โ”‚
                    โ”‚                     โ”‚
                    โ”‚  Poll โ–บ Filter โ–บ    โ”‚
                    โ”‚  Route โ–บ Pipeline   โ”‚
                    โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ฌโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜
                             โ”‚
                             โ–ผ
                    Google Chat API (reply)
```

## Features

- **No @mention required** โ€” Pub/Sub delivers ALL messages from subscribed spaces
- **Multi-agent routing** โ€” keyword matching + always-listen rules
- **Thread-first replies** โ€” bot replies in threads, never clutters main window
- **Thread-scoped sessions** โ€” each thread gets its own conversation context
- **File attachment support** โ€” downloads user-uploaded files (images, PDFs, docs) via Chat API and passes them to agents
- **Emoji reactions** โ€” ๐Ÿ‘€ on received messages via Chat Reactions API
- **Auto-renewing subscriptions** โ€” handles the 4-hour Workspace Events TTL automatically
- **In-process pipeline** โ€” uses OpenClaw SDK directly (no subprocess hacks)

## Prerequisites

- OpenClaw gateway running (v0.23+)
- Google Workspace account (not consumer Gmail)
- GCP project with billing enabled
- A Google Chat app (bot) already configured with a service account
- The **OAuth user must be a member** of every space in the bindings config

## Installation

### Option A: Install from npm (recommended)

```bash
openclaw plugins install @teyou/openclaw-googlechatpubsub
```

### Option B: Manual install

```bash
# Create the plugin directory
mkdir -p ~/.openclaw/extensions/googlechatpubsub

# Copy plugin files
cp openclaw.plugin.json ~/.openclaw/extensions/googlechatpubsub/
cp index.ts ~/.openclaw/extensions/googlechatpubsub/
```

## GCP Setup

### 1. Enable APIs

In the [GCP Console](https://console.cloud.google.com/apis/library):
- **Cloud Pub/Sub API** โ€” Enable
- **Google Workspace Events API** โ€” Enable

### 2. Create Pub/Sub Topic

```bash
# Via GCP Console or gcloud:
gcloud pubsub topics create openclaw-chat-events
gcloud pubsub subscriptions create openclaw-chat-events-sub \
  --topic=openclaw-chat-events
```

Grant the Chat API push service account permission to publish:

```bash
gcloud pubsub topics add-iam-policy-binding openclaw-chat-events \
  --member="serviceAccount:[email protected]" \
  --role="roles/pubsub.publisher"
```

### 3. OAuth Consent Screen

1. Go to **APIs & Services โ†’ OAuth consent screen**
2. Select **Internal** audience
3. Set app name (e.g., "OpenClaw Pub/Sub")
4. Add developer contact email
5. Add scopes:
   - `https://www.googleapis.com/auth/chat.messages` (read + send; supersedes `chat.messages.readonly`)
   - `https://www.googleapis.com/auth/chat.spaces.readonly`
   - `https://www.googleapis.com/auth/chat.messages.reactions`
   - `https://www.googleapis.com/auth/pubsub`

### 4. Create OAuth Client

1. Go to **APIs & Services โ†’ Credentials โ†’ Create Credentials โ†’ OAuth client ID**
2. Type: **Web application**
3. Add redirect URI: `http://localhost:3000/oauth/callback`
4. Download the JSON credentials file

### 5. Authorize & Get Tokens

Generate the authorization URL:

```
https://accounts.google.com/o/oauth2/v2/auth?client_id=YOUR_CLIENT_ID&redirect_uri=http://localhost:3000/oauth/callback&response_type=code&scope=https://www.googleapis.com/auth/chat.messages+https://www.googleapis.com/auth/chat.spaces.readonly+https://www.googleapis.com/auth/chat.messages.reactions+https://www.googleapis.com/auth/pubsub&access_type=offline&prompt=consent
```

Open the URL, grant consent, copy the `code` parameter from the redirect, then exchange it:

```bash
curl -s -X POST https://oauth2.googleapis.com/token \
  -d "code=AUTH_CODE" \
  -d "client_id=YOUR_CLIENT_ID" \
  -d "client_secret=YOUR_CLIENT_SECRET" \
  -d "redirect_uri=http://localhost:3000/oauth/callback" \
  -d "grant_type=authorization_code" | python3 -m json.tool > ~/gchat-tokens.json
```

### 6. Find Your Space ID

From the Google Chat URL:
- `https://chat.google.com/room/ABC123example` โ†’ `spaces/ABC123example`
- `https://mail.google.com/mail/u/0/#chat/space/ABC123example` โ†’ `spaces/ABC123example`

## Configuration

Add to your `openclaw.json`:

```jsonc
{
  // Register the plugin
  "plugins": {
    "allow": ["googlechatpubsub"]
  },

  // Channel config (standard convention since v0.2.0)
  "channels": {
    "googlechatpubsub": {
      "enabled": true,
      "projectId": "your-gcp-project",
      "topicId": "openclaw-chat-events",
      "subscriptionId": "openclaw-chat-events-sub",
      "pollIntervalSeconds": 3,
      "renewalBufferMinutes": 30,
      "oauth": {
        "clientId": "YOUR_OAUTH_CLIENT_ID",
        "clientSecret": "YOUR_OAUTH_CLIENT_SECRET",
        "tokensFile": "/home/you/gchat-tokens.json"
      },
      "bindings": [
        {
          "space": "spaces/ABC123example",
          "replyInThread": true,
          "threadSessionIsolation": true,
          "agents": [
            { "agentId": "chief-of-staff", "alwaysListen": true },
            { "agentId": "engineer", "mentionKeyword": "eng" },
            { "agentId": "designer", "mentionKeyword": "design" }
          ]
        }
      ]
    }
  },

  // Route each agent to its own session
  "bindings": [
    { "agentId": "chief-of-staff", "match": { "channel": "googlechatpubsub", "accountId": "chief-of-staff" } },
    { "agentId": "engineer", "match": { "channel": "googlechatpubsub", "accountId": "engineer" } },
    { "agentId": "designer", "match": { "channel": "googlechatpubsub", "accountId": "designer" } }
  ]
}
```

> **Migrating from v0.1.x?** The old `plugins.entries.googlechatpubsub.config` path still works as a fallback. Move your config to `channels.googlechatpubsub` when convenient โ€” no other changes needed.

Restart the gateway:

```bash
openclaw gateway restart
```

Verify the plugin loaded:

```bash
openclaw plugins list
```

## Multi-Agent Routing

Messages are routed based on two rules:

1. **`alwaysListen`** agents receive every message
2. **`mentionKeyword`** agents receive messages containing their keyword (case-insensitive)

Both are combined โ€” alwaysListen agents are always included, keyword-matched agents are added on top (deduped).

| Message | Routes to |
|---|---|
| `"hello everyone"` | chief-of-staff |
| `"eng, review this PR"` | chief-of-staff + engineer |
| `"design a new landing page"` | chief-of-staff + designer |
| `"eng and design, sync up"` | chief-of-staff + engineer + designer |

## Thread Behavior

| Setting | Effect |
|---|---|
| `replyInThread: false` | Bot replies in main window (default) |
| `replyInThread: true` | Bot always replies in a thread |
| `threadSessionIsolation: true` | Each thread gets its own session/memory |
| `threadSessionIsolation: false` | All threads share one space-level session |

When `replyInThread` is enabled and `threadSessionIsolation` is not set, it defaults to `true`.

## Subscription Lifecycle

- Workspace Events subscriptions have a **4-hour TTL**
- The plugin auto-creates subscriptions on startup
- Checks and renews every 5 minutes (configurable via `renewalBufferMinutes`)
- State persisted in `~/.openclaw/gchat-pubsub-subscription-state.json`

## Configuration Reference

| Option | Type | Default | Description |
|---|---|---|---|
| `enabled` | boolean | `true` | Enable/disable the plugin |
| `projectId` | string | *required* | GCP project ID |
| `topicId` | string | *required* | Pub/Sub topic ID |
| `subscriptionId` | string | *required* | Pub/Sub subscription ID |
| `pollIntervalSeconds` | number | `3` | Seconds between Pub/Sub polls |
| `renewalBufferMinutes` | number | `30` | Minutes before expiry to renew subscription |
| `agentTimeoutSeconds` | number | `60` | Timeout for agent pipeline execution |
| `serviceAccountFile` | string | *from googlechat* | Path to bot service account JSON |
| `oauth.clientId` | string | *required* | OAuth 2.0 client ID |
| `oauth.clientSecret` | string | *required* | OAuth 2.0 client secret |
| `oauth.redirectUri` | string | โ€” | OAuth redirect URI |
| `oauth.tokensFile` | string | *required* | Path to OAuth tokens JSON file |
| `bindings[].space` | string | *required* | Google Chat space name |
| `bindings[].replyInThread` | boolean | `false` | Always reply in threads |
| `bindings[].threadSessionIsolation` | boolean | *=replyInThread* | Isolate sessions per thread |
| `bindings[].agents[].agentId` | string | *required* | Agent ID to route to |
| `bindings[].agents[].mentionKeyword` | string | โ€” | Keyword trigger for this agent |
| `bindings[].agents[].alwaysListen` | boolean | `false` | Receive all messages |

## Troubleshooting

| Issue | Fix |
|---|---|
| Plugin not in `openclaw plugins list` | Add `"googlechatpubsub"` to `plugins.allow` array |
| Subscription fails with 403/404 | OAuth user must be a member of the target space |
| Messages not arriving | Verify IAM binding on Pub/Sub topic for `[email protected]` |
| OAuth token expired | Plugin auto-refreshes; if refresh_token revoked, re-run the auth flow |
| 403 on reactions | Missing `chat.messages.reactions` scope; re-auth with all scopes |
| Multiple replies per message | Check for

... (truncated)
tools

Comments

Sign in to leave a comment

Loading comments...