← Back to Plugins
Channels

Channel Streamchat

def-initialize-gmbh By def-initialize-gmbh 👁 229 views ▲ 0 votes

OpenClaw channel plugin for https://getstream.io/chat/

GitHub

Install

npm install
```

Configuration Example

{
  // Add the channel configuration
  "channels": {
    "streamchat": {
      "enabled": true,
      "apiKey": "your_api_key",
      "botUserId": "chatgpt",
      "botUserToken": "<token from step 2>",
      // Optional:
      "ackReaction": "eyes",           // reaction added when message is received (default: "eyes")
      "doneReaction": "white_check_mark", // reaction swapped in when response is done (default: "white_check_mark")
      "streamingThrottle": 15          // partial-update every Nth chunk (default: 15)
    }
  },

  // Register the plugin
  "plugins": {
    "load": {
      "paths": [
        "/absolute/path/to/openclaw-channel-streamchat"
      ]
    },
    "entries": {
      "streamchat": {
        "enabled": true
      }
    }
  }
}

README

# @wunderchat/openclaw-channel-streamchat

OpenClaw channel plugin for [Stream Chat](https://getstream.io/chat/). Connects as a bot user via WebSocket, normalizes inbound messages into OpenClaw envelope format, and delivers agent responses using Stream Chat's AI streaming pattern (`partialUpdateMessage` + `ai_indicator` events).

## Prerequisites

- OpenClaw `>= 2026.2.13`
- A Stream Chat application (API key + secret from the [Stream Dashboard](https://dashboard.getstream.io/))
- Node.js `>= 20`

## Setup

### 1. Install dependencies

```bash
cd openclaw-channel-streamchat
npm install
```

### 2. Generate a bot token

The plugin connects to Stream Chat as a regular user (the bot). You need a JWT for that user, generated from your API secret. The secret is only used here — it is **not** stored in the plugin config.

Create a `.env` file in the plugin root:

```env
STREAM_API_KEY=your_api_key
STREAM_API_SECRET=your_api_secret
BOT_USER_ID=chatgpt
```

Then run:

```bash
npx tsx scripts/generate-bot-token.ts
```

This prints the bot JWT. Copy it for the next step.

### 3. Configure OpenClaw

Add the channel config and plugin entry to your `~/.openclaw/openclaw.json`:

```jsonc
{
  // Add the channel configuration
  "channels": {
    "streamchat": {
      "enabled": true,
      "apiKey": "your_api_key",
      "botUserId": "chatgpt",
      "botUserToken": "<token from step 2>",
      // Optional:
      "ackReaction": "eyes",           // reaction added when message is received (default: "eyes")
      "doneReaction": "white_check_mark", // reaction swapped in when response is done (default: "white_check_mark")
      "streamingThrottle": 15          // partial-update every Nth chunk (default: 15)
    }
  },

  // Register the plugin
  "plugins": {
    "load": {
      "paths": [
        "/absolute/path/to/openclaw-channel-streamchat"
      ]
    },
    "entries": {
      "streamchat": {
        "enabled": true
      }
    }
  }
}
```

### 4. Restart the gateway

```bash
openclaw gateway restart
```

The plugin will connect to Stream Chat, watch all channels where the bot is a member, and start processing messages.

## Testing

All test scripts live in `scripts/` and can be run with `npx tsx`. They load credentials from `.env` or use environment variables.

### Discover channels

Lists all channels the test user belongs to:

```bash
npx tsx scripts/discover-channels.ts
```

Override the defaults with environment variables:

```bash
STREAM_API_KEY=... USER_ID=myuser USER_TOKEN=... npx tsx scripts/discover-channels.ts
```

### Interactive test client

Connects as a test user, watches a channel, and lets you send messages interactively while printing incoming bot responses and AI indicator events:

```bash
# Auto-discover channels and use the first one
npx tsx scripts/test-client.ts

# Specify a channel
npx tsx scripts/test-client.ts myChannelId

# Send a single message
npx tsx scripts/test-client.ts myChannelId "Hello bot"
```

Commands inside the interactive client:

| Command | Description |
|---------|-------------|
| `/thread <parentId> <text>` | Send a thread reply |
| `/quote <messageId> <text>` | Send a quoted reply |
| `/quit` | Disconnect and exit |

Override the test user with environment variables:

```bash
STREAM_API_KEY=... TEST_USER_ID=myuser TEST_USER_TOKEN=... npx tsx scripts/test-client.ts
```

### Automated round-trip test

Sends a message and waits for the bot to respond, verifying the full streaming lifecycle (placeholder message, AI indicators, partial updates, final update):

```bash
npx tsx scripts/test-roundtrip.ts
```

Expected output:

```
[NEW MSG][chatgpt] [AI]: (no text)        # empty placeholder
[AI INDICATOR] AI_STATE_THINKING           # thinking indicator
[AI INDICATOR] AI_STATE_GENERATING         # generating indicator
[STREAMING] 2 + 2 = 4.                    # partial update
[FINAL] 2 + 2 = 4.                        # final update (generating: false)
[AI INDICATOR] cleared                     # indicator cleared

✓ Round-trip test PASSED — got bot response.
```

### Thread test

Sends a parent message, waits for the bot's response, then sends a thread reply and verifies the bot responds inside the thread:

```bash
npx tsx scripts/test-thread.ts
```

## How it works

**Inbound flow:**
1. Bot receives `message.new` event via WebSocket
2. Plugin filters out bot's own messages and AI-generated messages
3. Builds an envelope with thread/reply context wrappers (`[Thread]`, `[Replying]`)
4. Dispatches to the OpenClaw agent pipeline

**Outbound flow (streaming):**
1. Creates an empty placeholder message with `ai_generated: true`
2. Sends `ai_indicator.update` with `AI_STATE_THINKING`
3. On first text chunk, switches to `AI_STATE_GENERATING`
4. Progressively updates the message via `partialUpdateMessage` with `generating: true`
5. On completion, sends final update with `generating: false` and clears the indicator

**Thread handling:**
- Thread replies include `parent_id` so the bot's response routes to the correct thread
- First message in a thread includes the parent message text for context
- Quoted replies are wrapped in `[Replying to ...]` envelopes
channels

Comments

Sign in to leave a comment

Loading comments...