中文EN

dsh-dingtalk-self

notifynpmMIT

以你本人钉钉身份自动回复私聊:在绑定的 DSH 工作区里查资料生成回答,通过 dws CLI 以本人身份发出。

下载量 / Downloads
453

安装

dsh plugin --profile web add dsh-dingtalk-self

沙箱测试

这个插件还没测过。提交测试 →

README

dsh-dingtalk-self

English TL;DR — A DeepSeek Harness (dsh) plugin that answers DingTalk direct messages as your own account. It watches the chats you pick, asks the agent (bound to a DSH workspace) to look the answer up, and sends it back through the dws CLI with an opt-out marker line. No bot account, no forwarded questions. Requires macOS + dws auth login; replies are Markdown, and tables/charts/flow diagrams can be rendered to PNG by the host.

DSH 插件:钉钉代答。别人在钉钉问你,agent 自己去你绑定的工作区里查资料,然后以你本人身份直接答复对方——

你不用把问题转发给 agent,对方收到的也是「你」发的普通消息,不是机器人、不是数字员工账号。


它和普通钉钉插件的区别

· 机器人 / 自建应用插件 · 本插件

发送身份 · 机器人 · 你本人

读取范围 · 机器人被拉进的群 · 你的私聊

AI 角标 · 有 · 关闭(--ai-tag=false)

回复内容来源 · 插件自带 prompt · 你绑定的 DSH 工作区

权限 · 插件的权限 · 工作区只读(仅可查看)

链路:

对方私聊你
   ↓  dws chat message list --open-dingtalk-id   (以你身份读)
过滤 / 去重 / 合并
   ↓  投递到绑定的 DSH 工作区(仅可查看)
生成回复
   ↓  出站护栏(禁代码 / 禁路径 / 禁内网地址)
dws chat message send --ai-tag=false --idempotency-key
   ↓
对方看到「你」发的普通消息

安装

# 1. 装进你的 profile(路径改成你的实际目录;日常用桌面版就是 desktop)
dsh plugin --profile desktop add ~/projects/dsh-dingtalk-self

# 2. 重启 DSH App,然后刷新页面
# 3. 打开 设置 → 钉钉代答(设置侧栏里,order=45)

装好后检查两处(缺一不可):

python3 -c "import json;d=json.load(open('$HOME/.dsh/profiles/desktop/package.json'));print('deps:', 'dsh-dingtalk-self' in d['dependencies'], 'bundles:', 'dsh-dingtalk-self' in d['dsh']['profile']['bundles'])"
cat ~/.dsh/data/dsh-dingtalk-self/boot.log   # 应有一行 version=0.2.0 ... schema=yes
  • 客户端半边(设置页)由 package.json 的 dsh.client 声明,普通 JS、无需构建;

重装/改代码后必须重启 App 才会重新装配(实测 Host 侧改代码不会热重载插件)。

卸载:

dsh plugin --profile web remove dsh-dingtalk-self
dsh 不在 PATH 时用全路径:
/Applications/DeepSeek\ Harness.app/Contents/Resources/runtime/cli/bin/dsh

前置条件(缺一不可)

1. dws 已安装(dws --version 有输出)

2. 已完成个人 OAuth 登录:

dws auth login          # 扫码授权
dws auth status         # 应返回 "authenticated": true

⚠️ dws auth login 必须在你自己的终端里执行 —— 在 Agent 沙箱里跑会因无法写 ~/.dws 而 EPERM。

3. 有一个可绑定的 DSH 工作区(侧栏里那个,例如 my-workspace)


设置页(client 半边)

设置 → 钉钉代答 一页完成全部操作,不需要手改配置文件:

区块 · 内容

运行状态 · dws 登录态 / 本人 userId、急停开关、立即检查一次、上次检查(读了几条 / 新私聊几条 / 出了什么)、重新诊断、刷新、版本、配置来源、计数

监听分组 · 一个工作区挂多位联系人:每组一张卡 = 工作区下拉 + 成员列表(从钉钉通讯录搜索选人,姓名/ID 只读)+ 组级「允许真实发送」。每位联系人使用独立会话,互不串上下文

行为设置 · 总开关、三档模式、轮询间隔、每小时上限、回复字数上限、静默时段

模拟回答 · 粘贴一条对方可能发来的消息,走真实生成通道跑一遍但不发送,看它会怎么答(可能耗时 1–3 分钟)

待确认草稿 · 每条可「发送」/「丢弃」

最近草稿 / 最近审计 · 新的在前,用于回看为什么回/为什么没回

自检 · 一键六项:Node、状态目录、dws 可执行、个人身份登录、工作区、联系人绑定

数据通道(契约见 [docs/client-host-api.md](docs/client-host-api.md)):客户端不直连宿主服务,

而是访问插件自己注册的五个同源 HTTP 端点:

GET  /dsh-dingtalk-self/api/state
POST /dsh-dingtalk-self/api/config     { patch }
POST /dsh-dingtalk-self/api/pause      { paused }
POST /dsh-dingtalk-self/api/confirm    { contact, action }
POST /dsh-dingtalk-self/api/diagnose
POST /dsh-dingtalk-self/api/contacts/search   { query }
POST /dsh-dingtalk-self/api/cycle              {}   // 立即检查一次
POST /dsh-dingtalk-self/api/test-reply         { message }   // 模拟回答,不发送

配置存放位置(当前 DSH 版本):本机 settings 服务没有 register,describe() 也不返回插件条目,

所以配置落在 ~/.dsh/data/dsh-dingtalk-self/config.json,设置页里「配置来源」会显示这一点。

宿主若提供可写的 settings.update,代码会优先走 DSH 原生 settings(响应里的 configSource: "settings")。


配置

设置页里的字段与含义(同一份 schema 也是 lib/settings.js 里的 Config):

字段 · 默认 · 说明

enabled · false · 总开关,默认关

mode · draft · draft 只出草稿 / confirm 等人工确认 / auto 直接发

selfUserId · 空 · 你的 userId,用于过滤自己发的消息

contacts[] · [] · 监控名单,空 = 什么都不做

contacts[].name · — · 联系人名,用于日志与会话标题

contacts[].openDingTalkId · — · 对方 ID(设置页从通讯录选人时自动带入,发送时免反查)

contacts[].workspaceId · — · 绑定到哪个 DSH 工作区(存工作区 id,界面显示标题;同一个人一个条目,同一工作区多人 = 多条 workspaceId 相同的联系人)

contacts[].autoReply · false · 是否允许真实发送

contacts[].sessionId · 空 · 指定要接管的会话;留空时由插件在首次生成后自动记录(state.sessions),每人的上下文互相隔离

pollIntervalSeconds · 60 · 轮询间隔(≥10)

initialLookbackSeconds · 900 · 首次启用(还没有游标)时回看多久的私聊;之后只看 overlapSeconds

mergeWindowSeconds · 20 · 连发合并窗口

quietHours · 关 · 静默时段,命中转草稿

limits.maxRepliesPerHour · 10 · 每人每小时上限

limits.minSecondsBetweenReplies · 30 · 两条之间最小间隔

limits.maxReplyChars · 1200 · 回复长度上限;超过会被截断并在末尾加「…」

replyFormat · markdown · 回复格式:markdown(钉钉渲染加粗/列表/小标题)/ text(纯文本 • 列表)

replyMarker · (本条由助手代答) · 出站标识:附在每条发出去的消息末尾,让对方知道不是本人手打;留空则不加

guard.* · 全开 · 出站护栏开关与禁用词

agent.kind · headless · headless(默认,已验证)/ session(宿主内,待适配)

agent.provider / agent.model · 空 · 生成回复用的模型;留空 = 跟随 DSH 当前默认模型(设置页可下拉选择)

agent.reasoningEffort · 空 · 推理档位(low/medium/high/max),留空用模型默认

agent.readOnly · true · 只读:生成回复时只在工作区查资料,不改文件(子进程注入 DSH_PERMISSION_MODE=read-only)

agent.profile · headless · headless 用的 profile

agent.persona · 简洁自然 · 口吻补充说明

agent.timeoutSeconds · 240 · 单次生成超时(秒)。查资料型回答通常要 1–2 分钟,别调太小

开起来的最小步骤:enabled=true → 加一条 contacts → mode=draft → 先看草稿。


回复排版(Markdown 优先)

dws chat message send 的默认消息类型就是纯文本 / Markdown,钉钉客户端会渲染加粗、列表、小标题,所以默认按 Markdown 发。

config.replyFormat 可选 markdown(默认)/ text,两层处理:

层 · 做法

提示词 · markdown 模式:先一句结论 → ### 小标题分组 → - 列表、关键名词 加粗;text 模式:结论 + • 要点

出站整理 · lib/core/format.js:markdown 模式只归一化(标题统一 ###、列表统一 - 、1)→1.、压缩空行);text 模式才去记号、• 列表、长段落按句折行

实测同一个接口问题的输出(markdown 模式,钉钉会渲染成加粗/列表/小标题):

APP 端提交工单的接口,写入工单主表并推进状态。

### 主要作用
- 接收 APP 提交的工单,写入 **work_order**
- 含工单号、客户信息、处理意见与附件
- 按入参把工单状态推进到 **DONE**

### 顺带做的事
- 把联系人回写到对应主体
- 生成一条待发通知记录
- 异步重新生成这张工单的 **PDF**

### 几个规则
- 按租户配置 **SIGN_MODE** 校验附件:**1** 电子签、**2** 纸质签、**3** 双要求
- 附件不齐不报错:先保存,状态不动,提示待补齐
- 同一工单重复调用只补录,一单只留 **1** 条记录

注意:通知只写待发记录,状态为未发,本接口不同步

…(truncated)

以上内容来自 npm 上的 README,我们只做格式化,不改内容。

版本

npm 上共发布:2,最后更新 2026-10-30

链接

GitHub · Homepage · npm

同类插件