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

多渠道消息接入 wsz987/dsh-channels

DeepSeek Harnessv0.0.1
wsz98752 天前有提交已提供中文文档扫描:含敏感能力

把微信 / QQ / 钉钉 / 飞书 / Telegram 接入 DeepSeek…

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

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

自动兼容检查未通过:缺少 main/exports/bin 入口声明;仓库 package.json 标记 private,未发布到 npm,需从源码安装。以下命令仍可尝试,但可能失败。
安装命令 · 需先装 dsh CLI 引擎
dsh plugin --profile web add wsz987/dsh-channels
该包不可直接 npm 安装,改从 GitHub 源安装(明细见下方安装检查)

状态速览

判定依据:实装验证 · 静态安装检查 · 自动扫描 · 仓库维护状态
信任档位:需留意
是什么
dsh 原生插件 · platform
装得上吗
实装验证未通过(unknown),装前请到仓库确认最近更新与 issue
L4 · 真实安装等级说明 →
安全吗
本站尚未对该插件做风险分级
暂未覆盖,不等同于无风险
还在维护吗
更新放缓:最近一次提交在 52 天前
档位由哪些信号合成

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

验证判据与等级说明 →
⚠︎ 实装验证未通过(unknown · 2026/10/22) ——可能是验证环境差异,装前建议到 GitHub 仓库确认最近更新与 issue。
社区实装还没有人打卡 · 装过的第一个就是你
安装兼容性检查需源码安装

缺少 main/exports/bin 入口声明;仓库 package.json 标记 private,未发布到 npm,需从源码安装

展开查看检查明细 ↓

以下结论由程序自动检查 npm 包、engines 声明与入口文件得出,未做人工实机验证——能装不等于用着没问题。

✓npm 包dsh-channels @ 0.0.1
✓Node 引擎要求 ^22.19.0 || >=24.0.0 · 基线 Node 22.19 满足
✓dsh CLI 依赖未声明 dsh 版本约束
✗入口文件缺少入口声明

源码安装时若 pnpm 拦截 prepare 脚本,按其提示在 pnpm-workspace.yaml 的 allowBuilds 中放行后重跑。

验证方式:npm registry 存在性 + package.json 静态校验 · 最后检查 2026/10/30 15:56:27

安全扫描自动 · 静态分析源码
v2.7.0
🔵 扫描:含敏感能力尚无人工评估
展开查看扫描说明与证据 ↓

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

可执行外部命令读写/删除本地文件发起外部网络请求
查看扫描证据(共 69 处,展示前 52 条)
  • 发起网络请求
    packages/channel-control/src/update-check.ts:397
    const response = await fetch(`${REGISTRY_BASE}/${BUNDLE_PACKAGE}/${tag}`, {
  • 读取本地文件
    packages/channel-core/src/file-secret-store.ts:61
    if (!existsSync(file)) return undefined;
  • 读取本地文件
    packages/channel-core/src/file-secret-store.ts:62
    return readFileSync(file, 'utf8');
  • 写入本地文件
    packages/channel-core/src/file-secret-store.ts:71
    mkdirSync(dirname(file), { recursive: true });
  • 写入本地文件
    packages/channel-core/src/file-secret-store.ts:73
    writeFileSync(tmp, value, { encoding: 'utf8', mode: 0o600 });
  • 写入本地文件
    packages/channel-core/src/file-secret-store.ts:74
    renameSync(tmp, file);
  • 写入本地文件
    packages/channel-core/src/file-secret-store.ts:76
    chmodSync(file, 0o600);
  • 删除本地文件
    packages/channel-core/src/file-secret-store.ts:85
    rmSync(file, { force: true });
  • 读取本地文件
    packages/channel-core/src/file-storage.ts:62
    if (!existsSync(file)) return undefined;
  • 读取本地文件
    packages/channel-core/src/file-storage.ts:63
    return readFileSync(file, 'utf8');
  • 写入本地文件
    packages/channel-core/src/file-storage.ts:72
    mkdirSync(dirname(file), { recursive: true });
  • 写入本地文件
    packages/channel-core/src/file-storage.ts:74
    writeFileSync(tmp, value, 'utf8');
  • 写入本地文件
    packages/channel-core/src/file-storage.ts:75
    renameSync(tmp, file);
  • 删除本地文件
    packages/channel-core/src/file-storage.ts:81
    rmSync(file, { force: true });
  • 发起网络请求
    packages/channel-dingtalk/src/official-upstream.ts:107
    return this.options.transport.request(sessionWebhook, {
  • 发起网络请求
    packages/channel-dingtalk/src/official-upstream.ts:127
    const raw = await this.options.transport.request(`${DINGTALK_API}/v1.0/oauth2/accessToken`, {
  • 发起网络请求
    packages/channel-dingtalk/src/official-upstream.ts:154
    const raw = await this.options.transport.request(`${DINGTALK_API}/v1.0/robot/${key}`, {
  • 发起网络请求
    packages/channel-dingtalk/src/official-upstream.ts:178
    const raw = await this.options.transport.request(
  • 发起网络请求
    packages/channel-dingtalk/src/official-upstream.ts:214
    const raw = await this.options.transport.request(`${DINGTALK_API}/v1.0/robot/${key}`, {
  • 发起网络请求
    packages/channel-dingtalk/src/official-upstream.ts:244
    const raw = await this.options.transport.request(`${DINGTALK_API}/v1.0/im/interactiveCards/send`, {
  • 发起网络请求
    packages/channel-dingtalk/src/upstream.ts:72
    raw = await this.options.transport.request(
  • 发起网络请求
    packages/channel-dingtalk/src/upstream.ts:90
    return this.options.transport.request('/message/send', {
  • 发起网络请求
    packages/channel-dingtalk/src/upstream.ts:98
    .request('/card/create', {
  • 发起网络请求
    packages/channel-dingtalk/src/upstream.ts:109
    return this.options.transport.request('/card/update', {
  • 发起网络请求
    packages/channel-dingtalk/src/upstream.ts:116
    return this.options.transport.request('/card/finish', {
  • 发起网络请求
    packages/channel-dingtalk/src/upstream.ts:123
    return this.options.transport.request('/card/fail', {
  • 读取本地文件
    packages/channel-harness/src/binding-store.ts:285
    text = await readFile(this.filePath, 'utf8');
  • 写入本地文件
    packages/channel-harness/src/binding-store.ts:375
    await mkdir(dirname(this.filePath), { recursive: true });
  • 写入本地文件
    packages/channel-harness/src/binding-store.ts:377
    await writeFile(tmp, JSON.stringify(Object.fromEntries(this.cache), null, 2), 'utf8');
  • 写入本地文件
    packages/channel-harness/src/binding-store.ts:378
    await rename(tmp, this.filePath);
  • 写入本地文件
    packages/channel-harness/src/workspace-resolver.ts:143
    await mkdir(cwd, { recursive: true });
  • 发起网络请求
    packages/channel-lark/src/openapi-outbound.ts:531
    const response = await globalThis.fetch(url);
  • 发起网络请求
    packages/channel-telegram/src/upstream.ts:299
    raw = await this.options.transport.request(
  • 发起网络请求
    packages/channel-telegram/src/upstream.ts:644
    return await this.options.transport.request(this.path(endpoint), { method: 'POST', body });
  • 读取本地文件
    packages/channel-testkit/src/fixture-loader.ts:70
    if (existsSync(candidate) && statSync(candidate).isDirectory()) {
  • 读取本地文件
    packages/channel-testkit/src/fixture-loader.ts:70
    if (existsSync(candidate) && statSync(candidate).isDirectory()) {
  • 读取本地文件
    packages/channel-testkit/src/fixture-loader.ts:89
    const raw = await readFile(fixturePath(channel, name), 'utf8');
  • 读取本地文件
    packages/channel-testkit/src/fixture-loader.ts:97
    const raw = readFileSync(fixturePath(channel, name), 'utf8');
  • 读取本地文件
    packages/channel-verify/src/verify.ts:180
    if (!existsSync(pkgPath)) {
  • 读取本地文件
    packages/channel-verify/src/verify.ts:188
    const parsed: unknown = JSON.parse(await readFile(pkgPath, 'utf8'));
  • 读取本地文件
    packages/channel-verify/src/verify.ts:220
    } else if (!existsSync(resolve(dir, patch))) {
  • 读取本地文件
    packages/channel-verify/src/verify.ts:336
    return existsSync(abs) ? { entry: abs, notBuilt: false } : { entry: abs, notBuilt: true };
  • 读取本地文件
    packages/channel-verify/src/verify.ts:341
    if (existsSync(lib)) return { entry: lib, notBuilt: false };
  • 读取本地文件
    packages/channel-verify/src/verify.ts:551
    if (existsSync(localFixtures) && statSync(localFixtures).isDirectory()) {
  • 执行外部命令固定命令
    packages/channel-verify/src/verify.ts:701
    const child = spawn('pnpm', ['test'], {
  • 读取本地文件
    packages/channels/build.mjs:9
    const source = await readFile(join(webLib, 'client.js'), 'utf8');
  • 写入本地文件
    packages/channels/build.mjs:19
    await writeFile(join(root, 'lib', 'client.js'), client, 'utf8');
  • 读取本地文件
    packages/channels/build.mjs:21
    const sourceMap = await readFile(join(webLib, 'client.js.map'), 'utf8');
  • 写入本地文件
    packages/channels/build.mjs:22
    await writeFile(join(root, 'lib', 'client.js.map'), sourceMap, 'utf8');
  • 发起网络请求
    templates/channel-adapter/src/upstream.ts:69
    raw = await this.options.transport.request(
  • 发起网络请求
    templates/channel-adapter/src/upstream.ts:87
    return this.options.transport.request('/message/send', {
  • 发起网络请求
    templates/channel-adapter/src/upstream.ts:94
    return this.options.transport.request('/message/media', {
扫描于 2026/11/3(0 天前) · 范围 全包扫描 · 来源 GitHub 仓库

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

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

界面预览

4 张 · 点击查看大图

功能亮点

  • 接入微信QQ钉钉飞书
  • 扫码授权统一配置
  • 收发图片与文件
展开完整介绍(119 字)↓

把微信 / QQ / 钉钉 / 飞书 / Telegram 接入 DeepSeek Harness:统一配置、扫码授权,直接在各 IM 与 Agent 对话;支持图片与文件收发,Agent 可读取 PDF、DOCX、XLSX 和文本内容。

README

由 DeepSeek 最新模型翻译生成
dsh-channels 将微信、QQ、钉钉、飞书和 Telegram 接入 DeepSeek Harness 多渠道集成,统一配置,并在各平台与 Agent 对话 支持图片与文件收发,Agent 可直接读取 PDF、DOCX、XLSX 和文本内容 本项目是社区维护的 DeepSeek Harness 渠道扩展,不是 DeepSeek Harness 或各消息平台的官方项目。项目参考各平台面向 OpenClaw 提供的渠道接入方案,结合官方 SDK / API 适配到 DeepSeek Harness;运行时不依赖 OpenClaw。 效果预览 接入后,在 Harness Web“设置 → 渠道”面板统一配置与扫码授权,并在各平台对话框中直接与 Agent 对话(图片来源:docs/ScreenShot): Harness Web · 渠道设置与 Telegram 接入示例(图片与文件收发、附件内容读取) 各平台对话框 能力总览 | 渠道 | 文本 | 图片 | 文件 | 流式回复 | 状态 | | 微信 | 支持 | 收发 | 入站读取 | - | ✅ | | QQ | 支持 | 收发 | 收发 | 支持 | ✅ | | 钉钉 | 支持 | 收发 | 收发 | 支持 | ✅ | | 飞书 | 支持 | 收发 | 收发 | 支持 | ✅ |
展开完整文档(README 剩余 1 节)
dsh-channels

将微信、QQ、钉钉、飞书和 Telegram 接入 DeepSeek Harness

多渠道集成,统一配置,并在各平台与 Agent 对话

支持图片与文件收发,Agent 可直接读取 PDF、DOCX、XLSX 和文本内容

本项目是社区维护的 DeepSeek Harness 渠道扩展,不是 DeepSeek Harness 或各消息平台的官方项目。项目参考各平台面向 OpenClaw 提供的渠道接入方案,结合官方 SDK / API 适配到 DeepSeek Harness;运行时不依赖 OpenClaw。

效果预览

接入后,在 Harness Web“设置 → 渠道”面板统一配置与扫码授权,并在各平台对话框中直接与 Agent 对话(图片来源:docs/ScreenShot):

Harness Web · 渠道设置与 Telegram 接入示例(图片与文件收发、附件内容读取)

各平台对话框

能力总览

| 渠道 | 文本 | 图片 | 文件 | 流式回复 | 状态 |
| 微信 | 支持 | 收发 | 入站读取 | - | ✅ |
| QQ | 支持 | 收发 | 收发 | 支持 | ✅ |
| 钉钉 | 支持 | 收发 | 收发 | 支持 | ✅ |
| 飞书 | 支持 | 收发 | 收发 | 支持 | ✅ |
| Telegram | 支持 | 收发 | 收发 | 支持 | ✅ |

- 支持视觉的多模态模型可直接识别图片;PDF、DOCX、XLSX 和文本附件可提取内容供 Agent 读取(入站单文件上限 100 MiB);音频和视频暂为降级处理。

使用前须知

- 确认 npx @deepseek-ai/dsh 可运行,且 Harness Web 普通会话可正常对话。
- 需要 DeepSeek Harness 0.1.5-rc.2 与 Node 22.19+(版本对照见兼容矩阵)。
- 渠道会话通常使用 Workspace Write;仅在确需访问 Workspace 外文件且信任当前任务时启用 Full access。
- 项目仍在快速迭代,升级前请备份数据。

安装

安装稳定版 bundle
npx @deepseek-ai/dsh plugin --profile web add -w @wsz987/dsh-channels@latest

检查 bundle 是否合并到 profile
npx @deepseek-ai/dsh --profile web --dump-config

启动 Harness Web
npx @deepseek-ai/dsh web

安装完成后,在 Harness Web 的“设置 → 渠道”中配置或登录需要使用的渠道,并完成“安全访问”设置。

更新与卸载

安装、更新和卸载时请保留 -w 参数。插件需与 Harness 版本匹配,升级时先升 Harness,再更新插件:

升级 Harness(当前基线在 npm 的 next 标签)
npm i -g @deepseek-ai/dsh@next

同一版本线内更新插件
npx @deepseek-ai/dsh plugin --profile web update -w @wsz987/dsh-channels

跨版本线升级:用 add 重装
npx @deepseek-ai/dsh plugin --profile web add -w @wsz987/dsh-channels@latest

卸载bash
npx @deepseek-ai/dsh plugin --profile web remove -w @wsz987/dsh-channels

各版本要求的 Harness 见兼容矩阵。

配置与登录

| 渠道 | 必要信息 | 登录方式 |
| 微信 | 无 | 扫码登录,凭据自动持久化 |
| QQ | AppID、AppSecret | QQ 开放平台创建机器人 |
| 钉钉 | clientId、clientSecret(可选) | 扫码或在钉钉开放平台创建应用 |
| 飞书 | AppId、AppSecret | 在飞书开放平台创建应用,或扫码创建智能体 |
| Telegram | Bot Token | 在 @BotFather 创建机器人并填写 Token |

Telegram:需 Bot API 10.2+;只支持 getUpdates 长轮询,启动时会调用 deleteWebhook 移除该 Bot 已配置的 webhook,不要让同一 Bot 同时承担其他 webhook 消费者。

必做:配置安全访问

在 设置 → 渠道 → 安全访问 确认谁可以通过 Bot 使用本机 Agent。默认不会把「能给 Bot 发消息的人」当作已授权用户。

- 微信:自动使用当前扫码账号。
- 钉钉 / 飞书 / Telegram:点击「识别我的账号」,按提示私聊 Bot 发送一次识别指令,再回本地页面确认。
- QQ:私聊仅创建者可用,无需识别;群聊需单独配置。
- 群聊默认关闭,需手动添加允许的群,或显式开启「所有群组」。

未完成确认时,渠道可能显示已连接,但消息不会进入 Agent。

常用操作

渠道指令

任意渠道会话内可直接发斜杠指令,由 Harness 官方命令系统解析执行:

部分指令暂不支持在群聊中使用,具体可用范围以当前渠道和会话为准。

| 指令 | 说明 |
| /stop | 立即终止当前任务(最高优先级:不等渠道排队消息,直接取消当前 Agent) |
| /new | 开启全新会话(遇到 bug 可以尝试使用) |
| /help [command] | 查看当前会话实际生效的命令,或单个命令的用法 |
| /status | 查看当前 Session / Agent / 模型状态 |
| /version | 查看当前 bundle 版本、Harness 兼容基线与新版本提示 |
| /models [provider] | 查看 Harness 当前注册的模型 Provider 及其模型 |
| /model [<provider> <model> [<reasoningEffort>]] | 查看或切换当前会话模型 |
| /mirror [on\|off] | 开关镜像模式:开启后,在 Web / CLI 发起的回复也会同步发送到本会话(默认关闭,状态持久化) |
| /bind <会话ID> [confirm] | 把本对话重绑到一个已存在的会话(先解析并列出影响,确认后加 confirm 执行) |

- /help 会列出当前可用的全部指令(含宿主加载的官方插件指令);未识别的斜杠指令直接提示「未知命令」,不会发给模型。

/model 示例 text /model # 查看当前会话解析到的模型 /model deepseek deepseek-chat /model openai gpt-5.6 high # 指定 reasoning effort

/model 切换当前会话,并同步写入 Harness 的全局默认模型,供后续新会话使用。

Workspace 隔离

默认已按「渠道 / 账号」自动隔离各渠道会话的文件,无需配置。如需复用 Harness 启动目录或关闭隔离,编辑 $DSH_HOME/profiles/web/cordis.patch.yml: yaml
- id: channels-harness
name: '@wsz987/dsh-channels/harness'
inject: [channels, agents, agentDefaultModel, agentPresets, llm, commands]
config:
workspace:
mode: channel-account # channel-account(默认)| host-cwd | disabled autoCreate: true

Roadmap

- 完善渠道内的会话管理和异常恢复体验。
- 接入更多即时通讯渠道(画饼中)。

从源码运行 bash
git clone https://github.com/wsz987/dsh-channels.git
cd dsh-channels
pnpm install
pnpm build
pnpm channels
pnpm web:debug

- pnpm channels 可指定渠道,例如 pnpm channels weixin qq。
- 修改代码后重新构建并重启 Harness;切回 npm 版本前运行 pnpm channels:clean。

提交前运行完整门禁: bash
pnpm ci:check

📚 文档

- 架构总览
- 公共/统一代码设计
- 多渠道规划
- 架构决策记录(ADR)
- 入站访问控制(安全)
- 渠道身份映射(安全)
- 第三方渠道接入指南
- 发布流程
- 兼容矩阵(Harness / Node / 必测场景)
- 微信 live 验证手册
- 渠道权限核验(接口/权限/上游漂移对照)
- 第三方版权声明
- 各子包 README:packages//README.md(每个包的安装、配置、开发说明)

🤝 二次开发规范

参考主流开源项目(Koishi / Wechaty 风格)的分层约定:适配器层零侵入核心,核心层不感知平台。

仓库结构

| 目录 | 职责 |
| packages/channels | 对外 bundle @wsz987/dsh-channels(聚合 patch) |
| packages/channel-core | Channel Contract:类型 + ctx.channels Service + defineChannelAdapter |
| packages/channel-harness | 渠道 ↔ Harness 桥;只保留可选 ChannelAttachmentProvider 端口(旧名 ChannelFileProvider 为兼容别名) |
| packages/channel-files | Generic Attachment compatibility backend:会话隔离存储、legacy 兼容解析、read_channel_attachment 兼容工具 |
| packages/channel-control | 控制面:配置 / 凭据 / 扫码授权 / 运行时生命周期 |
| packages/channel-{weixin,qq,dingtalk,lark,telegram} | 五个内置渠道适配器 |
| packages/channel-{compat,testkit,verify,web} | 契约验证 / 测试工具 / Web 可视化 |
| templates/channel-adapter | 新渠道脚手架 |

使用核心包(channel-core)

适配器只需实现 ChannelAdapter 契约,核心自动完成注册 / 挂载 / 回执 / 健康检查: ts
import { defineChannelAdapter } from '@wsz987/channel-core';

export default defineChannelAdapter({
id: 'my-channel',
capabilities: {
text: true, image: false, file: false,
audio: false, video: false, markdown: false,
cards: false, reactions: false, threads: false,
streaming: 'buffered', // native | edit | buffered
},
async start(ctx) { / 连接平台、ctx.emit('message', ...) / }, async stop() { / 幂等清理 / }, async send(target, message) { / 发送 / }, // 可选:createReply 流式 / beginAuth+pollAuth 扫码 / getHealth 健康 });

三条红线(详见 docs/adapter-authoring.md):

1. 不在 core 里按渠道做特判——渠道差异由 core 按 capabilities 协商处理
2. 适配器禁止调用 Harness Agent API(ctx.agents...)
3. 平台原始 payload 必须映射为结构化 MessagePart,禁止直塞给模型

契约表达不了的需求 → 上报 contract gap,禁止改 channel-core / channel-harness。

新增渠道四步

1. 复制 templates/channel-adapter 为 packages/channel-<name>,实现 defineChannelAdapter(含 config / transport / mapper)
2. 在 packages/channels/cordis.patch.yml 加一行(pnpm channels 自动识别新渠道)
3. pnpm build && pnpm typecheck && pnpm test
4. pnpm verify packages/channel-<name> --test 跑契约验证(fixtures + manifest + 测试套件)

新增渠道指令

指令以 factory 形式放在 packages/channel-harness/src/commands/,加入 commandFactories 数组即随 Agent 自动注册(官方 @deepseek-ai/dsh-commands 格式,无需改 bridge): ts // packages/channel-harness/src/commands/reset.ts
export function createResetCommand(deps: ChannelCommandDependencies): CommandDefinition {
return {
name: 'reset',
description: 'Reset the current session',
async handler(invocation) {
if (invocation.rawInput.trim().length > 0) return { kind: 'error', text: '用法:/reset' };
if (invocation.agent.status !== 'idle') return { kind: 'error', text: '当前会话仍在运行,请稍后再试。' };
// ...调用 deps 提供的 bridge 能力
return { kind: 'success', text: '已重置会话。' };
},
};
}

- commandFactories 是唯一注册点:['createNewCommand', createResetCommand]
- 需要 bridge 新能力时,在 ChannelCommandDependencies 加一个方法(平台无关),bridge 侧实现即可

提交与发布

- Commit:Conventional Commits(feat(scope): ... / fix(scope): ... / docs: ...),scope 用包名(如 channel-qq)
- PR:过 CI(build + typecheck + test + 契约验证 + live gate 前检)
- 发布:pnpm changeset 记录变更 → CI 合入后 pnpm release(Changesets 自动发版,见 docs/release.md)

🙏 致谢

本项目基于以下开源项目:

- deepseek-ai/deepseek-harness —— DeepSeek Harness(@deepseek-ai/)
- DingTalk-Real-AI/dingtalk-openclaw-connector —— 钉钉渠道插件(@dingtalk-real-ai/dingtalk-connector)
- tencent-connect/openclaw-qqbot —— QQ 机器人渠道插件(@tencent-connect/openclaw-qqbot)
- larksuite/openclaw-lark —— 飞书渠道插件(@larksuite/openclaw-lark)
- Tencent/openclaw-weixin —— 微信渠道插件(@tencent-weixin/openclaw-weixin)

License

MIT © 2026 wsz987
预览分享卡片长什么样 ↓wsz987/dsh-channels
分享 · DeepSeek Harness Hub
wsz987/dsh-channels

把微信 / QQ / 钉钉 / 飞书 / Telegram 接入 DeepSeek…

回到顶部