dsh-email-notify
Verifieddsh-email-notify · v0.4.6 · Apache-2.0 · Web UI
DeepSeek Harness (DSH) plugin — send SMTP email (QQ Mail etc.) for task-board settlements, conversation completions, pending approvals, and pending ask-user questions; ships a first-level Web GUI settings page with per-notification templates, session-name
Install
dsh plugin add dsh-email-notify Confirm the layer applied with dsh --profile default --dump-config — see the install guide.
Source
Tags
Readme
📧 dsh-email-notify
任务或对话完成时,让 DeepSeek Harness 替你发一封邮件。
DeepSeek Harness 的开源任务通知插件 · 简体中文 · English
dsh-email-notify 是 DeepSeek Harness(DSH)的邮件通知插件,支持以下触发方式:
- 官方自动化任务完成:监听 schedule 注入的
user/message,在任务轮次结束(turn/end)后发送任务完成邮件。 - 对话完成通知:在对话输入框左侧开启「邮件通知」开关后,当前会话每完成一轮都会发送一封完成邮件。
- 审批/提问提醒:等待用户审批或回答
ask_user_question时发送提醒邮件。
自动化任务 user/message → 标记任务轮次 → turn/end → 发送任务完成邮件
└→ 同轮抑制会话完成邮件
用户普通 turn/end → 检查 notify-sessions.json → SMTP 发送完成邮件
✨ 特性
- 🔔 自动化任务完成通知:官方定时/自动化任务结束后发送任务完成邮件。
- 💬 对话完成通知:在对话输入框左侧开启「邮件通知」开关,当前会话每完成一轮自动发信;开关状态按会话持久化。
- ⏳ 审批邮件提醒:设置中开启后,等待用户审批时发送提醒邮件;可分别选择「工作区审批提醒」与「Auto review 转手动审批提醒」,默认关闭。
- ❓ 提问邮件提醒:设置中开启后,Agent 使用
ask_user_question等待用户回答时发送提醒邮件,正文包含问题与选项;默认关闭。 - 🚫 任务轮次去重:自动化任务执行的那一轮不会再发会话完成邮件;任务结束后用户继续对话,会话通知恢复正常。
- 💾 开关状态持久化:对话开关状态保存在
~/.dsh/email-notify/notify-sessions.json。 - 🎛️ 一级设置页:在 DSH 设置侧边栏直接显示「邮件通知」,无需进入「Web UI 插件」子级,全部配置在页内完成。
- 📨 一键测试邮件:配置完成后点一下按钮即可验证 SMTP 是否可用。
- 🏷️ 会话名称优先:通知邮件主题与正文使用会话名称;会话 ID 作为会话属性放在正文中。
- 🧩 模板可自定义:任务通知、对话通知、审批通知、提问通知分别有独立的主题/正文模板,默认已填好当前格式。
- 👥 多收件人:收件人支持逗号、分号或换行分隔。
- 🔒 安全优先:所有 HTTP API 仅接受 loopback 请求;授权码以 secret 声明,浏览器侧脱敏显示。
- 🤖 Agent 公告可关:默认向 Agent 系统提示注入插件说明,可在设置中关闭。
📦 安装
前置依赖
- DeepSeek Harness(含 Web GUI 与官方桌面端),DSH
0.1.1-rc.x/0.1.5-rc.x/0.2.0-rc.x/0.2.1-rc.x——插件对四代客户端/宿主接缝都做了适配,装同一份构建即可 - Node.js
^22.19.0 || >=24 - pnpm
10.x - 自动化任务通知依赖 DSH 官方 schedule(
0.2.1-rc.x默认包含);任务看板轮询已停用
从源码安装
git clone https://github.com/MCviseron/dsh-email-notify.git
cd dsh-email-notify
pnpm install # prepare 钩子会自动执行 pnpm build
dsh plugin --profile web add "$PWD"
Windows Git Bash 下
$PWD会展开为绝对路径;如果dshCLI 不在 PATH 中,可改用:npx -y @deepseek-ai/dsh plugin --profile web add "$PWD"
安装完成后校验并重启:
dsh --profile web --dump-config # 确认 bundle 中包含 dsh-email-notify
dsh web
刷新 Web GUI,打开设置,即可在侧边栏看到「邮件通知」一级设置页。
卸载
dsh plugin --profile web remove dsh-email-notify
卸载后刷新 Web GUI 即可;本地源码目录不会被删除。
🚀 快速开始(QQ 邮箱)
登录 QQ 邮箱 → 设置 → 账户。
找到「POP3/IMAP/SMTP/Exchange/CardDAV/CalDAV 服务」,开启 SMTP 服务。
按提示发送短信后生成一个授权码——它不是 QQ 登录密码。
打开 Web GUI「设置 → 邮件通知」,填写:
字段 值 SMTP 服务器 smtp.qq.comSMTP 端口 465使用 SSL/TLS 开 发件邮箱 你的QQ号@qq.com邮箱授权码 第 3 步生成的授权码 发件人地址 你的QQ号@qq.com或DSH 通知 <你的QQ号@qq.com>收件人 接收通知的邮箱(可多个) 点击 「发送测试邮件」,收到邮件即配置成功。
使用 587 端口 + STARTTLS 时:SMTP 端口填
587,关闭「使用 SSL/TLS」。 其他邮箱服务商(Gmail、Outlook、163 等)只需替换 SMTP 服务器、端口与凭据。
💬 对话完成通知
配置好 SMTP 后,在任意对话的输入框左侧会看到「邮件通知」开关:
- 开启后仅对当前会话生效;
- 该会话每完成一轮(
turn/end)都会发送一封完成邮件; - 关闭开关后不再发送;
- 开关状态持久化在
~/.dsh/email-notify/notify-sessions.json,Host 重启后仍然保留。
对话完成邮件默认标题为
[DSH 对话完成] {{sessionName}},默认正文为DSH 会话「{{sessionName}}」已于 {{time}} 完成一轮对话。,并把{{sessionId}}作为「会话属性」写入正文;标题与正文都可以在设置中的「对话通知主题模板 / 对话通知正文模板」里修改。
⏳ 审批邮件提醒
在「设置 → 邮件通知」中开启 「审批邮件提醒」(默认关闭)后,DSH 等待用户审批时会发送一封提醒邮件,内容包含审批提示、工具名、调用 ID、会话名称、会话 ID 与时间。
可分别选择两种模式:
- 工作区审批提醒:沙箱/工作区权限升级等需要用户审批的场景。
- Auto review 转手动审批提醒:官方
dsh-experimental-auto-review插件判定拒绝并把调用转交用户手动审批的场景。
Auto review 转手动审批提醒选项只有在官方 auto review 插件已安装并启用时才显示/可选;未安装或未启用时插件不会提供该选项,只保留工作区审批提醒。
审批邮件默认标题为 [DSH 审批提醒] {{sessionName}} 的 {{toolName}} 等待审批,正文优先使用界面上的本地化审批提示(displayReason),并附带原始审批原因与会话 ID;标题与正文都可以在设置中的「审批通知主题模板 / 审批通知正文模板」里修改。
❓ 提问邮件提醒
在「设置 → 邮件通知」中开启 「提问邮件提醒」(默认关闭)后,Agent 使用 ask_user_question 等待用户回答时会发送一封提醒邮件。正文包含:
- 会话名称与会话 ID;
- 问题数量;
- 每个问题的标题、问题正文、可选项与说明;
- 是否可多选。
默认标题为 [DSH 提问] {{sessionName}} 需要你的回答,正文与标题都可以在「提问通知主题模板 / 提问通知正文模板」中修改;提问提醒只观察、不回答,不会影响 Agent 等待用户的流程。
⚙️ 设置项
| 设置 | 默认值 | 说明 |
|---|---|---|
| 启用插件 | true |
关闭后不发信 |
| 向 Agent 公告本插件 | true |
在系统提示中注入插件能力说明 |
| 自动化任务通知 | true |
官方定时/自动化任务结束后发信;该轮抑制会话完成邮件 |
| 审批邮件提醒 | false |
等待用户审批时发送提醒;默认关闭 |
| 工作区审批提醒 | true |
审批提醒开启后,工作区/沙箱审批是否发信 |
| Auto review 转手动审批提醒 | true |
审批提醒开启后,官方 auto review 转手动审批是否发信;插件不可用时该项不可选 |
| 提问邮件提醒 | false |
Agent 使用 ask_user_question 等待回答时发送提醒;默认关闭 |
| SMTP 服务器 | smtp.qq.com |
任意 SMTP 服务 |
| SMTP 端口 | 465 |
QQ 邮箱 SSL;STARTTLS 常用 587 |
| 使用 SSL/TLS | true |
465 开;587 + STARTTLS 关 |
| 发件邮箱 | 空 | SMTP 登录账号 |
| 邮箱授权码 | 空 | 不是登录密码;留空时不发送任何邮件 |
| 发件人地址 | 空 | 可写作 名称 <邮箱> |
| 收件人 | 空 | 逗号/分号/换行分隔 |
| 任务通知主题模板 | [DSH 任务完成] {{taskTitle}} - {{resultText}} |
自动化任务通知主题 |
| 任务通知正文模板 | 见默认值 | 自动化任务通知正文 |
| 对话通知主题模板 | [DSH 对话完成] {{sessionName}} |
对话完成通知主题 |
| 对话通知正文模板 | 见默认值 | 对话完成通知正文,包含会话 ID 属性 |
| 审批通知主题模板 | [DSH 审批提醒] {{sessionName}} 的 {{toolName}} 等待审批 |
审批提醒主题 |
| 审批通知正文模板 | 见默认值 | 审批提醒正文,包含会话 ID 属性 |
| 提问通知主题模板 | [DSH 提问] {{sessionName}} 需要你的回答 |
提问提醒主题 |
| 提问通知正文模板 | 见默认值 | 提问提醒正文,包含问题与选项 |
🧩 模板变量
任务、对话、审批、提问四类通知都各自支持主题与正文模板;不存在的变量会被替换为空字符串。
任务通知变量(自动化任务)
| 变量 | 说明 | 示例 |
|---|---|---|
{{taskTitle}} |
任务标题(提醒 prompt 第一行) | 每周巡检 |
{{result}} |
turn 结束原因 | completed / error / aborted |
{{resultText}} |
结果中文文案 | 成功 / 失败 / 已取消 |
{{taskId}} |
schedule ID | schedule-... |
{{executionId}} |
触发消息 ID | 1f31... |
{{startedAt}} |
turn 开始时间 | 2026/10/18 09:00:00 |
{{endedAt}} |
turn 结束时间 | 2026/10/18 09:05:12 |
{{durationText}} |
耗时 | 5 分钟 12 秒 |
{{error}} |
失败详情 | timeout |
{{sessionName}} |
会话名称 | 发送邮箱通知dsh插件 |
{{sessionId}} / {{session}} |
会话 ID | session-... |
{{scheduleId}} |
首个 schedule ID | schedule-... |
{{occurrenceAt}} |
计划触发时间 | 2026-10-18T01:00:00.000Z |
{{prompt}} |
首个提醒 prompt | 每周巡检... |
{{taskCount}} |
本批任务数 | 1 |
对话通知变量
| 变量 | 说明 |
|---|---|
{{sessionName}} |
会话名称(优先展示) |
{{sessionId}} / {{session}} |
会话 ID(会话属性) |
{{time}} |
完成时间 |
审批通知变量
| 变量 | 说明 |
|---|---|
{{sessionName}} |
会话名称(优先展示) |
{{sessionId}} / {{session}} |
会话 ID(会话属性) |
{{modeText}} |
模式中文名,如 工作区审批提醒 |
{{mode}} |
模式标识:workspace / auto-review |
{{toolName}} |
工具名 |
{{callId}} |
调用 ID(可能为空) |
{{time}} |
审批请求时间 |
{{prompt}} |
审批提示内容 |
{{reason}} |
原始审批原因 |
提问通知变量
| 变量 | 说明 |
|---|---|
{{sessionName}} |
会话名称(优先展示) |
{{sessionId}} / {{session}} |
会话 ID(会话属性) |
{{count}} |
问题数量 |
{{questions}} |
全部问题与选项的格式化文本 |
{{question}} |
第一个问题的题干 |
{{time}} |
提问时间 |
🔧 工作原理
- Host 监听每个会话的
session/event。 - 收到
user/message且source.kind === 'schedule'时,解析[SCHEDULE REMINDER]/[SCHEDULE REMINDER BATCH],记录该会话的待执行自动化任务。 - 下一次
turn/start将该任务绑定到当前轮次;turn/end时发送任务完成邮件,并跳过同一轮的对话完成邮件。 - 普通用户消息的
turn/end仍按会话开关状态发送对话完成邮件;任务结束后的后续对话不受影响。 - Host 监听
approval/requestwaterfall(只观察并next()放行):审批提醒开启且对应模式选中时,发送包含审批提示内容的提醒邮件。 - Host 监听
user-questions/requestwaterfall(只观察并next()放行):提问提醒开启时,发送包含问题与选项的提醒邮件。 - 所有会话相关通知优先解析
ctx.sessionTitle里的会话名称;会话 ID 作为会话属性写入正文。 - Web 侧一级设置页通过插件自带的 loopback 设置桥读写配置,并调用「测试邮件」接口;输入框开关通过
conversation-notify/describe/conversation-notify/set接口读写;审批模式可用性通过approval/availability接口读取;诊断信息通过approval/status读取。
自动化任务 user/message → 标记任务轮次 → turn/end → 任务完成邮件
用户普通 turn/end → 检查 notify-sessions.json → 会话完成邮件
🔒 安全说明
- 插件所有 HTTP API(测试邮件、设置读写)仅接受 loopback 请求,并校验 Host 头与同源 Origin,不信任
X-Forwarded-For。 - SMTP 授权码以
role('secret')声明:浏览器读取配置时脱敏(显示为空),真实授权码不会回传前端。 - 已通知执行 ID 与收件人等状态保存在用户主目录私有路径,不写入仓库。
- 如发现安全问题,请参考 SECURITY.md,不要在公开 Issue 中粘贴真实授权码。
🗂️ 项目结构
dsh-email-notify/
├── src/
│ ├── index.ts # 插件入口:配置、系统提示、路由注册
│ ├── notifier.ts # 自动化任务轮次、模板渲染、发信
│ ├── mailer.ts # nodemailer 封装、收件人解析、配置校验
│ ├── routes.ts # 测试邮件 / 设置桥接 HTTP API
│ ├── loopback.ts # loopback 请求校验
│ └── client/ # Web GUI 设置页 + 对话开关(React)
│ ├── index.ts # 注册 settings.section 与 conversation.input.left
│ ├── EmailNotifySettingsCard.tsx
│ ├── ConversationNotifyCheckbox.tsx
│ ├── locales.ts # 中英文案
│ └── settings-scope.ts # 设置桥接客户端
├── lib/ # 构建产物(git 忽略,pnpm build 生成)
├── cordis.patch.yml # DSH bundle patch
├── build.mjs # esbuild 构建脚本
└── package.json
🛠️ 开发
pnpm install # 安装依赖(prepare 钩子自动构建)
pnpm typecheck # TypeScript 类型检查
pnpm build # 构建 lib/index.js 与 lib/client.js
pnpm check # typecheck + build
提交 PR 前请保证 pnpm check 通过;CI 会在 GitHub Actions 上自动执行相同的检查。
更多约定见 CONTRIBUTING.md,变更历史见 CHANGELOG.md。
❓ 常见问题
测试邮件发送失败?
- 确认使用的是邮箱授权码而不是登录密码。
- 465 端口请开启「使用 SSL/TLS」;587 端口请关闭并确认服务商支持 STARTTLS。
- 确认「发件人地址」非空,格式可为
[email protected]或名称 <[email protected]>。 - 检查网络/防火墙是否能访问 SMTP 服务器(QQ 邮箱一般无需代理)。
自动化任务完成了但没收到邮件?
- 确认「自动化任务通知」已开启。
- 自动化任务必须由官方 schedule 注入;普通定时提醒也会走同一路径。
- 查看 Host 日志中是否有
[dsh-email-notify] automation completion send failed。 - 诊断接口:
http://127.0.0.1:<port>/api/dsh-email-notify/approval/status。
开启了「邮件通知」但对话完成后没收到邮件?
- 确认 SMTP 配置完整,且「发送测试邮件」可以成功收到。
- 开关状态是按会话记录的:换一个对话需要重新开启。
- 查看 Host 日志中是否有
[dsh-email-notify] conversation completion send failed或send failed。
审批邮件提醒没有收到?
- 确认「审批邮件提醒」已开启(默认关闭),且对应的「工作区审批提醒」/「Auto review 转手动审批提醒」模式已开启。
- 「Auto review 转手动审批提醒」只有在官方 auto review 插件已安装并启用时才可选。
- 当前审批请求必须处于等待用户审批状态;审批提醒不会改变审批结果。
- 查看 Host 日志中是否有
[dsh-email-notify] approval notify failed。
提问邮件提醒没有收到?
- 确认「提问邮件提醒」已开启(默认关闭)。
- 只有 Agent 通过
ask_user_question向你提问时才会触发;普通对话不会触发。 - 提问提醒只观察、不回答,不会改变 Agent 的等待流程。
- 查看 Host 日志中是否有
[dsh-email-notify] ask notify failed;也可以打开http://127.0.0.1:<port>/api/dsh-email-notify/approval/status查看askObserved/askSent/lastAsk。 - 若要清空所有会话的开关状态,删除
~/.dsh/email-notify/notify-sessions.json后重启 Host。