← Back to Plugins
Channels

Waxum Openclaw

imtaqin By imtaqin 👁 9 views ▲ 0 votes

OpenClaw channel plugin backed by waxum โ€” real WhatsApp buttons/lists/CTA-url

GitHub

Install

openclaw plugins install @imtaqin/openclaw-waxum

Configuration Example

{
  "channels": {
    "waxum": {
      "baseUrl": "http://127.0.0.1:3451",
      "token": "<waxum bearer token>",
      "sessionId": "<waxum session id>",
      "dmPolicy": "allowlist",
      "allowFrom": ["6281234567890"]
    }
  }
}

README

# waxum-openclaw-plugin

An [OpenClaw](https://github.com/openclaw/openclaw) channel plugin backed by
[waxum](https://github.com/imtaqin/waxum) โ€” self-hosted WhatsApp with real
interactive messages (buttons, list menus, CTA-url) instead of OpenClaw's
default plain-text-only bridges.

Structured as a native OpenClaw channel plugin per
[docs.openclaw.ai/plugins/sdk-channel-plugins](https://docs.openclaw.ai/plugins/sdk-channel-plugins):
`createChatChannelPlugin` + `defineChannelMessageAdapter` for outbound,
`defineChannelPluginEntry` for registration, `defineSetupPluginEntry` for
the `openclaw setup` wizard.

```
waxum-openclaw-plugin/
โ”œโ”€โ”€ package.json           # openclaw.channel manifest block
โ”œโ”€โ”€ openclaw.plugin.json   # config schema (baseUrl/token/sessionId/dmPolicy)
โ”œโ”€โ”€ index.ts                # defineChannelPluginEntry
โ”œโ”€โ”€ setup-entry.ts           # `openclaw setup` wizard step, validates the session live
โ””โ”€โ”€ src/
    โ”œโ”€โ”€ channel.ts            # createChatChannelPlugin: account resolution, DM security, outbound
    โ”œโ”€โ”€ client.ts               # waxum HTTP + SSE client โ€” retries, backoff, typed errors
    โ”œโ”€โ”€ client.test.ts           # unit tests (no openclaw/network dependency)
    โ””โ”€โ”€ inbound.ts                # SSE event tail -> dispatchInbound bridge
```

## Install

```bash
openclaw plugins install @imtaqin/openclaw-waxum
# or, from a local checkout:
openclaw plugins install ./waxum-openclaw-plugin
```

Then `openclaw setup` and pick the `waxum` channel โ€” it prompts for
`baseUrl` / `token` / `sessionId` and verifies the waxum session is
actually connected before writing config. The waxum session itself must
already be paired (QR/pair code done once via waxum directly); this plugin
never does first-time pairing.

Or configure `openclaw.json` directly:
```json
{
  "channels": {
    "waxum": {
      "baseUrl": "http://127.0.0.1:3451",
      "token": "<waxum bearer token>",
      "sessionId": "<waxum session id>",
      "dmPolicy": "allowlist",
      "allowFrom": ["6281234567890"]
    }
  }
}
```

## Sending interactive messages

Core's shared `message` tool only does plain text. This plugin's
`extraActions` add real WhatsApp interactivity, callable from the agent's
tool loop:

```ts
await channel.actions.waxum.sendButtons({
  account, to: "[email protected]",
  body: "Pick one", buttons: [{ id: "yes", text: "Yes" }, { id: "no", text: "No" }],
});
await channel.actions.waxum.sendList({ account, to, body: "Menu", buttonText: "Open", sections: [...] });
await channel.actions.waxum.sendCtaUrl({ account, to, body: "...", buttonText: "Open", url: "https://..." });
```

Button/list taps come back through the normal inbound path as a message
with `metadata.waxumMessageType` set (e.g. `buttons_response`,
`list_response`).

## Reliability

- `src/client.ts` retries 5xx/transport errors with capped exponential
  backoff + jitter; 401/503 fail fast (matching waxum's own status codes โ€”
  503 means "session not connected", not "try again").
- The inbound SSE bridge (`src/inbound.ts`) reconnects indefinitely on any
  drop and drops duplicate deliveries across reconnects via a bounded
  in-memory id set.

## Testing

```bash
npm test
```
`src/client.test.ts` stubs `fetch` directly โ€” no live waxum instance or
`openclaw` package needed to run it.

## Compatibility

Targets the `createChatChannelPlugin` / `defineChannelMessageAdapter` /
`defineChannelPluginEntry` API as documented publicly by OpenClaw. Only
`index.ts`, `setup-entry.ts`, and `src/channel.ts` import from `openclaw`;
`src/client.ts` and `src/inbound.ts` are plain TypeScript you can reuse or
test standalone.
channels

Comments

Sign in to leave a comment

Loading comments...