界面已本地化;技能介绍与说明文档按所选语言由 AI 自动翻译,代码、命令、路径和专业术语保留原文,以原作者文档为准。
探索技能
开发与工程 · SKILL.md

ngrok-unofficial-webhook-skill

ngrok-unofficial-webhook-skill

【开发与工程】Start an ngrok tunnel to receive incoming webhooks and process them via the LLM. Use when the user asks to listen for webhooks, set up a webhook endpoint, start ngrok, or when another skill (like Zoom RTMS Meeting Assistant) needs a public webhook URL. Receives webhook payloads and lets the LLM decide how to handle them.

独立 GitHub 快照 · 自动分类 · 以原作者文档为准

技能说明

GitHub

name: ngrok-unofficial-webhook-skill description: Start an ngrok tunnel to receive incoming webhooks and process them via the LLM. Use when the user asks to listen for webhooks, set up a webhook endpoint, start ngrok, or when another skill (like Zoom RTMS Meeting Assistant) needs a public webhook URL. Receives webhook payloads and lets the LLM decide how to handle them.

Ngrok Webhook Listener

Start a public webhook endpoint via ngrok. Incoming webhooks are auto-routed to matching skills or presented to the user for manual handling.

Prerequisites

cd skills/ngrok-unofficial-webhook-skill
npm install

Environment Variables

Set in the skill's .env file (copy from .env.example).

Required:

Optional:

  • NGROK_DOMAIN — stable ngrok domain for consistent URLs
  • WEBHOOK_PORT — local port (default: 4040)
  • WEBHOOK_PATH — webhook path (default: /webhook)
  • OPENCLAW_BIN — path to openclaw binary (default: openclaw)
  • OPENCLAW_NOTIFY_CHANNEL — notification channel (default: whatsapp)
  • OPENCLAW_NOTIFY_TARGET — phone number / target for notifications

Usage

Start the webhook listener

Run as a background process:

cd skills/ngrok-unofficial-webhook-skill
node scripts/webhook-server.js

The server prints its public URL to stderr:

NGROK_URL=https://xxxx.ngrok-free.app
Webhook endpoint: https://xxxx.ngrok-free.app/webhook

For long-running use, launch with nohup:

nohup node scripts/webhook-server.js >> /tmp/ngrok-webhook.log 2>&1 &

What happens when a webhook arrives

  1. The server immediately responds 200 OK to the sender
  2. It discovers installed skills that declare webhookEvents in their skill.json
  3. Auto-routing (no user intervention needed):
    • If a matching skill has forwardPort → HTTP POST to the local service
    • If a matching skill has webhookCommands → runs the configured shell command
  4. Manual routing (user decides):
    • If no auto-route is available, sends a WhatsApp notification with the payload and a numbered list of matching skills
    • User replies with their choice

Skill discovery

Skills opt into webhook handling by adding webhookEvents to their skill.json:

{
  "openclaw": {
    "webhookEvents": ["meeting.rtms_started", "meeting.rtms_stopped"],
    "forwardPort": 4048,
    "forwardPath": "/"
  }
}

For command-based auto-handling (no running service required):

{
  "openclaw": {
    "webhookEvents": ["recording.completed"],
    "webhookCommands": {
      "recording.completed": {
        "command": "python3 scripts/download.py {{meeting_id}}",
        "description": "Download cloud recording",
        "meetingIdPath": "payload.object.id"
      }
    }
  }
}
  • command — shell command to run; {{meeting_id}} is replaced with the extracted value
  • meetingIdPath — dot-separated path to extract the meeting ID from the webhook payload
  • description — human-readable description for notifications

The ngrok skill scans all sibling skill folders for skill.json files with these fields.

Stdout output

The server also writes each webhook as a JSON line to stdout for process polling:

{
  "id": "uuid",
  "timestamp": "ISO-8601",
  "method": "POST",
  "path": "/webhook",
  "query": {},
  "body": {}
}

Health check

curl http://localhost:4040/health

Stop the listener

Kill the background process when done.

Integration with Zoom

Typical flow:

  1. Start this webhook listener → get ngrok URL
  2. Configure the ngrok URL in your Zoom Marketplace app's webhook settings
  3. When RTMS starts, Zoom sends meeting.rtms_started → auto-forwarded to the RTMS Meeting Assistant
  4. When RTMS stops, Zoom sends meeting.rtms_stopped → auto-forwarded, triggers cleanup
我的收藏