扫码授权机器人,在微信单聊里收发消息并接续会话
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🔵 扫描:含敏感能力尚无人工评估展开查看扫描说明与证据 ↓
安全扫描自动 · 静态分析源码
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 均无隶属关系。预览分享卡片长什么样 ↓
分享 · DeepSeek Harness Hub
ChencLi819/dsh-weixin-channel
扫码授权机器人,在微信单聊里收发消息并接续会话
相关插件 · 平台集成
智能体工程课walkinglabs/learn-harness-engineering
一门项目制课程,教你搭建环境、管理状态、做验证、加控制机制,让 AI 编程智能体稳定干活。
★ 21,155已汉化DSH
71.7
视频翻译配音liuzhao1225/YouDub-webui
开源视频本地化工作台:导入视频,识别、翻译并逐句克隆原声,生成字幕和配音成片。
★ 5,792已汉化Cordis
71.4
失败经验库Ikalus1988/MisakaNet
📚 零依赖、由 git 支撑的微课程库,让 AI 智能体异步分享并检索经过验证的调试经验。| https://misakanet.org
★ 550已汉化DSH
71.2
IM 机器人接入xmanrui/dsh-im
让 DeepSeek Harness 触手可及 Connecting DeepSeek Harness
★ 3,170已汉化DeepSeek 客户端
71
桌面智能体工作区freestylefly/wesight
WeSight 是开源桌面控制台,面向本地 AI 智能体。它帮你安装或复用 Claude…
★ 933已汉化MCP
71
中国平台研究引擎Jesseovo/last30days-skill-cn
给 AI Agent 的中文互联网研究 Skill:检索 8 大平台最近 30…
★ 2,041已汉化DSH
70.7
这是你的仓库?认领条目