dsh-messaging
v0.1.2
Published
DSH 消息渠道网关:自动注册并激活 dsh-messaging 动态 Cordis 插件
Maintainers
Readme
dsh-messaging
DeepSeek Harness(DSH)/ DeepRein 的外部 IM 消息渠道网关。这是一个合规的 DSH 插件,内部通过启动壳自动注册并激活 动态 Cordis 插件,负责把外部即时通讯平台的消息接入 DSH 的 agent 会话,再把 agent 的回复发回原平台。
架构链路
外部平台与 agent 之间的数据流如下(各渠道适配器完成入站/出站协议转换):
外部平台(QQ/Telegram/Discord/Slack/飞书/企微/个人微信)
│ 入站消息(HTTP webhook / 长轮询 / WebSocket / 扫码)
▼
dynamic/host.js 适配器(adapter)
│ inbound(): 按 channel + conversation 创建或复用 agent 会话
▼
DSH agent 会话(ensureAgent)
│ agent.followup(...)
▼
agent 回复 → assistant/message 累计到 turnBuffer
│ turn/end 时
▼
sendOutbound() → adapter.sendText() → 回发原平台核心实现见 dynamic/host.js:inbound()/ensureAgent()/sendOutbound()/
flushReply()/onSessionEvent()(约 500-630 行),CHANNEL_DEFS 定义了支持的渠道(约 1-9 行)。
支持的渠道
| 渠道 | key | 入站方式 | 成熟度 | 有自动化测试 |
|------|-----|----------|--------|--------------|
| OneBot v11 | onebot | HTTP webhook | ✅ 可用,收发闭环 | ✅ 有 smoke 测试 |
| Telegram | telegram | 长轮询 / webhook | ⚠️ 代码完整,无测试 | ❌ |
| Discord | discord | WebSocket Gateway(伴随进程) | ⚠️ 代码完整,无测试;依赖 ws 模块 | ❌ |
| Slack | slack | Events API webhook | ⚠️ 代码完整,无测试;不校验签名 | ❌ |
| 飞书 / Lark | lark | Events API webhook | ⚠️ 代码完整,无测试 | ❌ |
| 企业微信 | wecom | 加密回调 | ⚠️ 代码完整,无测试 | ❌ |
| 个人微信 | wechat | 腾讯 iLink Bot API(长轮询 + 扫码登录) | ⚠️ 最新实现,无测试 | ❌ |
请勿把各渠道当作同等可用。 目前仅有 OneBot v11 有完整的 smoke 测试闭环; 其余六个渠道代码完整但未经自动化验证,上线前务必自行实测。
各渠道实现说明
- OneBot v11(
host.js:763-823):webhook 收消息,send_group_msg/send_private_msg发消息;带accessToken时用 Bearer 认证;从事件self_id做回显抑制(不依赖配置里的selfId)。 - Telegram(
host.js:826-907):getUpdates长轮询或本地 webhook 路由;webhook 模式只注册了 本地路由,并未调用 TelegramsetWebhook,需要你自行在外网网关把 webhook 转发到该路径。 - Discord(
host.js:910-967+companion/discord-gateway.cjs):通过伴随 Node 子进程维护 WebSocket Gateway。注意:companion/discord-gateway.cjs会require('ws'),但本包并未 声明ws运行时依赖——需要通过runtime.wsModulePath或渠道wsModulePath指向一个含ws的node_modules,否则无法运行。 - Slack(
host.js:970-1006):Events API。不校验signingSecret/verificationToken, 任何能访问该 webhook 地址的请求都会被当作入站消息处理,属安全风险。不要把 Slack webhook 暴露到公网;如需公网接入,请在前面加一层网关做签名校验。 - 飞书 / Lark(
host.js:1010-1084):Events API,支持encryptKey加密与verificationToken校验;解密走companion/crypto-helper.cjs。 - 企业微信(
host.js:1086-1168):加密回调,走companion/crypto-helper.cjs做签名校验与 AES 解密;支持echostr验证与文本消息。 - 个人微信(
host.js:1170-1389):腾讯 iLink Bot API(与 openclaw-weixin 同一协议), 含扫码登录(/ilink/bot/get_bot_qrcode+get_qrcode_status),长轮询收消息,sendmessage发消息;带上下文 token 与会话恢复。
使用与安装方式
安装到 DSH Web Profile
在 DSH 环境中运行以下命令安装:
dsh plugin --profile web add <本地目录路径|tgz|包名>安装完成后,需重启 DSH 宿主服务以应用 patch 并加载插件。
加载原理
本包声明了 dsh.bundle.patch(cordis.patch.yml),宿主启动时自动加载 lib/index.js 启动壳。启动壳会在宿主服务(agents / dynamicCordisRunner)就绪后将 dynamic/host.js 与 dynamic/client.js 注册为动态插件,并自动激活 Host 半区(消息收发在后台正常工作),同时将伴随脚本同步至 ~/.dsh-messaging/companion。
关于 Client 半区(设置页与状态面板):受官方 Cordis 动态插件安全模型限制,Client 前端代码无法从 Host 后端静默自动运行。如需使用图形化配置页面与状态面板,需在 DSH Web UI 左下角、设置上方的 Cordis 插件面板中运行 Client 半区。
关于
dynamic/manifest.json:该文件是本项目自用的元数据描述文件(记录 host/client 源码与配置模板映射),非 DSH 官方规范读取项。
配置说明
完整配置模板见 config.example.json。首次运行时由启动壳在 ~/.dsh-messaging/config.json 自动生成。
字段定义见 dynamic/client.js:11-58(含中英文标签)。
| 配置块 | 关键字段 | 说明 |
|--------|----------|------|
| version | 1 | 配置结构版本 |
| workspaceRoot | 路径 | DSH 工作区根目录(默认用户主目录) |
| runtime | nodePath / wsModulePath / companionDir | 子进程用 node 路径、Discord 用 ws 模块路径、伴随脚本目录 |
| runtime | pollIntervalMs / telegramLongPollTimeoutSec / shellTimeoutMs / stdoutMaxBytes | 轮询间隔、Telegram 长轮询超时、子进程超时、stdout 上限 |
| agent | cwd / agentPreset / provider / model | agent 工作目录、预设、模型提供方与模型(可空则用 DSH 默认) |
| adapters.<channel> | 各渠道字段 | 见下方渠道字段与 dynamic/client.js:11-58 |
各渠道常用字段(按渠道,均为 adapters.<key> 下):
onebot:endpoint、accessToken、webhookPathtelegram:token、mode(polling/webhook)、webhookPath、pollIntervalMs、longPollTimeoutSec、dropPendingUpdatesdiscord:botToken、intents、wsModulePathslack:botToken、signingSecret、verificationToken、webhookPathlark:appId、appSecret、verificationToken、encryptKey、webhookPathwecom:corpId、agentId、secret、token、encodingAESKey、webhookPathwechat:token、baseUrl、botAgent、pollIntervalMs、longPollTimeoutSec
⚠️ 已废弃 / 不再读取的配置字段
以下字段当前不被 host 读取,写入后不会生效,建议不要配置以免误导:
- OneBot 的
selfId:host 实际从入站事件的self_id动态做回显抑制(host.js:785-787), 配置里的selfId只保留在设置页定义中(client.js:16),不被startOnebot使用。 - WeChat 的
driver/collectPath/sendTextPath/postTextPath/appId:host 的 WeChat 适配器(host.js:1170-1217)实际只读取baseUrl/token/botAgent/pollIntervalMs/longPollTimeoutSec,其余字段是历史遗留配置,不再使用。
注意区分:
appId在 WeChat 渠道已废弃,但在 Lark 渠道(host.js:1014)仍是有效必填字段。
目录结构
dsh-messaging/
├── package.json 包元数据与 DSH bundle patch 声明
├── cordis.patch.yml Cordis profile patch 定义
├── lib/ 包入口
│ └── index.js 启动壳(同步伴随脚本、等待服务、动态定义与激活)
├── dynamic/ 插件本体(动态注入)
│ ├── host.js 宿主逻辑(1567 行):HTTP 路由、各渠道适配器、RPC、agent 会话
│ ├── client.js 设置页与状态面板(758 行),含渠道字段定义与中英文案
│ └── manifest.json 动态插件描述元数据
├── companion/ Node CJS 伴随脚本,由 host 通过 node 子进程调用
│ ├── crypto-helper.cjs 企业微信签名/AES 解密、Lark 解密
│ └── discord-gateway.cjs Discord WebSocket Gateway 维护
├── test/ 手动运行的 smoke 工具
│ ├── host-smoke.cjs 宿主逻辑 smoke 测试(Node 验证可通过)
│ ├── client-smoke.cjs 设置页 smoke 测试(Node 验证可通过)
│ └── fake-bot-server.cjs 可模拟 OneBot / Telegram 的假 bot 服务(无自动编排脚本)
├── config.example.json 配置模板
└── config.json 本地运行配置(用户级示例,非提交)测试运行方法
测试为手动运行的 smoke 工具,无测试框架、无自动编排脚本:
node test/host-smoke.cjs # 宿主逻辑 smoke 测试
node test/client-smoke.cjs # 设置页 smoke 测试已知限制
- 仅 OneBot v11 有自动化 smoke 覆盖;其余渠道未经测试,功能可能有偏差。
- Client 前端界面需手动运行:Host 后端消息网关随宿主启动自动在线,但设置页/状态面板(Client 半区)受官方安全模型限制无法静默自动拉起,需在 DSH Web UI 左下角、设置上方的 Cordis 插件面板中运行。
- Slack 不校验入站签名,切勿直接暴露公网。
- Telegram webhook 模式只注册本地路由,需自行配置到 Telegram 的 webhook 转发。
- Discord 依赖
ws,但本包未声明该运行时依赖,需通过runtime.wsModulePath指向可用的ws(若未找到则 Discord 不可用,其余渠道不受影响)。 - 入站目前以文本消息为主(OneBot 含群聊/私聊区分),媒体、语音、文件等暂未处理。
- 个人微信走 iLink Bot API,属协议逆向接入,稳定性与官方接口一致,可能有波动。
