dsh-qq-link
Bridges a DSH session and QQ over NapCat HTTP, forwarding agent replies to QQ and feeding messages you send in QQ back into the session.
Install
dsh plugin --profile web add dsh-qq-link
Sandbox test results
| Stage | Result |
|---|---|
| 1 install | ✓ |
| 2 list | ✓ |
| 3 mount | ✓ |
| 4 boot | — |
Four stages run in an isolated sandbox: install (network on) → list → mount → boot (last three with no network).
README
通到 QQ(dsh-qq-link)
让 DSH 里的 AI 伙伴和 QQ 连起来:它在 DSH 里说完话,自动发到 QQ。
现在两半都做出来了,而且都不用 BOT:
- DSH → QQ:伙伴说话 → 发到 QQ。
- QQ → DSH:你在 QQ 里发话,插件自己轮询那个 QQ 后端收进来 → 转进 DSH。只要一个后端就够。
现在的行为
- 盯两间屋(都可以选,也可以只选一间):私聊会话 和 群会话。
QQ 私聊进来的话进私聊那间,群里的话进群那间;哪间屋说的话就只回那一边(私聊的话不会跑到群里)。
两行选了同一间屋也能用,但那就等于「两边都发」——设置页会当场提示。
DSH → QQ:它在某一整轮的最后一句说完,就把这句原文发到 QQ(走 QQ 后端的3000)。QQ → DSH:插件每 4 秒轮询 QQ 后端(get_friend_msg_history/get_group_msg_history),
发现你在 QQ 里新发的消息 → 转进目标会话,让它照常开一轮。
- 发/收都只走这个 QQ 后端的 HTTP 接口(默认
127.0.0.1:3000)。 - 语音条也能变成字(可选):设置里填一条「读
{file}打一行字」的命令,QQ 语音就会被转写成文字;插件本身不带模型,仓库里附了tools/asr_cli.py(SenseVoice)。 - 收进来的东西不只有文字:图片、表情包、
@某人、分享卡片(B站 视频卡片会把标题和 BV 号写出来)、
合并转发的聊天记录(会去取内容压成「谁:说了什么」几行;里面还套着转发也会展开,最多 2 层)都会变成文字转给它。
转发里的图跟着「收图」开关走:开着就收第一层那几张(跟顶层图共用张数上限),关着只记 [图片];第二层起一律只记 [图片]。
- 图片两个方向都能传:你在 QQ 里发的图会转给它看;它这一轮里发的图也会发到 QQ。
收进来的图会在 ~/.dsh/qq-bridge-inbox/ 存一份,文字里带上路径。
回发同一张图时用的是这份原图 —— DSH 自己那份副本会被重新编码,GIF 动图会变静态 webp。
- 正文里写的 markdown 图也算:它写
(贴纸就是这么发的),
会被读成本地图片发到 QQ,那串 markdown 不会露出来。相对路径按「图片根目录」找 —— 留空就行,会自动用目标会话所在的那个工作区。
⚠️ 它到底能不能看见图,取决于那个会话用的模型:能看图的模型直接看,纯文本模型只会收到一句占位文字。
- 安全默认:总开关 = 关、试运行 = 开 —— 不手动打开,一句都不会真的发到 QQ。
- 回复门槛(可选,默认关):开着时 QQ 消息照常转进来,但会先让它判断「这条是不是在跟我说话」——
不是就当场把这一轮停掉(agent.cancel),什么都不回。群里特别省心。工具只在「被 QQ 叫醒后的 10 分钟内」有效,
她自己在 DSH 里聊天时关不掉自己那一轮。
- 被点名之后会接着听几句:群里默认是「只收点了名的」,可点了名之后的正题往往在后面几句里。
所以有人 @ 它或者引用它的话之后,同一个群里后面紧跟着的普通消息也会转进来;
接够条数或者过了时间就自己停,退回「只听点名」。
两个数在设置 →「提示与门槛」:点名之后接着听几条(默认 5,范围 0~50,填 0 = 关掉这个功能)、
接着听多少秒(默认 120,范围 0~600)。
接听期间进来的话不算点名,不会把条数又加回去,也不影响「点名必回」那套判定;
状态是每个群各记一份的,A 群在接听不影响 B 群,私聊完全不受影响。
适配哪个 DSH 版本(不用操心)
这个插件跟着 DSH 一起更新:作者这边跑的就是最新版的 DSH,最新版插件永远是给最新版 DSH 写的。
所以看到「不适配 / 不支持」之类的提示,基本都是装到了旧版本 —— 升级到最新版、重启一次 DSH 就好。
真遇到新版对不上(比如 DSH 刚升级、插件还没跟上),提个 issue,作者会跟着改。
实测对照 / 兼容范围看 [package.json](package.json) 里的 engines 和 dsh.compatibility;
这一版改了什么看 [CHANGELOG.md](CHANGELOG.md),发版记录看 Releases。
这里不写死版本号 —— 文档里钉一个数,过两天就对不上了。
装
⭐ 最省事的一条:把这个仓库的地址贴给你自己的 DSH,说「帮我装这个插件」。
一、在 DSH 里装(推荐)
打开 设置 → 插件 → 安装,把这一行填进去:
github:Yuuyuko-uu/dsh-qq-link
或者命令行(--profile 照你平时那个写,桌面端一般 desktop,网页端 web):
dsh plugin --profile desktop add github:Yuuyuko-uu/dsh-qq-link
装完重启一次 DSH,然后进 设置 → 通到 QQ。
⚠ 用 github: 这种写法装的时候,包管理器会去 clone 仓库,所以那台机器上得有 git。
没装 git 会报 ERR_PNPM_GIT_FETCH_FAILED。这种情况改用 tarball 直链,不用 git:
```bash
dsh plugin --profile desktop add https://codeload.github.com/Yuuyuko-uu/dsh-qq-link/tar.gz/refs/heads/main
```
(设置 → 插件 → 安装 那个框里也可以直接填这行地址。)
光装插件还不够:还得有一个 QQ 后端(默认 127.0.0.1:3000),见下面「它依赖什么」那一节。
二、装完起不来?先看这个
如果 DSH 弹「The application could not start」,错误里有 Unexpected token ''、is not valid JSON、
readProfileManifest —— 那是 profile 的 package.json 被存成了 UTF-8 带 BOM。
跟插件无关:文件内容都是对的,只是开头多了三个看不见的字节,DSH 读它就崩。
先找出来(不同装法位置不一样,别猜 —— 真正的 profile 目录里同时有 cordis.yml、cordis.patch.yml、package.json;机器上别处那些同名的都不算):
Get-ChildItem C:\,D:\,E:\ -Directory -Filter profiles -Recurse -Depth 4 -ErrorAction SilentlyContinue |
ForEach-Object {
Get-ChildItem $_.FullName -Directory -ErrorAction SilentlyContinue | ForEach-Object {
$p = Join-Path $_.FullName 'package.json'
if ((Test-Path (Join-Path $_.FullName 'cordis.patch.yml')) -and (Test-Path $p)) {
$b = [System.IO.File]::ReadAllBytes($p)
$bom = ($b.Length -ge 3 -and $b[0] -eq 0xEF -and $b[1] -eq 0xBB -and $b[2] -eq 0xBF)
"{0} BOM={1}" -f $p, $bom
}
}
}
输出里 BOM=True 的那一行,就是要修的文件(标准安装在 C:\Users\<你>\.dsh\profiles\<档名>\package.json)。
去掉 BOM(路径换成上面那一行):
$p = "把上面 BOM=True 那一行的路径粘到这里" [System.IO.File]::WriteAllText($p, [System.IO.File]::ReadAllText($p), (New-Object System.Text.UTF8Encoding($false)))
然后重启 DSH 就好,数据一点没丢。
实在进不去时,那个错误框里的
「Disable third-party plugins, back up profile patch, and restart」
能先起来(它先备份再停插件),再一个个开回去定位。
⚠️ 手动改 profile 里的文件,一律存 UTF-8 无 BOM。让 AI 帮你改时,别让它用
Set-Content -Encoding UTF8或Out-File -Encoding utf8(Windows 自带的这两个默认带 BOM),
用上面那行 .NET 的写法就不会。
更新到最新版
最省事:把这个仓库的地址丢给你自己的 DSH,说「帮我更新这个插件」。装完重启一次 DSH。
也可以点 设置 → 通到 QQ 最上面的「检查更新」 —— 有新版会提示,还能一键复制更新命令。
命令行(--profile 照你平时那个写,桌面端一般 desktop、网页端 web):
dsh plugin --profile desktop remove dsh-qq-link dsh plugin --profile desktop add github:Yuuyuko-uu/dsh-qq-link
⚠️ 必须先卸再装:直接装可能拿到缓存里的旧副本,装完还是老的。
⚠️ 装完重启一次 DSH才会用新代码。
我的设置会不会丢?
不会。 设置存在 DSH 家目录(%USERPROFILE%\.dsh\)里,不在插件代码里;卸载只删代码:
.dsh\qq-bridge-config.json (还有 qq-bridge-inbox\ 里收到的图)
所以卸载 → 重装,设置、收到的图片、转发记录 都还在。
三件小事提醒:
- 别用「重装 DSH」来更新插件 —— 那是两件事,重装可能动到 profile。
- 新版本新加的设置项会用默认值(以前没这一项),想要自己的值就再填一次。
- 设置项改名或换单位时,旧值会按规则自动换算,不用你管。
配置(设置页里点就行,不用改文件)
设置 → 通到 QQ,从上到下:
项 · 默认 · 说明
总开关 · 关 · 关着 = 一句都不发
试运行 · 开 · 开着只记账,不真发
目标会话 · (没选) · 下拉里选你自己要的那一间,不用手填 id
转私聊 / 私聊 QQ 号 · 开 / 空 · 发到哪个私聊
转群 / 群号 · 关 / 空 · 发到哪个群
收图(QQ → 它) · 开 · 你在 QQ 里发的图也转给它。文字里带本地备份路径
发图(它 → QQ) · 开 · 它这一轮里发的图也发到 QQ
一条最多收几张 · 4 · 1–10,多出来的不转
单张最大(MB) · 5 · 超过就跳过,两个方向共用
点名之后接着听几条 · 5 · 0–50。被 @ / 被引用之后,同一个群紧接着的几句话也转进来;0 = 关掉这个功能
接着听多少秒 · 120 · 0–600。到点就停,就算条数还没接完(填 0 只剩点名那一条能进来)
允许发 QQ 空间动态 · 关 · 只影响发说说;看说说、看好友动态不受它管。见下面「QQ 空间」那一节
测试一句 · — · 真发一条测试句到已填的私聊/群(绕过试运行)
配置文件落在 %USERPROFILE%\.dsh\qq-bridge-config.json(一般不用碰它)。
QQ 空间(可选)
绑了 QQ 的那几间会话会多出四个工具。它们走的就是上面那个后端地址和令牌,不用另填一套
(SnowLuma 2.0.0 原生就有这些动作,NapCat 也有同族接口 —— 前提是你的后端真的支持)。
工具 · 能干什么
qq_space_list · 看某个号的说说(不填 QQ 号 = 机器人自己):总共多少条;每条带时间、正文(长的会截断)、评论数、是不是私密、带几张图。每条前面有 tid,后面那个工具要用
qq_space_detail · 看一条说说的正文,加一页评论(谁说的、什么时候)
qq_space_feeds · 好友动态流:谁发的、什么时候、说了什么。里面的 HTM
…(truncated)
Rendered from the README published on npm. Formatted only, not edited.
Versions
Published on npm::9,最后更新 2026-11-06