ttmouse/dsh-dingtalk-channel
DingTalk IM channel for DeepSeek Harness: Stream-mode bot that turns each chat into a tool-capable agent — emotion read-receipts, silent process, durable sessions
Listed
0
Notify
Bundle verified
What it does
DingTalk IM channel via Stream-mode WebSocket: each chat drives its own tooled agent; replies stream back as messages, no public callback URL needed.
Best for
- Teams that want trusted users to operate tool-capable DSH agents from DingTalk private or group chats.
- Deployments that cannot expose a public callback URL and prefer DingTalk Stream-mode WebSocket connectivity.
- Chat workflows needing durable per-chat or per-sender sessions, allowlists, mention gating, and in-chat approval replies.
Not ideal for
- Workflows that need image or file forwarding, which is not implemented.
- Users who need tool-call reasoning or typing-style progress streamed into the chat; only receipts or reactions and the final answer are sent.
- Deployments without a DingTalk internal app, ClientID, and ClientSecret, or where chat participants must not inherit the host session's tool permissions.
- Workflows requiring in-chat /cd, /model use, or /ws switching.
README
dsh-dingtalk-channel
DeepSeek Harness 的钉钉 IM 机器人 channel——每条单聊/群聊背后都是一个真正带工具的 agent,消息即入口,回复回到对话里。
通过钉钉官方 Stream 模式(WebSocket 长连接)把钉钉「机器人」接入 dsh。不需要公网回调地址、不需要服务器配置 webhook,机器人私聊或群里 @ 它即可驱动完整 agent(带 bash、read、edit、skills 等工具,按 preset 挂载)。
架构沿袭 dsh-lark-channel(BSD-3-Clause)的 channel 设计:窄宿主契约 + 传输层端口 + 会话爬梯 + 事件渲染。
✨ 特性
- 🤖 一会话一 agent——会话 id 由会话键确定性派生(
ding-<chatId>),跨重启稳定;sessionScope: chat-sender可让共享群里每人一个 agent - ⚡ 即时反馈——每条消息先回执「🤔 已收到」,再流式到达最终答案(钉钉无打字指示,回执是唯一即时反馈)
- 🤫 静默过程——中间过程只在回执/思考表情里暗示,agent 调用 bash/read/edit 等工具不发聊天消息,只把最终答案发成 markdown
- 🛡️ 访问策略——单聊/群聊各自
senderAllowlist/groupAllowlist,群聊requireMention;审批按聊天回复「允许一次 / 拒绝」结算 - 📡 长连接自愈——SDK 自动重连,断线事件落在操作台
- 💬 命令——
/ping/help/status/stop/new,未知/命令下传给宿主commands运行时(有/compact等时可用) - 🩺 可观测——拒绝/失败/断线全部 notify 到进程 stderr + 宿主日志
🚀 快速开始
1. 钉钉侧准备(一次性)
- 打开 钉钉开发者后台,创建企业内部应用,记下 ClientID(AppKey) 与 ClientSecret(AppSecret)。
- 应用能力 → 添加应用能力 → 机器人,完善机器人信息,消息接收模式选 Stream 模式,发布应用。
- 把机器人拉进目标群(或让成员私聊它)。群聊中机器人默认只收到 @ 它的消息。
2. 安装插件
# 从 npm
dsh plugin --profile web add dsh-dingtalk-channel
# 或从 GitHub(自动构建)
dsh plugin --profile web add github:ttmouse/dsh-dingtalk-channel
# 或从源码/本地目录(先 npm install && npm run build 产出 lib/)
dsh plugin --profile web add /绝对路径/dsh-dingtalk-channel
3. 配置凭证
~/.dsh/profiles/web/cordis.patch.yml 里覆盖该行(也可用 !!js process.env.… 走环境变量):
- id: dingtalk-channel
name: 'dsh-dingtalk-channel'
config:
clientId: !!js process.env.DINGTALK_CLIENT_ID
clientSecret: !!js process.env.DINGTALK_CLIENT_SECRET
botName: 我的助手 # 用于剥离群消息 @ 前缀(不配则剥离首个 @… 词元)
# preset: standard # 挂进会话 agent 的 preset(部署组合了 roster 时)
# cwd: /path/to/workspace # 默认宿主进程 cwd
# sessionScope: chat # chat-sender 让共享群里每人一个 agent
# sendReceipt: true
# emotion: true # 消息上贴 🤔思考中 表情,回复完成自动撤回(替代文字回执)
requireMention: true
export DINGTALK_CLIENT_ID='ding...'
export DINGTALK_CLIENT_SECRET='...'
dsh web
dsh web 启动日志里出现 dsh-dingtalk-channel 的凭证校验通过(无缺凭证告警)后,私聊机器人发 /ping 应收到 pong。
⚙️ 配置
| 字段 | 默认 | 含义 |
|---|---|---|
clientId / clientSecret
|
— | 钉钉应用凭证(必填) |
botName |
— | 机器人昵称;配置后只在群消息首个 @ 匹配时才剥离 |
cwd |
宿主 cwd | 会话 agent 工作目录 |
workspaceRoots |
[] |
/cd 可达目录前缀(空=任意) |
provider / model
|
宿主默认 | 会话 agent 模型路由 |
preset |
roster 默认 | 会话 agent 挂载的 preset |
sessionScope |
chat |
chat / chat-thread(=chat) / chat-sender
|
sendReceipt |
true |
每条消息先发回执(emotion 开启时被替代) |
emotion |
true |
消息上贴 🤔思考中 表情表示已读/处理中,回复完成自动撤回 |
denyTools |
[ask_user_question, exit_plan_mode] |
会话 agent 禁用的工具 |
requireMention |
true |
群聊仅被 @ 时响应 |
senderAllowlist |
[] |
单聊 staffId 白名单(空=应用可见范围内任何人) |
groupAllowlist |
[] |
群会话白名单(空=任何群) |
approvers |
[] |
可回答审批的 staffId(空=能驱动该会话的人) |
💬 命令
| 命令 | 作用 |
|---|---|
/ping |
连通性检查 |
/help |
列出命令 |
/status |
会话/目录/模型/运行状态 |
/stop |
取消当前生成 |
/new |
开启新会话(历史保留) |
🧠 审批
agent 需要批准时(approval/request),channel 在对话里发审批消息,回复「允许一次」放行一次、「拒绝」取消;abort 时结算为取消。默认 denyTools 已禁用 ask_user_question / exit_plan_mode(答案到不了本渠道的人类交互工具),模型会被引导直接在回复里提问。
⚠️ 已知限制
- 钉钉无思考过程/打字机卡片:本 channel 故意不在聊天里发工具调用过程消息,只发最终答案(回执/思考表情作为唯一的即时反馈),比飞书原生 CoT 朴素。
-
图片/文件暂不转发:
attachImages未实现(钉钉图片需先下载,v0.1 不做)。 - 无扫码注册:凭证必须在开发者后台创建(钉钉无公开的扫码建应用流程)。
-
无
/cd//model use//ws:工作区切换与模型热切换 v0.1 未实现(配置层字段已预留)。 - 群消息去 @:
botName配置后只在首个 @ 匹配时剥离;不配置则剥离首个@…词元。 - 审批与轮次并发:宿主 agent 自带排队;本 channel 每个会话最多一个待决审批。
🔐 权限说明
-
chat agent 与宿主会话同权限:能执行 bash、读写文件(read/edit/write)、git、网络与技能(skills)——凡是你本地
dsh会话能做的,聊天里都能做。请把机器人只加进可信的人/群。 -
访问收窄(只收窄不兜底):
senderAllowlist限单聊发送者、groupAllowlist限群会话、approvers限审批人;最终以钉钉应用的可见范围为准。 -
默认禁用
ask_user_question/exit_plan_mode(答案到不了本渠道的人类交互工具),审批改为对话内回复「允许一次 / 拒绝」。
🔌 关闭方式
-
停用:从 profile 的
dsh.profile.bundles移除dsh-dingtalk-channel,重启dsh web即不再连接钉钉。 -
卸载:
dsh plugin --profile web rm dsh-dingtalk-channel(或pnpm remove dsh-dingtalk-channel),重启。 - 彻底下线:钉钉开发者后台删除该应用/机器人。
📄 许可证
MIT —— 见 LICENSE。
开发
npm install
npm run typecheck # tsc --noEmit
npm run build # tsc → lib/
npm test # vitest
Frequently Asked QuestionsFAQ
Use the verified command dsh plugin --profile default add github:ttmouse/dsh-dingtalk-channel in a DSH-enabled shell. The command resolves the public package metadata and keeps the plugin attached to the catalog identity shown on this page.
Compatibility follows the bundle and profile status shown above. If a profile is not detected, keep the plugin disabled there and check the repository documentation before enabling it in production.
The GitHub link and activity metadata are the source of truth for releases and maintenance. Revisit this page after a new release to confirm the catalog has observed the latest version.