← Back to Plugins
Channels

Whatsapp Cloud Api

mcostantino-dev By mcostantino-dev 👁 268 views ▲ 0 votes

WhatsApp Cloud API channel plugin for OpenClaw - official Meta Business API, no Baileys

GitHub

Install

npm install &&

Configuration Example

> {
>   "plugins": {
>     "load": {
>       "paths": ["/absolute/path/to/openclaw-channel-whatsapp-cloud"]
>     }
>   }
> }
>

README

# OpenClaw WhatsApp Cloud API Channel

WhatsApp channel for [OpenClaw](https://github.com/openclaw/openclaw) using Meta's **official Cloud API** — production-safe, no Baileys, no ban risk.

## Why this plugin?

OpenClaw's built-in WhatsApp channel uses [Baileys](https://github.com/WhiskeySockets/Baileys), a reverse-engineered WhatsApp Web protocol. It works great for personal use, but Meta can ban accounts at any time — making it unsuitable for business bots.

This plugin uses the **official WhatsApp Cloud API** (`graph.facebook.com`) instead:

| | Built-in (Baileys) | This plugin (Cloud API) |
|---|---|---|
| Auth | QR code scan | OAuth access token |
| Ban risk | High (unofficial) | None (official) |
| 24-hour window | No restriction | Required (templates after 24h) |
| Cost | Free | Pay-per-conversation |
| Sending first | Anytime | Templates only |
| Best for | Personal assistant | Customer-facing bots |

## Prerequisites

- **OpenClaw** >= 2026.2.x installed and configured (`openclaw configure`)
- **Node.js** >= 22
- A **Meta Business App** with WhatsApp product enabled
- A domain with **HTTPS** for the webhook (ngrok for dev, reverse proxy for prod)

## Quick start (development)

### 1. Install the plugin

```bash
git clone https://github.com/baiadigitale/openclaw-channel-whatsapp-cloud.git
cd openclaw-channel-whatsapp-cloud
npm install && npm run build
openclaw plugins install -l .
```

> **Note:** Due to a known OpenClaw bug with symlinks, if the plugin isn't discovered after `install -l .`, add this to `~/.openclaw/openclaw.json`:
> ```json
> {
>   "plugins": {
>     "load": {
>       "paths": ["/absolute/path/to/openclaw-channel-whatsapp-cloud"]
>     }
>   }
> }
> ```

### 2. Get Meta credentials

1. Go to [developers.facebook.com](https://developers.facebook.com/) and create an app (type: **Business**)
2. Add the **WhatsApp** product
3. In **WhatsApp > API Setup**, note your **Phone Number ID**
4. Create a permanent access token:
   - **Business Settings > System Users** > create one with **Admin** role
   - Generate a token with permissions: `whatsapp_business_messaging`, `whatsapp_business_management`
5. Note your **App Secret** from **App Settings > Basic** (for webhook signature verification)

### 3. Run the setup wizard

```bash
openclaw whatsapp-cloud setup
```

This will prompt for all credentials and save them to `~/.openclaw/openclaw.json`.

Alternatively, set them manually:

```bash
openclaw config set channels.whatsapp-cloud.phoneNumberId "YOUR_PHONE_NUMBER_ID"
openclaw config set channels.whatsapp-cloud.accessToken "YOUR_ACCESS_TOKEN"
openclaw config set channels.whatsapp-cloud.appSecret "YOUR_APP_SECRET"
openclaw config set channels.whatsapp-cloud.verifyToken "a-random-string-you-choose"
```

### 4. Expose the webhook (dev)

```bash
ngrok http 3100
```

Copy the `https://xxxx.ngrok-free.app` URL.

### 5. Register the webhook on Meta

1. Go to **WhatsApp > Configuration** in your Meta app
2. Click **Edit** on the Webhook section
3. **Callback URL**: `https://your-ngrok-url/webhook/whatsapp-cloud`
4. **Verify Token**: the string you chose in step 3
5. Click **Verify and Save**
6. Subscribe to the **messages** webhook field

### 6. Start the gateway

```bash
openclaw gateway restart
```

Send a WhatsApp message to your business number — the bot will respond.

---

## Production deployment

### Architecture

```
User on WhatsApp
      |
      v
Meta Cloud API (graph.facebook.com)
      |
      v  HTTPS POST
+--------------------------------------------------+
|  Your server (VPS / Docker / Cloud)              |
|                                                  |
|  nginx/Caddy (TLS termination, port 443)         |
|      |                                           |
|      v  proxy_pass :3100                         |
|  OpenClaw Gateway (systemd service)              |
|    +-- whatsapp-cloud plugin                     |
|    |     webhook.ts  -> receives messages         |
|    |     crypto.ts   -> verifies HMAC signature   |
|    |     index.ts    -> dispatches to agent        |
|    |     api.ts      -> sends replies              |
|    +-- agent (Claude / GPT / ...)                |
+--------------------------------------------------+
```

### Recommended repo structure

Create a **deployment repository** separate from this plugin:

```
my-openclaw-bot/
  openclaw.json          # OpenClaw config (env var refs for secrets)
  .env.example           # Documents all required env vars
  .env                   # Actual secrets (NEVER commit this)
  .gitignore
  workspace/
    AGENTS.md            # Agent instructions, persona, behavior rules
    SOUL.md              # Personality, tone, boundaries
    IDENTITY.md          # Agent name, emoji
    USER.md              # Info about the user/company
    TOOLS.md             # Tool-specific notes
  scripts/
    deploy.sh            # Deployment automation
    backup.sh            # State backup
  docker-compose.yml     # Optional: containerized deployment
  Caddyfile              # Or nginx.conf — reverse proxy config
```

**`.gitignore`:**
```
.env
*.bak
sessions/
credentials/
```

**`openclaw.json`** (with env var references):
```json5
{
  "gateway": {
    "mode": "local",
    "bind": "loopback",
    "auth": {
      "mode": "token",
      "token": "${OPENCLAW_GATEWAY_TOKEN}"
    }
  },

  // LLM provider
  "auth": {
    "profiles": {
      "anthropic:default": {
        "provider": "anthropic",
        "mode": "token"
      }
    }
  },
  "agents": {
    "defaults": {
      "workspace": "./workspace",
      "models": {
        "anthropic/claude-sonnet-4-5": {}
      }
    }
  },

  // WhatsApp Cloud channel
  "channels": {
    "whatsapp-cloud": {
      "phoneNumberId": "${WHATSAPP_PHONE_NUMBER_ID}",
      "accessToken": "${WHATSAPP_ACCESS_TOKEN}",
      "appSecret": "${WHATSAPP_APP_SECRET}",
      "verifyToken": "${WHATSAPP_VERIFY_TOKEN}",
      "webhookPort": 3100,
      "dmPolicy": "open",
      "sendReadReceipts": true
    }
  },

  // Plugin
  "plugins": {
    "entries": {
      "whatsapp-cloud": { "enabled": true }
    }
  }
}
```

**`.env.example`:**
```bash
# Anthropic API key (get from https://console.anthropic.com/settings/keys)
ANTHROPIC_API_KEY=sk-ant-...

# OpenClaw gateway auth token (generate: openssl rand -hex 24)
OPENCLAW_GATEWAY_TOKEN=

# WhatsApp Cloud API (from https://developers.facebook.com/)
WHATSAPP_PHONE_NUMBER_ID=
WHATSAPP_ACCESS_TOKEN=
WHATSAPP_APP_SECRET=
WHATSAPP_VERIFY_TOKEN=
```

### Install on a production server

```bash
# 1. Install OpenClaw
npm install -g openclaw

# 2. Clone the plugin (private repo — no npm publish needed)
git clone [email protected]:baiadigitale/openclaw-channel-whatsapp-cloud.git ~/extensions/whatsapp-cloud
cd ~/extensions/whatsapp-cloud && npm install && npm run build

# 3. Clone your deployment repo
git clone https://github.com/yourorg/my-openclaw-bot.git ~/openclaw-bot
cd ~/openclaw-bot

# 4. Copy env file and fill in secrets
cp .env.example .env
nano .env

# 5. Point OpenClaw to your config
export OPENCLAW_CONFIG_PATH=~/openclaw-bot/openclaw.json
export OPENCLAW_STATE_DIR=~/openclaw-bot/.state

# 6. Install and start the gateway
openclaw gateway install
systemctl --user start openclaw-gateway.service
systemctl --user enable openclaw-gateway.service
```

Make sure your `openclaw.json` loads the plugin from the cloned path:

```json
{
  "plugins": {
    "load": {
      "paths": ["~/extensions/whatsapp-cloud"]
    },
    "entries": {
      "whatsapp-cloud": { "enabled": true }
    }
  }
}
```

### Update the plugin

After pushing changes to the repo, run this on the server:

```bash
cd ~/extensions/whatsapp-cloud && git pull && npm install && npm run build && systemctl --user restart openclaw-gateway.service
```

### Reverse proxy (Caddy)

**`Caddyfile`:**
```
yourdomain.com {
    reverse_proxy /webhook/whatsapp-cloud localhost:3100
}
```

```bash
sudo caddy start --config Caddyfile
```

Caddy handles TLS automatically via Let's Encrypt.

**nginx alternative:**
```nginx
server {
    listen 443 ssl;
    server_name yourdomain.com;

    ssl_certificate /etc/letsencrypt/live/yourdomain.com/fullchain.pem;
    ssl_certificate_key /etc/letsencrypt/live/yourdomain.com/privkey.pem;

    location /webhook/whatsapp-cloud {
        proxy_pass http://127.0.0.1:3100;
        proxy_set_header Host $host;
        proxy_set_header X-Real-IP $remote_addr;
        proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
        proxy_set_header X-Forwarded-Proto $scheme;
    }
}
```

### Docker deployment (optional)

**`docker-compose.yml`:**
```yaml
services:
  openclaw:
    image: node:22-slim
    working_dir: /app
    command: ["npx", "openclaw", "gateway", "--bind", "lan", "--port", "3100"]
    env_file: .env
    environment:
      OPENCLAW_CONFIG_PATH: /app/openclaw.json
      OPENCLAW_STATE_DIR: /data
      NODE_ENV: production
    volumes:
      - ./openclaw.json:/app/openclaw.json:ro
      - ./workspace:/app/workspace:ro
      - openclaw-data:/data
    ports:
      - "3100:3100"
    restart: unless-stopped

volumes:
  openclaw-data:
```

### Monitoring

```bash
# Live logs
journalctl --user -u openclaw-gateway.service -f

# Channel status
openclaw whatsapp-cloud status

# Gateway health
openclaw gateway status

# Send a test message
openclaw whatsapp-cloud test +39XXXXXXXXXX
```

### Security checklist

- [ ] `appSecret` is set (enables webhook HMAC signature verification)
- [ ] Access token is a **System User token** (permanent, not a temporary test token)
- [ ] `dmPolicy` is set to `"allowlist"` if the bot should only serve specific numbers
- [ ] Webhook endpoint is HTTPS-only
- [ ] `.env` file has `chmod 600` and is not committed to git
- [ ] Gateway auth token is set (`gateway.auth.mode: "token"`)
- [ ] Gateway binds to loopback only (reverse proxy handles external traffic)

---

## Configuration reference

| Key | Type | Default | Description |
|-----|------|---------|-------------|
| `enab

... (truncated)
channels

Comments

Sign in to leave a comment

Loading comments...