feishu

nebullii/openclaw

Otheropenclawby nebullii

Summary

OpenClaw plugin exposing 1 skill across feishu.

Install to Claude Code

openclaw plugin add nebullii/openclaw

Run in Claude Code. Add the marketplace first with /plugin marketplace add nebullii/openclaw if you haven't already.

README.md

OpenClaw Setup Guide

Full setup guide for running OpenClaw via Docker with Telegram, google-antigravity provider, and Join39 agent network integration. Follow each step in order.

Architecture

                    Telegram Bot
                        |
                        v
Join39 / External --> Cloudflare Tunnel (HTTPS)
                        |
                        v
                  OpenClaw Gateway (HTTP :18789)
                        |
                        +--> /join39 (Join39 plugin route)
                        +--> /v1/chat/completions (OpenAI-compatible API)
                        +--> /overview (Control UI)
                        +--> WebSocket (Telegram, CLI, etc.)
                        |
                        v
                  AI Provider (google-antigravity / Gemini Flash)

Prerequisites

Before you start, make sure you have:

  • macOS or Linux (Windows users: use WSL2)
  • Docker Desktop installed and running
  • Node.js 22+ installed
  • cloudflared - install with brew install cloudflared (macOS) or see Cloudflare docs for Linux
  • A Telegram account (optional, for Telegram bot)
  • A Join39 account (optional, for agent network)

Step 1: Clone and Build

git clone https://github.com/nebullii/openclaw.git
cd openclaw

Build the Docker image (this may take a few minutes):

docker build -t openclaw:local .

Step 2: Create Your Config Directory

The .openclaw/ directory holds your gateway config, extensions, and agent data. It is gitignored (your secrets stay local).

mkdir -p .openclaw/extensions

Copy the example config:

cp openclaw.example.json .openclaw/openclaw.json

Create the workspace directory:

mkdir -p workspace

Step 3: Set Up Environment Variables

cp .env.example .env

Open .env in your editor and fill in the values. Here's what each one does:

| Variable | Required? | Description | |---|---|---| | OPENCLAW_IMAGE | Yes | Docker image name. Use openclaw:local if you built it in Step 1 | | OPENCLAW_GATEWAY_TOKEN | Yes | Pick any random string. This is the password for the Control UI and CLI | | OPENCLAW_CONFIG_DIR | Yes | Path to your .openclaw/ directory. Use ./.openclaw | | OPENCLAW_WORKSPACE_DIR | Yes | Path to your workspace directory. Use ./workspace | | OPENCLAW_GATEWAY_PORT | No | Gateway port (default: 18789) | | OPENCLAW_GATEWAY_BIND | No | lan (accessible from network) or loopback (localhost only) | | JOIN39_PASSPORT_URL | No | Your Join39 passport token (needed for Join39 integration) | | CLOUDFLARE_TUNNEL_TOKEN | No | Only for persistent Cloudflare tunnels |

Step 4: Configure the Gateway

Open .openclaw/openclaw.json in your editor. The example file has everything pre-configured, but you need to update these values:

4a. Set your gateway token

Find gateway.remote.token and replace "your-gateway-token-here" with the same token you put in OPENCLAW_GATEWAY_TOKEN in .env. These must match.

4b. Set up your AI provider

The example uses google-antigravity with Gemini Flash. Update the email in auth.profiles:

"google-antigravity:your-email@gmail.com": {
  "provider": "google-antigravity",
  "mode": "oauth"
}

Replace your-email@gmail.com with your actual Google account email.

4c. Set up Telegram (optional)

If you want a Telegram bot, get a token from @BotFather on Telegram and update:

"channels": {
  "telegram": {
    "enabled": true,
    "botToken": "your-bot-token-from-botfather"
  }
}

If you don't want Telegram, set "enabled": false.

Step 5: Start the Gateway

docker compose up -d openclaw-gateway

Check that it started successfully:

docker compose logs openclaw-gateway --tail 20

You should see a line like listening on ws://0.0.0.0:18789.

Open the Control UI

Go to http://localhost:18789/overview in your browser. Paste your OPENCLAW_GATEWAY_TOKEN to connect.

Step 6: Device Pairing (CLI)

To send messages via the CLI:

docker compose run --rm openclaw-cli message send "hello"

If it says "pairing required", approve the device:

docker compose exec openclaw-gateway node dist/index.js devices list
docker compose exec openclaw-gateway node dist/index.js devices approve <device-id>

Replace <device-id> with the ID shown in the list.

Step 7: Join39 Integration (Optional)

Skip this step if you don't need Join39.

7a. What is Join39?

Join39 is ClawNanda's agent network. Other AI agents can discover and call your agent. It sends function calls as HTTPS POST requests and expects JSON responses within 10 seconds / 2000 characters.

7b. Copy the extension

cp -r extensions/join39 .openclaw/extensions/join39

This copies the plugin files into your config directory. The extension contains:

| File | Purpose | |---|---| | package.json | Extension metadata | | openclaw.plugin.json | Plugin manifest (gateway crashes without this!) | | index.ts | Entry point - registers the /join39 HTTP route | | src/config.ts | Config parsing | | src/handler.ts | Handles incoming requests, forwards to your agent | | src/types.ts | TypeScript types |

7c. Verify plugin config

The openclaw.example.json already includes the Join39 plugin config. Verify these sections exist in your .openclaw/openclaw.json:

"gateway": {
  "http": {
    "endpoints": {
      "chatCompletions": { "enabled": true }
    }
  }
}
"plugins": {
  "load": {
    "paths": ["/home/node/.openclaw/extensions/join39"]
  },
  "entries": {
    "join39": {
      "enabled": true,
      "config": {
        "enabled": true,
        "webhookPath": "/join39",
        "agentId": "main",
        "timeoutMs": 30000
      }
    }
  }
}

7d. Restart the gateway

docker compose restart openclaw-gateway

Verify the plugin loaded:

docker compose logs openclaw-gateway 2>&1 | grep "join39"

You should see: [join39] registered HTTP route at /join39

7e. Start the Cloudflare Tunnel

Join39 requires HTTPS. Cloudflare Tunnel exposes your local gateway over a secure URL for free.

Quick tunnel (free, URL changes every restart):

cloudflared tunnel --url http://localhost:18789

It will print a URL like https://random-words.trycloudflare.com. Your Join39 endpoint is that URL + /join39.

Persistent tunnel (requires a Cloudflare domain):

Add your tunnel token to .env as CLOUDFLARE_TUNNEL_TOKEN, then:

docker compose --profile tunnel up -d cloudflared

7f. Test it

Replace <TUNNEL_URL> with your actual Cloudflare tunnel URL:

source .env && curl -s -X POST "<TUNNEL_URL>/join39" -H "Content-Type: application/json" -H "Authorization: Bearer ${JOIN39_PASSPORT_URL}" -d '{"function":"ping","parameters":{"message":"hello"}}'

You should get a response like:

{"result":"pong! Hello there! What can I help you with?","error":false}

7g. Register your app on Join39

1. Go to https://join39.org/apps/submit 2. Fill in:

  • Name: pick a URL-safe slug (e.g. my-openclaw-agent)
  • Display name: your agent's name
  • Description: what your agent does
  • Category: utilities or productivity
  • API endpoint: <TUNNEL_URL>/join39
  • HTTP method: POST
  • Auth type: bearer

3. For the function parameters schema, use:

   {
     "type": "object",
     "properties": {
       "function": {
         "type": "string",
         "description": "The function to call, e.g. chat, ping, ask"
       },
       "parameters": {
         "type": "object",
         "properties": {
           "message": {
             "type": "string",
             "description": "The message or query to send to the agent"
           }
         },
         "required": ["message"]
       }
     },
     "required": ["function", "parameters"]
   }

4. Submit and install the app on your agent

File Structure Overview

openclaw/
├── .env.example              # Template for environment variables
├── .env                      # Your actual env vars (gitignored)
├── openclaw.example.json     # Template for gateway config
├── docker-compose.yml        # Docker services definition
├── Dockerfile                # Build instructions
├── SETUP.md                  # This guide
├── extensions/
│   └── join39/               # Join39 extension (repo reference copy)
├── .openclaw/                # Your config directory (gitignored)
│   ├── openclaw.json         # Gateway config (copied from example)
│   └── extensions/
│       └── join39/           # Join39 extension (active copy)
└── workspace/                # Agent workspace

Docker Compose Services

| Service | Description | Command | |---|---|---| | openclaw-gateway | Main gateway (always running) | docker compose up -d openclaw-gateway | | openclaw-cli | CLI for sending messages | docker compose run --rm openclaw-cli message send "hi" | | cloudflared | Cloudflare tunnel (opt-in) | docker compose --profile tunnel up -d cloudflared |

Common Commands

# Start the gateway
docker compose up -d openclaw-gateway

# Stop everything
docker compose down

# View gateway logs
docker compose logs openclaw-gateway --tail 50

# Restart after config changes
docker compose restart openclaw-gateway

# Start quick tunnel
cloudflared tunnel --url http://localhost:18789

# Send a message via CLI
docker compose run --rm openclaw-cli message send "hello"

Troubleshooting

| Issue | Fix | |---|---| | Cannot find module 'zod' | The Docker container has no node_modules for extensions. Make sure src/config.ts uses plain JS, not zod imports. | | Gateway crash-loops | Make sure openclaw.plugin.json exists in the extension directory. | | 405 on /v1/chat/completions | Set gateway.http.endpoints.chatCompletions.enabled: true in openclaw.json. | | pairing required on Control UI | Paste your OPENCLAW_GATEWAY_TOKEN in the Control UI settings field. | | token_mismatch | Make sure gateway.remote.token in openclaw.json matches OPENCLAW_GATEWAY_TOKEN in .env. | | Volume mount shows stale files | Use docker compose cp <file> openclaw-gateway:<path> to force-copy into the container, then restart. | | Quick tunnel URL changed | You get a new URL every time you restart cloudflared. Update it on Join39. | | Plugin not loading | Run docker compose logs openclaw-gateway 2>&1 \| grep join39 to see errors. |

Links

License

MIT

Related plugins

Browse all →