npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2026 – Pkg Stats / Ryan Hefner

@vrv-platform/vrv

v0.1.1

Published

OpenClaw VRV channel: HTTP entry for external messages, reply via Channel outbound (pushApi)

Readme

vrv-channel 插件

最小化 OpenClaw 渠道插件:通过官方 API 注册 HTTP 入口接收外部消息,OpenClaw 回复后通过 Channel 插件的 outbound 向外推送到业主侧的 HTTP 接口(pushApi)。

快速上手

部署和更新插件: 1.配置回调地址

openclaw config set channels.vrv '{
  "enabled": true,
  "pushApi": "http://39.99.149.198:8100/ai-app/api/v1/clawdbot/callback?clientId=vrvclowd",
}' --json
  1. 在openclaw的插件目录创建文件夹vrv
  2. 把源码上传到此文件夹
  3. 安装此本地插件,重启网关
openclaw plugins install -l /root/openclaw-assistant/openclaw/extensions/vrv
openclaw gateway restart

源码安装的服务器:

cd /home/openclaw
pnpm openclaw plugins install -l /home/openclaw/extensions/vrv
pnpm openclaw gateway restart
  1. 日志和验证

滚动查看最新日志

openclaw logs --follow

curl测试

curl -X POST "http://121.43.129.161:18789/vrv/message" -H "Content-Type: application/json" -d '{"text":"今天天气怎样"}'
curl -X POST "http://192.168.203.201:18789/vrv/message" -H "Content-Type: application/json" -d '{"text":"今天天气怎样"}'
curl -X POST "http://114.55.81.36:18789/vrv/message" -H "Content-Type: application/json" -d '{"text":"今天天气怎样"}'

插件如何工作(分层视角)

1. OpenClaw 边界层(index.ts)

  • 插件入口index.ts 只做两件事:
    1. api.registerChannel({ plugin: vrvPlugin }):注册 vrv 渠道(出站能力)。
    2. api.registerHttpHandler(handleVrvHttpRequest):注册 HTTP handler(入站能力)。
  • 这里完全只依赖 openclaw/plugin-sdk,不关心你业主系统的具体逻辑。

2. HTTP 入站层(monitor.ts)

  • HTTP 入口:使用 api.registerHttpHandler(handleVrvHttpRequest) 注册函数 (req, res) => Promise<boolean>
  • 路径POST /vrv/message
    • /vrv/message 的请求返回 false,交给其他插件处理;
    • POST 的请求返回 405
  • 请求体:JSON,例如
    { "text": "用户消息内容", "to": "可选目标ID", "sessionKey": "可选会话键" }
    其中:
    • text:必填,用户发给 Agent 的自然语言内容;
    • to:可选,业主侧定义的“用户或会话 ID”(默认 "default");
    • sessionKey:可选,会话键,用于区分多轮对话(默认等于 to)。
  • OpenClaw 调用流程
    1. runtime.config 解析出 vrv 账户配置(主要是 pushApi)。
    2. runtime.channel.routing.resolveAgentRoute 解析出要走哪个 Agent + Session:
      • channel: "vrv"
      • peer: { kind: "dm", id: to }
    3. runtime.channel.reply.formatAgentEnvelope / finalizeInboundContext 组装上下文 ctx
      • 包含 From/To/SessionKey/Provider/Surface/OriginatingChannel 等字段。
    4. 调用 runtime.channel.reply.dispatchReplyWithBufferedBlockDispatcher({ ctx, cfg, dispatcherOptions })
      • 由 OpenClaw 调度 Agent 执行;
      • 通过 dispatcherOptions.deliver 把 Agent 产出的回复交给下一层。

3. 业主侧出站层(channel.ts / sendVrvReply)

  • Channel outboundvrvPlugin.outbound.sendText 只是一个“适配器”,它会:

    1. 根据 ctx.accountId / ctx.cfg 调用 resolveVrvAccount 取出 pushApi
    2. 调用 sendVrvReply({ cfg, to, text, sessionKey, accountId })
  • 业主逻辑的核心只有一处sendVrvReply

    • 从账户配置中拿到 pushApi
    • fetch(pushApi, { method: "POST", body: JSON.stringify({ reply, to, sessionKey }) }) 推送到你的 HTTP 服务;
    • 日志统一走 console.log/console.error
  • pushApi 请求体:POST 的 JSON 形如
    { "reply": "Agent 回复内容", "to": "目标ID", "sessionKey": "会话键" }

总结:第 1、2 层完全是 OpenClaw 的集成代码;第 3 层只关心“给哪个 URL 发什么 JSON”,把业务逻辑压缩在 sendVrvReply 一处,便于今后替换为 MQ、内部网关等实现。

配置

在 OpenClaw 配置中增加渠道 vrv,并设置回复推送地址,例如:

channels:
  vrv:
    enabled: true
    pushApi: "https://your-server.com/webhook/reply"

多账户时可在 channels.vrv.accounts.<accountId>.pushApi 下为不同 account 配置不同 pushApi。

环境变量回退:若主配置中未设置 channels.vrv.pushApi,插件会读取环境变量 VRV_PUSH_APIOPENCLAW_VRV_PUSH_API 作为 pushApi(便于未改主配置时快速测试)。例如:

export VRV_PUSH_API="https://webhook.site/197b1f39-b58a-4db5-88d9-8e55ab3a1677"
# 再启动 OpenClaw

通过 curl 测试

前置:OpenClaw 网关已启动,且配置了 channels.vrv.pushApi(用于接收 Agent 回复的 webhook 地址)。将下面的 GATEWAY_URL 换成你的网关地址(如 http://localhost:3000)。

1. 测试入站:向 OpenClaw 发送一条消息

# 最简:只发文本
curl -X POST "${GATEWAY_URL}/vrv/message" \
  -H "Content-Type: application/json" \
  -d '{"text":"你好"}'

# 带目标与会话(可选)
curl -X POST "http://121.43.129.161:18789/vrv/message" \
  -H "Content-Type: application/json" \
  -d '{"text":"今天天气怎样","to":"user-001","sessionKey":"session-001"}'

成功时返回 200 且 body 为 {"ok":true}。若返回 4xx,body 中会有 error 说明(如缺少 text、未配置 pushApi 等)。

2. 测试出站:确认回复被推到 pushApi

需要有一个能接收 POST 的 URL 作为 pushApi,才能看到 Agent 的回复被推过去。

方式 A:用 webhook.site 收回复(无需自建服务)

  1. 打开 https://webhook.site,复制给你的唯一 URL(如 https://webhook.site/xxx-xxx-xxx)。
  2. 在 OpenClaw 配置里设置:
    channels:
      vrv:
        enabled: true
        pushApi: "https://webhook.site/你的唯一ID"
  3. 重启/重载 OpenClaw 后,用上面的 curl 发一条消息。
  4. 在 webhook.site 页面应看到一条 POST 请求,body 为 JSON:{"reply":"...","to":"...","sessionKey":"..."},其中 reply 为 Agent 的回复内容。

方式 B:用本地 nc 收回复(看原始请求)

# 终端 1:在 9999 端口监听一次 HTTP(只收一条就退出)
nc -l 9999

# 配置里 pushApi 填 http://你的本机IP:9999(网关能访问到的地址)
# 若网关也在本机,可填 http://127.0.0.1:9999

然后另开终端用 curl 向 /vrv/message 发消息;终端 1 会收到一次 POST 请求(含 HTTP 头和 JSON body)。

方式 C:用 Python 起一个最小 HTTP 服务收回复

# 终端 1:监听 9999,打印收到的 POST body
python3 -c "
from http.server import HTTPServer, BaseHTTPRequestHandler
import json
class H(BaseHTTPRequestHandler):
    def do_POST(self):
        n = int(self.headers.get('Content-Length', 0))
        body = self.rfile.read(n)
        self.send_response(200)
        self.end_headers()
        self.wfile.write(b'{}')
        print('Received POST:', json.loads(body))
HTTPServer(('0.0.0.0', 9999), H).serve_forever()
"

配置 pushApi: "http://127.0.0.1:9999"(或网关能访问的地址),再用 curl 发消息,终端会打印收到的 {"reply":..., "to":..., "sessionKey":...}

3. 常见错误对应的 curl 响应

| 现象 | 可能原因 | |------|----------| | 405 Method Not Allowed | 未用 POST 或路径不是 /vrv/message | | 400 + "error":"missing or empty text" | body 里没有 text 或为空 | | 400 + "error":"invalid payload" | body 不是合法 JSON 或不是对象 | | 503 + "error":"vrv pushApi not configured" | 未配置 channels.vrv.pushApi | | 503 + "error":"gateway routing or reply dispatcher not available" | 网关/Agent 未就绪或未正确加载插件 | | 503 + "error":"vrv pushApi not configured" | 未配置 pushApi:见下方「解决 pushApi 未配置」 |

解决 "vrv pushApi not configured"

在 OpenClaw 的配置文件(如 config.yaml 或环境/控制台里使用的配置)中增加 vrv 渠道并填写 pushApi,然后重启或重载 OpenClaw:

channels:
  vrv:
    enabled: true
    pushApi: "https://webhook.site/你的唯一ID"   # 或你的接收回复的 URL
  • 若用 webhook.site:打开 https://webhook.site,复制给你的唯一 URL,填到 pushApi
  • 若用本机服务:填 http://你的服务器IP:端口(网关能访问到的地址,例如 http://121.43.129.161:9999)。

保存配置并重启 OpenClaw 后,再用 curl 发消息即可。

目录结构

vrv/
├── openclaw.plugin.json   # 插件元信息与 configSchema
├── index.ts               # 入口:register 中 registerChannel + registerHttpHandler
├── README.md              # 本说明
└── src/
    ├── runtime.ts         # 保存 api.runtime,供 handler 与 channel 使用
    ├── accounts.ts        # vrv 账户解析(list/resolve/default)
    ├── channel.ts         # Channel 插件定义与 outbound(sendText → POST pushApi)
    └── monitor.ts         # HTTP handler:解析 /vrv/message,构造 ctx,调用 dispatchReplyWithBufferedBlockDispatcher

与官方 API 的对应关系

  • 注册 HTTP 入口:使用官方 api.registerHttpHandler(handleVrvHttpRequest),在 handler 内自行判断 path 与 method,符合则处理并返回 true,否则返回 false 交给其他插件或网关。
  • 接收外部消息:在 handler 中把请求体转成 OpenClaw 入站上下文,并调用 core.channel.reply.dispatchReplyWithBufferedBlockDispatcher,即按官方推荐方式把“外部消息”交给 OpenClaw 处理。
  • 回复通过 Channel 发出:通过同一插件的 Channel 定义中的 outbound.sendText,以及在 dispatcherOptions.deliver 中调用相同的推送逻辑(POST 到 pushApi),实现“OpenClaw 回复后通过 Channel 插件向外发送或调用外部 API”。

参考

  • OpenClaw 文档:https://docs.openclaw.ai
  • 参考实现:本仓库中 pluginCodeForReference/googlechat(HTTP handler + Channel)、pluginCodeForReference/clawdbot-feishu(Channel + outbound)