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

微信单聊通道 ChencLi819/dsh-weixin-channel

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

扫码授权机器人,在微信单聊里收发消息并接续会话

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

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

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

状态速览

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

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

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

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

读写/删除本地文件发起外部网络请求
查看扫描证据(共 46 处,展示前 46 条)
  • 写入本地文件
    index.js:174
    mkdirSync(stateDir, { recursive: true })
  • 写入本地文件
    index.js:175
    writeFileSync(diagFile, `${JSON.stringify({ ...diagnostics, updatedAt: new Date().toISOString() }, null, 2)}\n`)
  • 发起网络请求
    client/ui.js:42
    const res = await fetch(`${BASE}/status`, { cache: 'no-store' })
  • 发起网络请求
    client/ui.js:122
    const res = await fetch(`${BASE}/login`, { method: 'POST' })
  • 写入本地文件
    lib/log.js:17
    mkdirSync(stateDir, { recursive: true })
  • 写入本地文件
    lib/log.js:19
    if (statSync(file).size > MAX_BYTES) renameSync(file, `${file}.1`)
  • 读取本地文件
    lib/log.js:19
    if (statSync(file).size > MAX_BYTES) renameSync(file, `${file}.1`)
  • 写入本地文件
    lib/log.js:23
    appendFileSync(file, line)
  • 读取本地文件
    lib/store.js:17
    if (!existsSync(file)) return
  • 读取本地文件
    lib/store.js:18
    const raw = JSON.parse(readFileSync(file, 'utf8'))
  • 写入本地文件
    lib/store.js:35
    mkdirSync(stateDir, { recursive: true })
  • 写入本地文件
    lib/store.js:37
    writeFileSync(tmp, `${JSON.stringify(data, null, 2)}\n`)
  • 写入本地文件
    lib/store.js:38
    renameSync(tmp, file)
  • 读取本地文件
    lib/client.js:94
    const stamped = readdirSync(qrDir)
  • 删除本地文件
    lib/client.js:98
    try { rmSync(join(qrDir, name), { force: true }) } catch { }
  • 写入本地文件
    lib/client.js:105
    mkdirSync(qrDir, { recursive: true })
  • 写入本地文件
    lib/client.js:108
    writeFileSync(file, toPng(url, { scale: settings.login.qrScale, quiet: settings.login.qrQuiet }))
  • 写入本地文件
    lib/client.js:110
    try { writeFileSync(latest, toPng(url, { scale: settings.login.qrScale, quiet: settings.login.qrQuiet })) } catch { }
  • 删除本地文件递归
    lib/client.js:368
    await rm(sdkStorageDir, { recursive: true, force: true })
  • 读取本地文件
    lib/client.js:378
    return existsSync(join(sdkStorageDir, 'credentials.json'))
  • 写入本地文件
    lib/inbound.js:66
    mkdirSync(dir, { recursive: true })
  • 写入本地文件
    lib/inbound.js:68
    writeFileSync(file, bytes)
  • 读取本地文件
    lib/qr-page.js:224
    if (!existsSync(qrFile)) {
  • 读取本地文件
    lib/qr-page.js:228
    const stat = statSync(qrFile)
  • 读取本地文件
    lib/qr-page.js:235
    send(res, 200, 'image/png', readFileSync(qrFile), { ETag: etag })
  • 读取本地文件
    lib/model.js:36
    if (!existsSync(file)) continue
  • 读取本地文件
    lib/model.js:37
    const text = readFileSync(file, 'utf8')
  • 发起网络请求
    vendor/wechatbot/dist/media/remote.js:20
    const response = await fetch(url, {
  • 读取本地文件
    vendor/wechatbot/dist/protocol/types.js:15
    const pkg = JSON.parse(readFileSync(pkgPath, 'utf-8'));
  • 发起网络请求
    vendor/wechatbot/dist/transport/http.js:56
    const response = await this.request({
  • 发起网络请求
    vendor/wechatbot/dist/transport/http.js:75
    const response = await this.request({
  • 发起网络请求
    vendor/wechatbot/dist/transport/http.js:90
    response = await fetch(url, {
  • 发起网络请求
    vendor/wechatbot/dist/media/downloader.js:24
    const response = await fetch(downloadUrl, {
  • 发起网络请求
    vendor/wechatbot/dist/media/uploader.js:57
    const response = await fetch(uploadUrl, {
  • 读取本地文件
    vendor/wechatbot/dist/storage/file.js:16
    const raw = await readFile(this.filePath(key), 'utf8');
  • 写入本地文件
    vendor/wechatbot/dist/storage/file.js:27
    await writeFile(this.filePath(key), JSON.stringify(value, null, 2) + '\n', {
  • 删除本地文件
    vendor/wechatbot/dist/storage/file.js:32
    await rm(this.filePath(key), { force: true });
  • 读取本地文件
    vendor/wechatbot/dist/storage/file.js:36
    await readFile(this.filePath(key));
  • 读取本地文件
    vendor/wechatbot/dist/storage/file.js:45
    const files = await readdir(this.dir);
  • 删除本地文件
    vendor/wechatbot/dist/storage/file.js:48
    .map((f) => rm(path.join(this.dir, f), { force: true })));
  • 写入本地文件
    vendor/wechatbot/dist/storage/file.js:61
    await mkdir(this.dir, { recursive: true, mode: 0o700 });
  • 读取本地文件
    lib/voice.js:32
    if (!existsSync(file)) return out
  • 读取本地文件
    lib/voice.js:33
    for (const line of readFileSync(file, 'utf8').split('\n')) {
  • 发起网络请求
    lib/voice.js:69
    const res = await fetch(cfg.baseURL || DASHSCOPE_TTS_URL, {
  • 发起网络请求
    lib/voice.js:85
    const audioRes = await fetch(url, { signal: AbortSignal.timeout(Number(cfg.timeoutMs) || 60_000) })
  • 读取本地文件
    lib/voice.js:149
    if (!existsSync(spec)) continue
扫描于 2026/11/3(1 天前) · 范围 入口闭包 + 发布文件清单 · 来源 GitHub 仓库

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

依赖的 DSH / Cordis 模块
@deepseek-ai/cordis@deepseek-ai/dsh-agent@deepseek-ai/dsh-llm@deepseek-ai/dsh-session@deepseek-ai/schemastery
给这个插件打分还没有人投票↓
用户评分
还没有人投票,来当第一个

DSH 插件:把 agent 接进微信单聊。走腾讯官方 iLink Bot API(ClawBot 通道),扫码授权机器人身份,支持文本/图片/语音/文件收发、会话映射与工具收口。

README

由 DeepSeek 最新模型翻译生成
dsh-weixin-channel DeepSeek Harness(DSH)插件。把智能体接入微信单聊:扫码授权出一个机器人身份,支持文本、图片、语音、文件的收发,并把微信用户映射为 DSH 会话。 通信走腾讯官方 iLink Bot API(即微信官方 ClawBot 通道),不是客户端逆向:不模拟登录、不读取通讯录与朋友圈,只做「一个能收发消息的机器人」。 目录 - 1. 功能 - 2. 兼容性与依赖 - 3. 安装 - 4. 登录 - 5. 工具参考 - 6. 配置 - 7. 安全模型 - 8. 工作原理 - 9. 运维与故障排查 - 10. 已知限制 - 11. 合规与风险 - 12. 开发 - 13. 第三方代码 - 14. 许可证 - English Overview 1. 功能 | 能力 | 说明 | | 扫码登录 | 生成二维码 PNG,用微信扫码授权;凭证落盘,重启免扫 | | 入站消息 | 长轮询接收文本、图片、语音、文件、视频;消息 ID 去重 | | 图片处理 | 入站图片经 DSH attachments 服务转为原生图片块,直接进入模型视野 | | 语音转写 | 优先使用平台自带转写文本,不依赖外部 ASR 服务 | | 出站消息 | 文本按句子边界自动切分;图片与文件按扩展名路由 |
展开完整文档(README 剩余 1 节)
dsh-weixin-channel

DeepSeek Harness(DSH)插件。把智能体接入微信单聊:扫码授权出一个机器人身份,支持文本、图片、语音、文件的收发,并把微信用户映射为 DSH 会话。

通信走腾讯官方 iLink Bot API(即微信官方 ClawBot 通道),不是客户端逆向:不模拟登录、不读取通讯录与朋友圈,只做「一个能收发消息的机器人」。

目录

- 1. 功能
- 2. 兼容性与依赖
- 3. 安装
- 4. 登录
- 5. 工具参考
- 6. 配置
- 7. 安全模型
- 8. 工作原理
- 9. 运维与故障排查
- 10. 已知限制
- 11. 合规与风险
- 12. 开发
- 13. 第三方代码
- 14. 许可证
- English Overview

1. 功能

| 能力 | 说明 |
| 扫码登录 | 生成二维码 PNG,用微信扫码授权;凭证落盘,重启免扫 |
| 入站消息 | 长轮询接收文本、图片、语音、文件、视频;消息 ID 去重 |
| 图片处理 | 入站图片经 DSH attachments 服务转为原生图片块,直接进入模型视野 |
| 语音转写 | 优先使用平台自带转写文本,不依赖外部 ASR 服务 |
| 出站消息 | 文本按句子边界自动切分;图片与文件按扩展名路由 |
| 会话映射 | 微信用户与 DSH 会话确定性映射,重启后可续接上下文 |
| 白名单 | 默认仅放行登录者本人;名单为空时不会退化为放行所有人 |
| 工具收口 | 微信会话可见的工具面被限制为白名单内的若干项(默认 26 个) |
| 插件页二维码 | 在 DSH 界面内直接显示登录二维码,无需翻找文件 |

2. 兼容性与依赖

| 项目 | 要求 | 说明 |
| DSH | 宿主包 ^0.1.0-rc.6 或 ^0.2.0-rc.1 | 见 peerDependencies |
| Node.js | >= 22 | 使用内置 fetch、node:crypto 等 |
| 微信 | 已开通 ClawBot / iLink Bot 通道的微信号 | 登录时由服务端下发二维码 |
| @deepseek-ai/schemastery | ^3.18.1 | 配置校验 |
| silk-wasm | 可选 | 解码 SILK 语音;未安装时落盘为原始 SILK(不影响转写文本) |
| Python | 可选 | 仅用于二维码解码对照测试(tools/qr-suite-check.py) |

3. 安装

3.1 通过 DSH CLI 安装(推荐)

从 npm 安装
dsh plugin --profile web add dsh-weixin-channel

或从源码安装
dsh plugin --profile web add github:ChencLi819/dsh-weixin-channel

Desktop 版
dsh plugin --profile desktop add dsh-weixin-channel

安装完成后重启 DSH。

3.2 通过仓库脚本 / link 安装

以 link: 方式安装(改源码即时生效)时,需要在插件目录补一层指向宿主包的链接:

cd <你的 profile 目录>
pnpm add link:<本仓库路径>

补依赖链接:插件用 link 装进来时是 junction,Node 会解析成真实路径,于是去真实路径下找 @deepseek-ai/,找不到会报 ERR_MODULE_NOT_FOUND $src = "$env:USERPROFILE\.dsh\profiles\node_modules\@deepseek-ai" $dst = "<本仓库路径>\node_modules\@deepseek-ai" New-Item -ItemType Directory -Force -Path (Split-Path $dst) | Out-Null New-Item -ItemType Junction -Path $dst -Target $src

然后在 profile 的 package.json 的 dsh.profile.bundles 中加入 dsh-weixin-channel,重启 DSH。
插件会写入体检文件 ~/.dsh/wechat-channel/diagnostic.json。

3.3 升级与卸载

| 操作 | 步骤 |
| 升级 | 重新执行 CLI 安装命令;link: 方式更新源码后重启 DSH |
| 卸载 | 从 dsh.profile.bundles 中移除,并卸载依赖;如不再使用,删除 ~/.dsh/wechat-channel |

4. 登录

1. 调用 wechat_login(action=start)申请二维码,返回 PNG 路径(默认 ~/.dsh/wechat-channel/login-qr.png)
2. 用微信扫码
3. 若手机提示输入配对码,调用 wechat_login(action=verify,code=<配对码>)

凭证保存在 ~/.dsh/wechat-channel/sdk/,之后启动自动登录。

action=logout 会停止轮询并删除凭证目录——仅清理内存不够,凭证留在磁盘上时下次启动会自动登录回来。

二维码必须实时轮询。 二维码存在有效期,且扫码后需要插件在轮询中接收服务端下发的凭证。因此不要用截图代替插件自身发起的登录流程,也不要关掉进程后再扫。

5. 工具参考

插件注册 3 个工具。所有工具的输出均为 { text: string }。

5.1 wechat_login

管理登录状态。

| 参数 | 类型 | 必填 | 说明 |
| action | string | 是 | start 生成二维码 / verify 提交配对码 / logout 清除登录状态 |
| code | string | 否 | 配对码,action=verify 时必填 |

5.2 wechat_status

查询渠道状态:登录情况、二维码位置、收发计数、白名单。

| 参数 | 类型 | 默认 | 说明 |
| selftest | boolean | false | 为 true 时真实建立一次会话,校验工具收口名单的有效性 |

selftest 会给出权威结论:哪些工具名有效、哪些不存在。日常无需开启。

5.3 wechat_send

向微信发送内容。

| 参数 | 类型 | 默认 | 说明 |
| userId | string | 当前会话对端 | 目标微信用户 ID |
| text | string | — | 文本内容 |
| file | string | — | http(s) 链接(插件自行下载)或本地绝对路径 |

回复当前会话不需要调用此工具,正文会自动发送。text 与 file 同时提供时拆为两条消息发送(微信不支持图文混合单条消息)。

6. 配置

默认值定义于 lib/config.js。在 profile 的 cordis.patch.yml 中按需覆盖,配置为深合并:

- id: wechat-channel
config:
allow:
users: ['wxid_xxxxxxxx'] # 留空 = 只放行登录者本人
send:
maxPerMinute: 6
session:
resetCommand: '/new'
tools:
restrict: true
allow: [wechat_login, wechat_status, wechat_send]

| 配置项 | 类型 | 默认 | 说明 |
| enabled | boolean | true | 插件总开关 |
| stateDir | string | ~/.dsh/wechat-channel | 状态目录:凭证、context token、日志、媒体 |
| baseUrl | string | https://ilinkai.weixin.qq.com | iLink Bot API 基址 |
| botAgent | string | dsh-weixin-channel/0.1 | 请求中携带的调用方标识 |
| login.autoLogin | boolean | true | 启动时使用已有凭证自动登录 |
| login.qrDir | string | 空(用 stateDir) | 二维码 PNG 落盘目录 |
| login.qrScale / login.qrQuiet | number | 8 / 4 | 二维码渲染参数 |
| login.timeoutMs | number | 180000 | 扫码等待时长 |
| login.expiredCooldownMs | number | 3600000 | 会话过期后的冷却时长 |
| allow.users | string[] | [] | 白名单;留空退化为只放行登录者本人 |
| allow.selfOnly | boolean | true | 仅放行登录者本人(忽略 users) |
| allow.silentDrop | boolean | true | 非白名单消息静默丢弃 |
| session.prefix | string | wechat | 会话 key 前缀 |
| session.resetCommand | string | /new | 重置会话的指令,留空则不启用 |
| session.preset | string | 空 | 可选的 agent preset;留空见下文说明 |
| model.provider / model.model | string | 空 | 微信会话的模型路由,留空则由宿主解析 |
| tts.apiKeyEnv | string | DASHSCOPE_API_KEY | 语音合成凭据的环境变量名 |
| tts.apiKey | string | 空 | 直接提供凭据(留空则按 apiKeyEnv 查找) |
| tts.model / tts.voice | string | qwen3-tts-flash / Cherry | 合成模型与音色 |
| send.maxChars | number | 2000 | 单条文本上限,超出按句子边界切分 |
| send.typing | boolean | true | 发送前显示「正在输入」 |
| send.maxPerMinute | number | 12 | 出站限流(0 = 不限) |
| receive.poll | boolean | true | 是否开启长轮询收消息 |
| receive.dedupeSize | number | 500 | 去重窗口大小 |
| tools.enabled | boolean | true | 是否注册 wechat_ 工具 |
| tools.restrict | boolean | true | 是否对微信会话启用工具收口 |
| tools.allow / tools.deny | string[] | 见 7.3 | 收口后的工具白/黑名单 |

7. 安全模型

7.1 三道边界

| 边界 | 机制 | 默认 |
| 谁能触发 | 白名单:仅处理指定微信用户的消息 | 仅登录者本人 |
| 能做什么 | 工具收口:限制微信会话可见的工具面 | 26 项(无 shell / 文件 / 子代理) |
| 能聊什么 | 仅单聊;协议本身不提供群聊能力 | 不可配置 |

默认拒绝:白名单为空时退化为「只放行扫码登录的那个微信号」,不会因为列表为空而放行所有人。

即便有上述边界,插件背后仍是一个具备工具调用能力的智能体。不要把该渠道暴露给不可信的人。

7.2 工具收口的实现

会话装配时调用 tools.restrict({ allow }),把该智能体作用域可见的全局工具面限制为 tools.allow 中的项。这是过滤继承面,不是「可见但禁止调用」——模型侧这些工具根本不存在,因此诱导其执行命令无效。

7.3 默认放行的工具(26 个)

| 分类 | 工具 |
| 渠道与状态 | wechat_login wechat_status wechat_send mood_now mood_feel mood_diary |
| 联网检索 | advanced_search multi_search research cache_search platform_search domain_search image_search video_search grab_image |
| 内容聚合 | feed_scroll feed_read feed_share feed_history feed_watch |
| 表情图库 | meme_list meme_update learn_meme |
| 图像理解 | qqbot_describe_image |
| 实用 | weather qqbot_time |

故意不放行:pwsh write edit subagent workflow send_message(任意命令、文件修改、派生智能体); qqbot_say qqbot_send_file qqbot_voice_call(QQ 专用发送类);send_meme(输出其他渠道的标记格式); present exit_plan_mode(GUI 卡片)。

7.4 收口的失效模式

dsh-tools 的 restrict() 遇到不认识的工具名会抛错,而不是忽略该项。
抛错会导致收口未装上、工具面全开——「看起来只是少了个功能,实际是把整面放开」。

插件对此的处理是向安全方向回退:按原样尝试一次,抛错后从报错信息中取出问题名、移除后重试。因此写错一个名字的后果是「该项不放行」,而不是「全部放行」。

不要在外部预先用 tools.view(undefined).restrictableNames 校验名单:该调用的作用域与
restrict() 内部使用的不是同一个,会误判十余个正常工具为「不存在」。权威清单来自
restrict() 自身的报错信息,或 wechat_status({ selftest: true })。

7.5 收口的能力边界

restrict() 只能在智能体已继承到的工具面内过滤,无法授予原本不在其中的工具。
部分工具(web_search web_fetch read glob grep write edit pwsh schedule_ todo_write skill ask_user_question read_image present)不在该继承链上,写入 allow 也会被剔除;这些工具在微信会话中本就不可见。联网能力由 advanced_search / multi_search / research 提供。

8. 工作原理

8.1 处理链路

登录 wechat_login → 申请二维码 → 扫码 → 配对码 → 凭证落盘入站 长轮询 → 去重 → 白名单 → 记录 context token → 媒体落盘 / attachments → 投递到 DSH 会话出站 session/event → 文本切分 → 限流 → 发送(回带 context token)

context token 必须持久化:iLink 要求每条出站消息回带最近一次入站消息的 context_token。插件重启后若丢失该 token,将无法再发送消息。

会话 key 不含 accountId:accountId 是每次扫码登录时服务端新建的机器人身份,重新扫码即更换。若将其纳入会话 key,重新登录等同于换了一个人,聊天上下文全部丢失。
身份区分依靠微信 userId。

8.2 入站媒体

| 类型 | 处理方式 |
| 图片 | 交给 DSH attachments 服务,转为原生图片块进入模型视野(不依赖工具,收口后仍可用) |
| 语音 | 优先使用平台转写文本;音频落盘至 ~/.dsh/wechat-channel/media/<用户>/ |
| 文件 / 视频 | 落盘并在正文中附带路径 |

attachments 服务不可用时回退为「落盘 + 正文路径」,功能不丢失;启动日志会说明实际路径。

8.3 二维码

插件内置零依赖二维码编码器(lib/qr.js),支持版本 1–10(内容 ≤ 213 字节)。
iLink 登录链接约 89 字节,对应版本 6。

8.4 状态文件

| 路径 | 内容 |
| ~/.dsh/wechat-channel/sdk/ | 登录凭证(logout 时整体删除) |
| ~/.dsh/wechat-channel/state.json | context token、去重窗口、登录元信息(原子写) |
| ~/.dsh/wechat-channel/diagnostic.json | 体检信息:登录状态、轮询状态、计数、异常标记 |
| ~/.dsh/wechat-channel/media/<用户>/ | 入站媒体文件 |
| ~/.dsh/wechat-channel/login-qr.png | 登录二维码 |

9. 运维与故障排查

node tools/run-tests.mjs # 全部 6 套测试
node tools/selftest.mjs # 纯逻辑自测
node tools/e2e.mjs # 端到端集成(假宿主)
node tools/probe-login.mjs # 登录链路探测
node tools/probe-poll-timing.mjs # 长轮询时序探测
node tools/probe-storage.mjs # SDK 存储目录探测
node tools/verify-qr.mjs # 二维码校验

| 现象 | 可能原因 | 处理 |
| 工具未注册 | 插件未安装或未重载 | 检查 profile 的 bundles 与 cordis.patch.yml,重启 DSH |
| ERR_MODULE_NOT_FOUND(@deepseek-ai/) | link: 安装缺少依赖链接 | 按 3.2 补一层 junction |
| 二维码扫了没反应 | 登录轮询中断;二维码过期 | 重新调用 wechat_login;确保进程在轮询(不要用截图代替) |
| 收不到消息 | 长轮询关闭;会话已过期(服务端返回 -14) | 检查 receive.poll;重新扫码登录 |
| 发不出消息 | 缺少 context token(重启后丢失) | 等待一次入站消息以刷新 token |
| 陌生人消息被丢弃 | 白名单生效(预期行为) | 如需放行,在 allow.users 中显式添加 |
| 语音只有文件没有文字 | 平台未提供转写文本 | 属预期;可自行接入 ASR 处理落盘文件 |

10. 已知限制

- 仅支持单聊。 微信机器人协议不提供群聊能力,这不是配置项。
- 出站语音不可用(协议层限制)。 TTS、SILK 编码、CDN 上传、VoiceItem 字段填充均已验证通过,服务端返回 message_id 且无错误码,但对端收不到消息。
详见 12.3。入站语音正常。
- 会话过期需重新扫码。 服务端返回 -14 时会话作废;插件会记录日志并在 diagnostic.json 中标记。
- 落盘语音为原始 SILK。 未安装 silk-wasm 时不做格式转换;模型本身不解析音频,实际可用的是平台转写文本,该路径不依赖 silk-wasm。
- 二维码仅支持版本 1–10(内容 ≤ 213 字节)。
- session.preset 默认留空。 preset 依赖 dsh-agent-presets 扫描用户 preset 根目录;若部署未扫描该目录(只列出随附 preset),填写后只会持续报警告。
工具收口由 tools.restrict 负责,不依赖目录发现。

11. 合规与风险

- 使用官方接口。 通信走腾讯官方 iLink Bot API,不涉及客户端逆向、不模拟登录、不读取通讯录与朋友圈。
- 需要本人扫码授权。 登录凭证属于扫码的微信号,插件以该身份收发消息;凭证保存在本地状态目录,wechat_login action=logout 可清除。
- 非官方项目。 本插件由社区维护,与腾讯、DeepSeek 均无隶属关系。
- 使用前请自行确认符合微信平台的相关条款与所在地区的适用规定;由使用者承担使用风险。
- 数据流向:消息内容与媒体经 iLink 服务端传输;使用云端 TTS 时文本会发送至所配置的合成服务(默认阿里云百炼)。如不允许外发,请勿启用语音合成。
- 不要暴露给不可信的人:渠道背后是具备工具调用能力的智能体,尽管已有白名单与工具收口。

12. 开发

12.1 目录结构

index.js 插件入口:name / inject / Config / apply lib/config.js 配置默认值与深合并 lib/log.js 日志(落盘 + 宿主 logger) lib/store.js context token / 去重窗口 / 登录元信息(原子写) lib/qr.js 零依赖二维码编码器 lib/client.js iLink 客户端封装(SDK + 扫码出图 + 限流) lib/session.js 微信用户 ↔ DSH 会话映射与投递 lib/inbound.js 入站:去重 → 白名单 → 存 token → 媒体落盘 → 投递 lib/outbound.js 出站:session/event → 切分 → 发送 client/ui.js 客户端插件:插件页内的二维码展示 vendor/wechatbot/ 内置 SDK(MIT,见第 13 节) tools/ 测试与探测脚本

12.2 测试

node tools/run-tests.mjs

包含 6 套:纯逻辑自测、回归测试、插件加载、端到端集成、二维码验收、二维码解码对照。

12.3 验证方法

原则:自洽的实现可以同时是错的,只有外部证据才算数。
(项目曾出现二维码「格式信息副本 2」写反的问题——编码器与解码器同为自己所写,一起错、互相验证通过。)

| 验证对象 | 外部证据 |
| 二维码 | ISO/IEC 18004 测试向量 + OpenCV 独立解码(非自研解码器) |
| 入站媒体解密 | FIPS-197 C.1 的 AES-128 标准向量(首块逐字节比对) |
| 工具收口 | 真实建立一次会话,检查智能体视角实际可见的工具(wechat_status selftest) |
| 端到端 | 真实微信收发 |

13. 第三方代码

vendor/wechatbot/ 是 @wechatbot/wechatbot 2.2.0 的副本(dist/ 运行时代码与 types/ 类型声明),MIT 许可,作者 corespeed-io。
原始许可文本见 vendor/NOTICE.md。

内置而非 npm install 的原因:离线可用、版本锁定,避免上游发布新版本导致行为变更。
该 SDK 是 iLink 协议的第三方 MIT 实现,与本插件为直接依赖关系。

14. 许可证

MIT

English Overview

dsh-weixin-channel 把 DeepSeek Harness 智能体接到微信一对一聊天,走的是腾讯官方 iLink Bot API(ClawBot 通道)。它先做扫码授权拿到机器人身份,然后收发文本、图片、语音和文件,把每个微信用户映射到一个 DSH 会话。

这不是客户端逆向工程项目:不模拟登录,不读取通讯录和朋友圈。插件注册三个工具 —— wechat_login、wechat_status 和 wechat_send —— 并自带默认拒绝的白名单(默认只放行扫码的那个账号),外加一条工具限制,规定微信会话能调用哪些工具(默认 26 个工具,无 shell,无文件访问,无子代理)。

dsh plugin --profile web add dsh-weixin-channel

已知限制:协议不支持群聊;发出的语音消息服务端会接收,但不会投递给接收方(见第 10 节)。需要 Node.js >= 22。采用 MIT License;内置的第三方 SDK 也是 MIT(见第 13 节)。这是社区项目,与腾讯、DeepSeek 均无隶属关系。
预览分享卡片长什么样 ↓ChencLi819/dsh-weixin-channel
分享 · DeepSeek Harness Hub
ChencLi819/dsh-weixin-channel

扫码授权机器人,在微信单聊里收发消息并接续会话

这是你的仓库?认领条目

回到顶部