🎁 福利专区全网大模型免费应用 + 新用户福利 + 注册活动入口,低成本玩转 AI

QQ群聊扩展 jjjjjsgrmjjjjj/dsh-qq-plugin-group-expand

DeepSeek Harness
jjjjjsgrmjjjjj11 天前有提交已提供中文文档扫描:含敏感能力

让 QQ 群成为远程操控与对话的入口

30.8/100
综合分
1
GitHub 星标
—
npm 周下载
—/5
用户评分

数据截至 2026/10/24 · 周下载取自 npm 全网(含 CI / 镜像),非本站安装数;综合分由星标、活跃度与兼容性检查合成。

安装命令 · 需先装 dsh CLI 引擎
dsh plugin --profile web add jjjjjsgrmjjjjj/dsh-qq-plugin-group-expand
该包不可直接 npm 安装,改从 GitHub 源安装(明细见下方安装检查)

状态速览

判定依据:实装验证 · 静态安装检查 · 自动扫描 · 仓库维护状态
信任档位:仅索引
是什么
dsh 原生插件 · platform
装得上吗
本站尚未做安装检查
L4 · 真实安装等级说明 →
安全吗
本站尚未对该插件做风险分级
暂未覆盖,不等同于无风险
还在维护吗
活跃:最近一次提交在 11 天前
档位由哪些信号合成

本站实装验证(真实安装 L4 覆盖全站;L5 为运行时冒烟或实机截图,覆盖范围小于 L4) · 验证所用 dsh 版本 · 静态安装检查 · 风险分级 · 仓库维护状态。 下方各区块是它的证据明细。

验证判据与等级说明 →
社区实装还没有人打卡 · 装过的第一个就是你
安全扫描自动 · 静态分析源码
v2.7.0
🔵 扫描:含敏感能力尚无人工评估
展开查看扫描说明与证据 ↓

静态扫描发现插件具备触达本地系统的能力:执行外部命令、读写/删除本地文件、读取剪贴板或密钥类环境变量(至少其一)。这是能力清单,不是危险判定——具体能力项与证据见下方,安装前请自行判断是否需要。

读写/删除本地文件发起外部网络请求
查看扫描证据(共 39 处,展示前 39 条)
  • 发起网络请求
    client.js:165
    void fetch(`${PREFIX}/client-error`, {
  • 发起网络请求
    client.js:593
    const response = await fetch(path, {
  • 写入本地文件
    lib/log.js:46
    mkdirSync(dirname(logFile), { recursive: true })
  • 写入本地文件
    lib/log.js:70
    appendFileSync(logFile, line)
  • 读取本地文件
    lib/log.js:79
    if (statSync(logFile).size <= MAX_LOG_BYTES) return
  • 写入本地文件
    lib/log.js:84
    renameSync(logFile, `${logFile}.1`)
  • 写入本地文件
    lib/paths.js:73
    mkdirSync(workspace, { recursive: true })
  • 写入本地文件
    lib/paths.js:88
    mkdirSync(join(home, WORKSPACE_DIR_NAME), { recursive: true })
  • 写入本地文件
    lib/paths.js:101
    mkdirSync(join(home, STATE_DIR_NAME, 'stickers'), { recursive: true })
  • 写入本地文件
    lib/paths.js:187
    mkdirSync(dir, { recursive: true })
  • 写入本地文件
    lib/paths.js:189
    writeFileSync(probe, 'ok', 'utf8')
  • 删除本地文件
    lib/paths.js:190
    rmSync(probe, { force: true })
  • 写入本地文件
    lib/runtime.js:2410
    writeFileSync(path, plan.text, 'utf8')
  • 读取本地文件
    lib/runtime.js:3318
    if (!existsSync(entry.path)) {
  • 读取本地文件
    lib/runtime.js:3360
    info = statSync(path)
  • 读取本地文件
    lib/routes.js:225
    const text = readFileSync(logPath(), 'utf8')
  • 写入本地文件
    lib/media.js:73
    mkdirSync(dir, { recursive: true })
  • 发起网络请求
    lib/media.js:177
    const response = await fetch(url, { signal: AbortSignal.timeout(30_000) })
  • 写入本地文件
    lib/media.js:193
    writeFileSync(path, data)
  • 读取本地文件
    lib/session-index.js:122
    const raw = await readFile(join(storeDir, name), 'utf-8')
  • 读取本地文件
    lib/session-index.js:174
    const entries = await readdir(root, { withFileTypes: true })
  • 读取本地文件
    lib/session-index.js:281
    await stat(join(indexDir, name))
  • 读取本地文件
    lib/session-index.js:291
    const entries = await readdir(join(home, 'sessions', folder), { withFileTypes: true })
  • 读取本地文件
    lib/stickers.js:190
    for (const entry of readdirSync(folder, { withFileTypes: true })) {
  • 读取本地文件
    lib/stickers.js:207
    const parsed = JSON.parse(readFileSync(join(collectedDir, COLLECTED_INDEX_NAME), 'utf8'))
  • 写入本地文件
    lib/stickers.js:217
    writeFileSync(
  • 写入本地文件
    lib/stickers.js:241
    mkdirSync(collectedDir, { recursive: true })
  • 读取本地文件
    lib/stickers.js:261
    buffer = readFileSync(downloaded.path)
  • 删除本地文件
    lib/stickers.js:270
    unlinkSync(downloaded.path)
  • 读取本地文件
    lib/stickers.js:279
    if (existsSync(target)) {
  • 删除本地文件
    lib/stickers.js:281
    unlinkSync(downloaded.path)
  • 写入本地文件
    lib/stickers.js:289
    renameSync(downloaded.path, target)
  • 删除本地文件
    lib/stickers.js:306
    unlinkSync(join(collectedDir, oldest.file))
  • 读取本地文件
    lib/stickers.js:316
    bytes = statSync(target).size
  • 读取本地文件
    lib/state.js:316
    text = await readFile(this.#file, 'utf8')
  • 写入本地文件
    lib/state.js:331
    renameSync(this.#file, `${this.#file}.corrupt`)
  • 写入本地文件
    lib/state.js:379
    mkdirSync(dirname(this.#file), { recursive: true })
  • 写入本地文件
    lib/state.js:386
    writeFileSync(temp, `${JSON.stringify(state, null, 2)}\n`, { mode: 0o600 })
  • 删除本地文件
    lib/state.js:414
    unlinkSync(temp)
扫描于 2026/11/2(1 天前) · 范围 入口闭包 + 发布文件清单 · 来源 GitHub 仓库

静态扫描只反映源码中出现的调用,不构成安全背书;人工评估与自动扫描相互独立、互不覆盖。

给这个插件打分还没有人投票↓
用户评分
还没有人投票,来当第一个

README

由 DeepSeek 最新模型翻译生成
dsh-qq-plugin-group-expand 把 QQ 变成 DeepSeek Harness(DSH)的远程入口,并在上游 dsh-qq-plugin 的基础上补上群聊能力。 本项目是基于 xcisxc29/dsh-qq-plugin 的扩展分支,不是从零重写。私聊遥控、扫码绑定、多会话、附件、审批、主动推送等能力来自上游;本仓库的增量集中在群聊、群聊礼仪、引用图片、表情包、权限默认值与 token 优化。 - 包名:dsh-qq-plugin-group-expand - 当前版本:1.2.0 - 运行环境:DSH desktop 0.2.0-rc.2 或更新版本 - QQ 侧:腾讯官方机器人,扫码创建;不使用个人号协议,不需要公网 IP 与上游的关系 | 项目 | 上游 dsh-qq-plugin | 本仓库 | | 私聊遥控 | ✅ | ✅ 继承 | | 扫码绑定 / 凭据服务 | ✅ | ✅ 继承 | | 多会话与 /new /list /switch | ✅ | ✅ 继承 | | 图片 / 文件 / 语音 | ✅ | ✅ 继承 | | 权限审批回流 | ✅ | ✅ 继承 | | notify_qq 主动推送 | ✅ | ✅ 继承 | | 群聊收发 | ❌ | ✅ 新增 | | 群聊人格门禁 / 5 分钟连续对话 | ❌ | ✅ 新增 |
展开完整文档(README 剩余 1 节)
dsh-qq-plugin-group-expand

把 QQ 变成 DeepSeek Harness(DSH)的远程入口,并在上游 dsh-qq-plugin 的基础上补上群聊能力。

本项目是基于 xcisxc29/dsh-qq-plugin 的扩展分支,不是从零重写。私聊遥控、扫码绑定、多会话、附件、审批、主动推送等能力来自上游;本仓库的增量集中在群聊、群聊礼仪、引用图片、表情包、权限默认值与 token 优化。

- 包名:dsh-qq-plugin-group-expand
- 当前版本:1.2.0
- 运行环境:DSH desktop 0.2.0-rc.2 或更新版本
- QQ 侧:腾讯官方机器人,扫码创建;不使用个人号协议,不需要公网 IP

与上游的关系

| 项目 | 上游 dsh-qq-plugin | 本仓库 |
| 私聊遥控 | ✅ | ✅ 继承 |
| 扫码绑定 / 凭据服务 | ✅ | ✅ 继承 |
| 多会话与 /new /list /switch | ✅ | ✅ 继承 |
| 图片 / 文件 / 语音 | ✅ | ✅ 继承 |
| 权限审批回流 | ✅ | ✅ 继承 |
| notify_qq 主动推送 | ✅ | ✅ 继承 |
| 群聊收发 | ❌ | ✅ 新增 |
| 群聊人格门禁 / 5 分钟连续对话 | ❌ | ✅ 新增 |
| 群聊表情包收藏 | ❌ | ✅ 新增 |
| 引用消息中的图片 | 仅占位 | ✅ 下载后交本地路径 |
| 新会话默认只读 | 可配置 | ✅ 默认锁定只读 |
| 渠道说明 token 优化 | 每条重复 | ✅ 每个新会话只发一次 |

上游的完整用户手册、设置项和设计说明仍然适用,见 docs/HANDBOOK-USER.md。本 README 只写清“这个分支是什么、比上游多了什么、怎么装、边界在哪”。

功能概览

私聊

- 手机 QQ 扫码绑定官方机器人,之后一直有效;
- 一个 QQ 对话可对应多个 DSH 会话,支持 /new、/list、/switch、/current、/cancel、/help;
- 文字、图片、文件、语音双向;语音优先使用 QQ 服务端 ASR 转写;
- agent 的权限提示、二选一/多选提问可以回到 QQ,用「允许 / 拒绝」或数字回答;
- 任意 DSH 会话都能通过 notify_qq 主动推送;
- 回复过长时转成 .md 文件发送,不截断。

群聊(本分支重点)

群聊和私聊的礼貌规则不同。本分支默认只在以下情况发言:

| 条件 | 行为 |
| 被 @ | 立即交给 agent,正常回答 |
| 被 @ 后 5 分钟内 | 每条文字消息都交给 agent,由模型判断是否回应 |
| 正文提到人格名或接话关键词 | 本地短句 + 表情包接一句,不调用模型 |
| 其他 | 不发言 |

被 @ 后会开启一个 5 分钟的连续对话窗口。窗口内不按关键词过滤:消息会原样交给 agent,并在提示词里附上最近 8 条群消息(发送者 + 正文,单条截断 120 字),由模型判断这条是不是在跟它说话。

如果无关,agent 输出 [[NO_REPLY]],插件把整条回复丢弃,群里一个字都不发。流式分片被拆成 [[NO_ / [[NO_RE 时也按静默处理,避免群里冒出一行半截标记。

窗口不滑动:只有新的 @ 会续期,闲聊不会无限延长。

表情包

不生成表情包,只用两种来源:

- 群里像表情包的方形小图,收到时静默下载到 ~/.dsh/qq/stickers/collected/;
- 用户自己导入到 ~/.dsh/qq/stickers/ 根目录的 png/jpg/gif/webp。

收藏判定:最长边 ≤ 1024、宽高比 0.45–2.2、文件 ≤ 2 MiB、SHA-256 去重、最多 300 张;索引写 index.json。手机照片和截图会被排除。发送失败或目录为空时退到 emoji,不影响文字回复。

引用图片

QQ 把被引消息的图片放在 msg_elements[<refMsgIdx>].attachments。本分支会把引用附件下载到会话媒体目录,把本地绝对路径交给 agent,而不是只写一句“(引用了 image/png)”。

权限

新会话默认 read-only:

- permissionPreset 默认值改为 read-only;
- newSessionsReadOnly 默认开启,新建/采纳的会话会被强制施加只读,即使状态文件里存着旧的 danger-full-access;
- 已有会话的权限由 DSH 锁定,插件不会偷偷改。

要让某条新会话动手,需要先关闭只读锁,再选择「工作区可写」或「完全访问」。这是有意的摩擦:群里任何人都能触发它,默认不能写文件。

Token 优化

presenceNote(渠道上下文说明)只在每个新对话的第一条提示词里发送一次。运行时先检查宿主会话里是否已有 user/assistant/tool/developer 消息,没有才拼进去;群聊的 [群聊] 上下文仍然每条都带。

安装

从 npm 安装(推荐)

dsh plugin --profile desktop add dsh-qq-plugin-group-expand
或
dsh plugin --profile web add dsh-qq-plugin-group-expand

也可以在 DSH 的「添加插件」里直接输入包名:

dsh-qq-plugin-group-expand

从 GitHub 安装

https://github.com/jjjjjsgrmjjjjj/dsh-qq-plugin-group-expand

把 Git 地址粘进「添加插件」,或:

dsh plugin --profile web add https://github.com/jjjjjsgrmjjjjj/dsh-qq-plugin-group-expand

从本地目录 / tarball

npm pack
→ dsh-qq-plugin-group-expand-1.2.0.tgz

把 .tgz 的绝对路径或放着 package.json 的目录粘进「添加插件」。

从旧插件迁移

1. 先在 DSH 里停用并移除原来的 dsh-qq-plugin,否则两个插件会抢同一个 QQ 通道和 qqChannel 服务;
2. 安装 dsh-qq-plugin-group-expand;
3. 凭据作用域沿用上游的 dsh-qq-plugin,已绑定过的 AppSecret 可以直接复用;
4. 状态文件仍是 ~/.dsh/qq/state.json,会话映射、待发队列和设置会继续生效;
5. 启动后检查设置页的连接状态和 boot.log。

配置

设置项与上游一致,群聊新增字段主要在 lib/settings.js:

| 设置 | 默认 | 说明 |
| groupChatEnabled | true | 群聊总开关 |
| groupPersonaNames | 鲸鱼娘 | 群里认的人格名,逗号分隔 |
| groupAutoSpeak | true | 提到人格/关键词时自动接话 |
| groupFollowUpWindowMs | 300000 | 被 @ 后的连续对话窗口(5 分钟) |
| groupContextWindowMs | 120000 | 群历史语境窗口 |
| groupAutoSpeakKeywords | 鲸鱼娘,鱼鱼,胖鱼,在吗,哈哈,笑死,可爱,笨蛋 | 接话关键词 |
| groupSpeakCooldownMs | 20000 | 自动接话冷却 |
| groupSpeakMaxPerHour | 20 | 自动接话每小时上限 |
| groupCollectStickers | true | 收藏群里的表情包 |
| groupStickerChance | 70 | 接话时附带表情包的概率 |
| groupStickerDir | <home>/qq/stickers | 表情包目录 |
| groupFullMessageMode | 未启用 | 平台推送全量群消息时才有的分支,见「平台边界」 |
| permissionPreset | read-only | 新会话权限预设 |
| newSessionsReadOnly | true | 新会话强制只读锁 |

完整说明见 docs/HANDBOOK-USER.md 和设置页内置帮助。

实现要点

| 模块 | 职责 |
| index.js | 插件入口、服务注入、设置与生命周期 |
| lib/runtime.js | QQ 连接、入站消息、会话提交、助手流聚合、发送 |
| lib/router.js | 一个 QQ 对话对应哪个 DSH 会话,以及指令解析 |
| lib/group.js | 群聊门禁、人格判定、连续对话、[[NO_REPLY]] |
| lib/stickers.js | 表情包收藏、去重、上限、索引 |
| lib/prompt.js | 提示词合成、引用解析、引用附件提取 |
| lib/media.js | 图片/文件/语音落盘与描述 |
| lib/state.js | 原子写、串行化状态、对话键 |
| lib/credentials.js | 凭据服务适配(作用域沿用上游) |
| client.js | 设置页 UI |

几个关键决定:

1. 对话键带作用域:私聊 accountId:peerId,群聊 accountId:group:groupId。绑定、被动目标、待发队列、附件停靠全部按这个键走。
2. 群被动回复复用最近 @ 的 msg_id:QQ 群的被动回复只认最近一次 @ 的 msg_id(5 分钟有效);用后续普通消息的 id 会被当成主动消息,未认证官方机器人没有群主动消息权限,会直接失败。插件为每个群保留 #groupAt,窗口内统一复用。
3. 引用图片先落盘:QQ 附件 URL 会过期,收到消息时立刻下载,再给 agent 本地路径。
4. 渠道说明只发一次:用宿主会话消息判断是否新会话,再用进程内 #noteSent 兜底。
5. 群历史在提示词里,不额外调模型:最近 8 条、单条 120 字、最多 30 条在内存中。

测试

仓库自带三套离线自检,不依赖 DSH 宿主:

node scripts/verify.mjs
node scripts/verify-client.mjs
node scripts/verify-send-path.mjs

当前结果:836 项宿主侧检查、113 项客户端检查、81 项发送路径检查(836 host checks, 113 client checks, 81 send-path checks)。

verify-send-path.mjs 使用假 SDK 真跑发送路径,覆盖:

- 私聊/群聊 target、scope、被动 msg_id;
- 被动失败后的主动降级与限流;
- 群聊最近 @ 的 msg_id 复用;
- 新会话强制只读;
- 渠道说明首条发送、后续不重复;
- 群聊窗口关闭后不再提交。

平台边界与安全

1. 官方机器人默认只能收到群里的 @ 消息。腾讯的 GROUP_AND_C2C_EVENT 订阅包含 GROUP_AT_MESSAGE_CREATE;普通群消息 GROUP_MESSAGE_CREATE 需要平台侧的群消息全量权限。代码能处理该事件,但没有收到消息就没有内容可判断。
2. 未认证机器人只能由管理员使用,群主动消息通常没有权限;被动回复必须带有效 msg_id。
3. 不使用个人号协议,不共享个人 QQ 账号,也不依赖公网回调地址。
4. 群成员可以触发 agent。默认只读锁是安全底线;不要在群里直接放开「完全访问」。
5. 群聊收藏的图片来自群成员上传,使用前应自行确认内容与版权。

已知限制

- 官方通道下,非 @ 的群消息默认不可见;需要平台权限,插件无法绕过。
- sendTyping 仅支持单聊,群聊里会记录一条非致命错误。
- 群历史在内存中,DSH 重启后从零开始。
- 表情包只支持图片,不支持群里的动态表情协议。

许可与致谢

MIT License。上游项目:xcisxc29/dsh-qq-plugin。本分支的群聊、表情包、引用图片、权限默认值与 token 优化在上面继续演进;问题请提到本仓库的 Issues。
预览分享卡片长什么样 ↓jjjjjsgrmjjjjj/dsh-qq-plugin-group-expand
分享 · DeepSeek Harness Hub
jjjjjsgrmjjjjj/dsh-qq-plugin-group-expand

让 QQ 群成为远程操控与对话的入口

这是你的仓库?认领条目

回到顶部