DingTalk IM channel via Stream-mode WebSocket: each chat drives its own tooled agent; replies stream back as messages, no public callback URL needed.
Install
# from npm (prebuilt)
dsh plugin --profile web add dsh-dingtalk-channel
# from GitHub (first run asks for allowBuilds approval — follow the hint, retry)
dsh plugin --profile web add github:ttmouse/dsh-dingtalk-channel
Any plugin you install runs third-party code with your own permissions — it can read your files, use your credentials, and reach the network, and tool approvals don’t sandbox it. GitHub-sourced plugins also run build scripts at install time — pnpm blocks those until you allow them, so an install can stop with ERR_PNPM_GIT_DEP_PREPARE_NOT_ALLOWED or ERR_PNPM_IGNORED_BUILDS; dsh prints the exact key to add under allowBuilds in your profile’s pnpm-workspace.yaml, and the install works on the next run. Allowing a build is a trust decision: only install sources you trust, and pin a commit (github:owner/repo#sha).
README
This plugin publishes its README in Chinese only.
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
Links
More in this category
xmanrui/dsh-im★ 1548
Connect IM bots to DeepSeek Harness via QR codes or bot credentials (9 channels: Feishu, WeChat, DingTalk, WeCom, QQ, Slack, Telegram, Discord, and WhatsApp).
shaobeichen/dsh-pocket★ 1415
Remote phone access to the DSH Web UI: scan a QR code for LAN or public (cloudflared tunnel) access with real-time sync, a mobile-adaptive layout, and a settings tab.
inclusionAI/Avernet#deepseek-harness-channel-bcn★ 574
Connects DeepSeek Harness to Avernet's Bot Collaboration Network over WebSocket V2, with automatic onboarding, isolated agent sessions, tool-call events, and multi-bot routing tools.
omdsh-dev/dsh-notification★ 86
Desktop notifications for turn completions, with per-outcome controls and keyword rules.
whyihaveyou/dsh-suite#plugin-notify★ 57
IM webhook and local notifications on turn completion, errors, or approval (Feishu/WeCom/DingTalk/Slack/Discord/custom).
omdsh-dev/dsh-lark★ 55
Lark/Feishu bot channel for DeepSeek Harness: each chat drives its own agent, and tool approvals, model questions, and plan reviews return as cards answered by a button or a reply. Switch workspace and model from the chat (`/cd`, `/model`, `/new`), and run several bots that keep separate sessions and can hand turns to each other in one group.
Community comments
Comments are public GitHub Discussions. Loading them connects to GitHub and Giscus; a GitHub account is required to post.