@vclaw/linkdood
v0.1.2
Published
OpenClaw Linkdood channel plugin for inbound HTTP messaging and outbound websocket, webhook or SSE replies
Readme
@vclaw/linkdood
OpenClaw linkdood 渠道插件,用来把 Linkdood 消息接入 OpenClaw,再把 Agent 回复送回 Linkdood。
当前代码已经拆成两层:
- 插件层:负责 OpenClaw 运行时接入、路由、SSE、webhook、原生 websocket、日志和账号配置
- SDK 层:负责密信 DDIO 初始化、Socket.IO 建连、消息解码、消息发送
插件不会直接创建、也不会直接导入 socket.io-client,这部分已经收进独立 SDK @vrv-platform/linkdood-sdk。
兼容性
openclaw >= 2026.3.23
出站链路
插件现在支持四条链路:
sdk当配置了channels.linkdood.sdk.server、appId、appSecret时启用。 插件会先调 SDK 初始化 DDIO,再由 SDK 用 Socket.IO 建立连接。websocket原生 websocket realtime connector,适合兼容老的 Linkdood websocket 服务。SSE外部客户端订阅GET /linkdood/stream?sessionKey=<sessionKey>。webhook兜底回调到webhookUrl。
回复时的实际优先级:
sdkwebsocketSSEwebhook
也就是说:
- 配了
sdk.server时,优先走 SDK 这条第四类链路 - 没配
sdk.server时,继续走原有websocket、SSE、webhook
入站链路
插件接收入站消息有三种方式:
POST /linkdood/message- 原生
websocket sdk
其中 sdk 模式下的完整流程是:
- 插件发现账号配置了
channels.linkdood.sdk.server gateway.startAccount调用src/linkdood/realtime.tsrealtime-sdk.ts调用src/linkdood/client.ts- client 调用
@vrv-platform/linkdood-sdk的公开 API - SDK 调 DDIO 初始化接口,拿到
endpoint、短期token、expiresAt、namespace - SDK 自己创建
socket.io-client - SDK 用
token + appId建连,发送sys.init - 收到
sys.connected后认为连接完成 - SDK 收到业务消息后,先解码成统一结构
src/linkdood/linkdood-sdk.ts把 SDK 入站转换成插件内部入站格式- monitor 再继续后面的 OpenClaw 入站处理流程
目录结构
关键目录如下:
packages/linkdood-sdk面向所有 Node.js 调用方的独立 SDKsrc/linkdoodLinkdood 相关代码,其中realtime.ts负责总入口分流,realtime-native.ts负责原生 websocket,realtime-sdk.ts负责 SDK 链路,client.ts负责创建连接,linkdood-sdk.ts负责 OpenClaw 和独立 SDK 的桥接src/httpwebhook、SSE 和 HTTP 入站编排src/outboundOpenClaw 回复消息、结构化动作和最终选路
安装
openclaw plugins install @vclaw/linkdood
openclaw gateway restart插件会注册:
POST /linkdood/message
GET /linkdood/stream配置
推荐使用 CLI:
openclaw config --section channels原生三链路模式
如果你不配置 channels.linkdood.sdk.server,插件继续按原有方式工作:
- 收消息:
POST /linkdood/message- 原生
websocket
- 回消息:
- 原生
websocket SSEwebhook
- 原生
相关配置:
webhookUrlwebsocket.enabledwebsocket.urlwebsocket.headers
SDK 模式
如果你配置了:
channels.linkdood.sdk.serverchannels.linkdood.sdk.appIdchannels.linkdood.sdk.appSecret
插件会把这个账号切到 SDK 模式:
- 入站由 SDK 的 Socket.IO 连接接收
- 回复和结构化动作也由 SDK 连接发送
- 不再依赖插件里原生 websocket 的协议包装
SDK 相关可选配置:
sdk.rejectUnauthorized是否验证 SSL 证书,默认true;开发环境自签名证书可设为falsesdk.ddioInitPathDDIO 初始化路径,默认/platform/api3/ws/ticketsdk.socketInitEvent默认sys.initsdk.socketConnectedEvent默认sys.connectedsdk.replyEvent默认message.replysdk.actionEvent默认message.action
其他常用配置
signingSecret统一签名密钥capabilities结构化能力声明directoryApi目录查询接口groupPolicy群消息接入策略groupAllowFrom群消息 allowlistgroupRequireMention群里是否必须 mentiongroupToolPolicy群工具权限defaultAccount默认账户accounts多账户配置
开发说明
当前代码里和 SDK 相关的边界是:
packages/linkdood-sdk/src/index.ts纯 SDK,对所有 Node.js 项目开放src/linkdood/realtime.ts账户级监听总入口,对标飞书monitorFeishuProvidersrc/linkdood/realtime-native.ts只处理原生 websocket 链路src/linkdood/realtime-sdk.ts只处理 SDK Socket.IO 链路src/linkdood/client.tsLinkdood 连接创建层,只负责创建 SDK/原生 websocket 连接,不直接依赖socket.io-clientsrc/linkdood/linkdood-sdk.tsOpenClaw 适配层,只负责把 SDK 接到插件运行时src/outbound/push.ts统一决定回复最终走sdk、websocket、SSE还是webhook
当前代码里的“realtime”语义特指两类长连接:
- 原生
websocket - SDK
socket.io
对应的运行时方法已经统一使用 realtime 命名,例如:
countLinkdoodRealtimeConnectionsresolveLinkdoodActiveRealtimeModepublishLinkdoodRealtimeReply
依赖约束
为了保持边界稳定,当前仓库约定:
- 插件
src/目录禁止直接依赖或导入socket.io-client socket.io-client只能存在于packages/linkdood-sdk- 插件只能通过
@vrv-platform/linkdood-sdk的公开 API 使用 SDK 能力
文档索引
- 服务端对接说明:docs/对接linkdood服务端说明.md
- 手动 JSON 配置:docs/MANUAL_CONFIG.md
- 本地开发和联调:docs/DEVELOPMENT.md
- 独立 SDK 文档:packages/linkdood-sdk/README.md
