npm package: @prombot-ai/prombot-channel
Description: OpenClaw channel plugin for PromBot
Latest version: 0.7.0

# PromBot Channel

OpenClaw channel plugin for [PromBot](https://prombot.io) messaging.

Inbound webhooks are dispatched through OpenClaw's standard auto-reply pipeline (same family of flow as Telegram or WhatsApp integrations): the agent generates a reply, and long text is **split into multiple PromBot API messages** using markdown-aware chunking, so users see a natural "streaming" sequence of bubbles on the wire.

## Installation

```sh
# From npm / ClawHub
openclaw plugins install @prombot-ai/prombot
```

### Local development (linked install)

Use `--link` (`-l`) to load the plugin directly from the source directory
without copying it. OpenClaw registers the path in `plugins.load.paths`
so changes are picked up on the next gateway restart.

> **Important:** the path must point to the `channel/` directory (where
> `openclaw.plugin.json` lives), not the repository root.

Run from the repository root:

```sh
openclaw plugins install -l ./channel
```

Or with an absolute path from anywhere:

```sh
openclaw plugins install -l /path/to/prombot-ai/channel
```

Then confirm `plugins.load.paths` and the entry are present in your config:

```jsonc
{
  "plugins": {
    "load": { "paths": ["/path/to/prombot-ai/channel"] },
    "entries": {
      "prombot": { "enabled": true }
    }
  }
}
```

```sh
openclaw gateway restart
openclaw plugins list   # verify "prombot" appears
```

## Configuration

Add the following to your OpenClaw config file:

```jsonc
{
  "channels": {
    "prombot": {
      "token": "pb-...",           // required — PromBot API token (any non-empty string is fine for the local mock)
      "baseUrl": "http://127.0.0.1:3456/v1", // required — PromBot API base URL (e.g. chat server)
      "webhookSecret": "...",      // recommended — verifies incoming webhooks
      "allowFrom": ["user-id-1"],  // optional — DM allowlist (see below)
      "dmSecurity": "allowlist"    // optional — "allowlist" (default) or "open"
    }
  },
  "plugins": {
    "entries": {
      "prombot": { "enabled": true }
    }
  }
}
```

Use `http://127.0.0.1:3456/v1` when running the [PromBot chat](../chat/) web server locally (default port `3456`, path `/v1` via `CHAT_PUBLIC_BASE_URL`). For the included mock API instead, use `http://127.0.0.1:4321/v1`. For a hosted deployment, set `baseUrl` to your public API root (for example `https://prombot.ai/chat`).

When the gateway runs inside WSL2, local proxy environment variables can break replies back into the chat web even when `http://127.0.0.1:3456/v1` is otherwise correct. This plugin now bypasses proxy environment variables for outbound PromBot HTTP, but if you are debugging with ad-hoc scripts, verify `NO_PROXY` covers `127.0.0.1` and `localhost` or bypass the proxy explicitly.

**DM access:** With the default `dmSecurity` of `"allowlist"`, if `allowFrom` is non-empty, only those PromBot user IDs can trigger the agent. Add every user ID you expect to test (for example the `from` value used in `test-webhook.sh` or `/simulate/inbound`). Use `"dmSecurity": "open"` to allow any sender while testing.

Then restart the gateway:

```sh
openclaw gateway restart
```

## Sending messages

Use the OpenClaw TUI or CLI to send a message to a PromBot user. The `--target`
value is the recipient's PromBot user ID (see [Finding user IDs](#finding-user-ids) below).

```sh
# Send a text message
openclaw message send --channel prombot --target <user-id> -m "Hello"

# Send with media
openclaw message send --channel prombot --target <user-id> -m "See attached" --media ./file.png
```

### Finding user IDs

PromBot user IDs come from the `from` field of inbound webhook events. The
easiest ways to obtain one:

1. **Inbound message** — ask the user to send your bot a message first. The
   gateway session key will be `prombot-<user-id>`:
   ```sh
   openclaw sessions --json
   ```

2. **Channel logs** — inspect recent inbound events:
   ```sh
   openclaw channels logs --channel prombot
   ```

3. **Test webhook** — use the included `test-webhook.sh` script (see
   [Local development](#local-development) below) to simulate an inbound message
   and confirm the round-trip.

## Webhook setup

Point your PromBot app's webhook URL to:

```
https://<your-openclaw-host>/prombot/webhook
```

Set the webhook secret in your PromBot app dashboard and mirror it in
`channels.prombot.webhookSecret`. Incoming requests are verified with
HMAC-SHA256 (`X-PromBot-Signature: sha256=<hex>`).

## Inbound flow and chunked replies

1. **Webhook** — PromBot (or the local mock) posts JSON to `/prombot/webhook` with `type`, `from`, `conversationId`, `text`, and optional `messageId`.
2. **Routing** — The plugin resolves the agent route and session, builds the agent envelope, and records session metadata.
3. **Agent** — OpenClaw runs the configured model and streams assistant output through the shared reply dispatcher (tool/block/final chunks).
4. **Outbound** — Each sendable slice of text is chunked with the same markdown-aware logic used elsewhere in OpenClaw, then sent via `POST {baseUrl}/messages` (the client appends `/messages` to your configured `baseUrl`). Long answers therefore appear as **several** API calls—similar in spirit to multi-message delivery on Telegram or WhatsApp.

## Development

```sh
# Install dependencies
npm install

# Run tests
npm test

# Type-check
npm run check
```

### Mock API server

`mock-server.mjs` runs a local HTTP server that stubs the PromBot API so you
can develop and test without hitting the real API. You still need a `token` in
config (the mock does not validate it). Point `baseUrl` at the mock as below.

**Terminal 1 — start the mock server:**

```sh
node mock-server.mjs          # listens on http://127.0.0.1:4321
node mock-server.mjs 5000     # custom port
```

Two optional CLI flags control inbound-simulation behaviour:

| Flag | Default | Description |
|---|---|---|
| `--gateway-url` | `http://localhost:18789` | URL of the running OpenClaw gateway |
| `--webhook-secret` | _(unset)_ | Shared secret used to sign simulated inbound events with HMAC-SHA256. Must match `channels.prombot.webhookSecret` in your OpenClaw config. |

```sh
# Example — custom gateway port and a webhook secret
node mock-server.mjs 4321 --gateway-url http://localhost:19000 --webhook-secret mysecret
```

**Configure OpenClaw to use it:**

```sh
openclaw config set channels.prombot.baseUrl 'http://127.0.0.1:4321/v1'
```

Or add `"baseUrl": "http://127.0.0.1:4321/v1"` directly to the `channels.prombot`
section of `~/.openclaw/openclaw.json`.

**Terminal 2 — send a test outbound message (OpenClaw → mock API):**

```sh
openclaw message send --channel prombot --target 'any-user-id' -m 'Hello'
```

The mock server terminal prints the request details and confirms the user ID.
All sent messages are also available at `GET http://127.0.0.1:4321/v1/sent`.

**Terminal 2 — simulate an inbound message (mock API → OpenClaw):**

Use `POST /simulate/inbound` to push a fake PromBot message into the running
OpenClaw gateway. The mock server signs the webhook with HMAC-SHA256 when
`--webhook-secret` is set, or uses a bypass signature otherwise.

Ensure the same `from` user id is allowed by your DM policy (e.g. listed in
`allowFrom`, or use `dmSecurity: "open"`). Otherwise the plugin will ignore the
inbound event.

```sh
curl -s -X POST http://localhost:4321/simulate/inbound \
  -H 'Content-Type: application/json' \
  -d '{"from": "any-user-id", "text": "Hello bot"}'
```

You can also supply an explicit `conversationId`:

```sh
curl -s -X POST http://localhost:4321/simulate/inbound \
  -H 'Content-Type: application/json' \
  -d '{"from": "any-user-id", "conversationId": "conv_abc", "text": "Hi again"}'
```

The server forwards the event to `--gateway-url/prombot/webhook` and
prints the gateway's response along with the `openclaw message send` command
you can use to reply.

With the gateway and model configured, the bot’s answer is sent back through
the mock as one or more `POST /v1/messages` requests; watch the mock terminal
to see chunked delivery for longer replies.

**Restore the real API when done:**

```sh
openclaw config unset channels.prombot.baseUrl
```

### Simulating inbound webhooks

`test-webhook.sh` sends a simulated inbound message to the local gateway and
shows the resulting PromBot user ID.

**Requirements:** gateway must be running (`openclaw gateway`).

```sh
# Default — uses pb_testuser_001 as the fake sender
./test-webhook.sh

# Custom user ID and message text
./test-webhook.sh pb_real_user_abc "Hey bot"
```

The script prints the HTTP status, gateway response, and the exact
`openclaw message send` command to reply to that user.

## Further reading

- [Building a Channel Plugin for OpenClaw — A Step-by-Step Guide](https://wemble.com/2026/01/31/building-an-openclaw-plugin.html) — Wemble (Jan 2026): walks through project setup, manifest, entry point, channel definition, testing, and installation from scratch.
- [OpenClaw Plugin Documentation](https://docs.openclaw.ai/plugin) — Full plugin API reference.

## License

Apache 2.0