← 返回列表
未验证
为智能体接入 Gmail 收发、搜索与联系人管理
尚未跑自动兼容性验证,可查看页面内的依赖与入口分析。 · 最近上游提交 2026/8/25 · 已提供中文文档
dsh-gmail:DeepSeek Harness 的 Gmail 插件套件——通过 Gmail 和 People API(OAuth2)提供 61 个面向模型的工具 + 2 个轮询触发器
综合分
28.5
GitHub 分
28.5
用户评分
—
★ Stars
1
周下载量
—
安装插件(需先安装 dsh CLI 引擎:npm install -g @deepseek-ai/dsh)
dsh plugin --profile web add sakthiveltofficial/dsh-gmail-plugins该插件未发布到 npm,走 GitHub 源安装(pnpm 若拦截 prepare 脚本,按其提示在 pnpm-workspace.yaml 的 allowBuilds 中放行后重跑)
数据截至 2026/9/16(元数据每日更新 · 实装验证按队列轮转,单条结论的验证时间见上方)
依赖的 DSH / Cordis 模块
@deepseek-ai/cordis@deepseek-ai/schemastery@deepseek-ai/dsh-tools@deepseek-ai/dsh-credentials用户评分
还没有人投票,来当第一个
订阅周报,不错过优质插件更新
每周一封 · 高评分插件 + 新用户活动
README
dsh-gmail · DeepSeek Harness 的 Gmail 插件
DSH-GMAIL — DeepSeek Harness 的 Gmail 能力
License: MIT
一个完整、可用于生产环境的 DeepSeek Harness (DSH) Gmail 插件。它通过官方 Gmail 和 People REST API 为智能体提供类型化、策略感知的 Gmail 访问能力——63 个面向模型的工具(发送、搜索、草稿、标签、过滤器、会话、设置、联系人)以及 2 个轮询触发器——并具备自动 OAuth2 令牌管理。
官方生态关键词: 这是一个 dsh-plugin——请为本仓库添加 dsh-plugin GitHub 主题标签。
🤖 供 LLM 阅读的摘要
- 是什么: 一个单一的 Cordis 插件,通过 63 个 gmail_ 工具 + 2 个轮询触发器扩展 DSH 智能体。
- 安装: dsh plugin --profile web add github:sakthiveltofficial/dsh-gmail-plugins,然后在你的 profile patch(或智能体预设)中添加一行——参见安装。
- 工具: gmail_send_email、gmail_fetch_emails、gmail_fetch_message_by_message_id、gmail_fetch_message_by_thread_id、gmail_list_threads、gmail_reply_to_thread、gmail_create_email_draft、gmail_send_draft、gmail_forward_message、标签/过滤器/回收站/设置/联系人工具——完整列表见工具表。
- 认证: OAuth2(gmail.modify、gmail.settings.basic、gmail.compose、gmail.send、contacts.readonly 作用域)。凭据从不存储在配置中——通过 ctx.credentials 在每次操作时解析环境变量引用。gmail_authorize 运行交互式 Google 登录,并自动捕获并存储刷新令牌;只需设置 GMAIL_CLIENT_ID / GMAIL_CLIENT_SECRET。
- 触发器: gmail/message-received(新邮件)和 gmail/message-sent(已发送邮件)——基于轮询,首次激活时进行种子初始化,因此邮箱不会被重放。
- 运行时要求: DeepSeek Harness、Node.js ≥ 20(全局 fetch),以及一个启用了 Gmail(和 People)API 的 Google Cloud OAuth 客户端。
- 安全性: 永久删除(gmail_delete_message、gmail_batch_delete_messages、gmail_delete_thread、gmail_delete_label)有明确标注,并需要用户明确确认;智能体被提示优先使用回收站而非永久删除,除非用户要求不可逆的移除。
- 许可证: MIT。
✨ 功能
- 读取与搜索——使用 Gmail 查询语法获取邮件,按 ID 获取邮件或完整会话,列出会话,列出/获取草稿,下载附件,获取个人资料/历史记录。
- 撰写与发送——发送邮件(附件可来自本地路径、URL 或内联 base64),创建/更新/发送草稿,转发邮件,在会话内回复(正确的 In-Reply-To/References 会话关联)。
- 组织 — 添加/移除标签(单条消息、1,000 条批量或整个会话串),创建/修补/更新/删除标签,创建/列出/获取/删除过滤器。
- 管理 — IMAP/POP 设置、自动转发、假期自动回复、显示语言、代发别名、S/MIME 配置、CSE 身份/密钥对、停止监视通知。
- 联系人 — 获取联系人(连接)、获取某个人或“其他联系人”、通过 People API 搜索人员。
- 一键授权 — gmail_authorize 会在浏览器中打开 Google 同意页面,并自动捕获 + 存储刷新令牌;无需手动生成令牌。
- 触发器 — 轮询新收到/已发送的邮件,并为下游监听器发出带类型的 Cordis 事件。
- 弹性 — 自动刷新访问令牌并带内存缓存、401 失效并重试、对 429/5xx 进行有界指数退避、保留 HTTP 状态的结构化 GmailError。
🚀 安装
前置条件
DeepSeek Harness 正在运行(某个 profile,例如默认的 web profile)
Node.js >= 20(宿主机的 Node —— 插件在进程内运行)
一个 Google Cloud OAuth 客户端(见下文“配置凭据”)
1. 从此 GitHub 仓库安装该包
dsh plugin --profile web add github:sakthiveltofficial/dsh-gmail-plugins
这会将 @google-workspace/dsh-gmail 插件包安装到该 profile 中(仓库根目录即为包 —— 无需构建步骤)。
2. 在组合中挂载插件
该插件不发布任何服务 —— 它只向宿主的 tools 注册表注册工具(外加用于触发器的可选 timer 服务)—— 因此它作为普通的松散行挂载,无需 isolate 领域。
选项 A —— profile 补丁(宿主平面,工具对所有 agent 可见)。 追加到你的 profile 的 cordis.patch.yml:
- insert:
- id: gmail
name: '@google-workspace/dsh-gmail'
config:
clientIdRef: GMAIL_CLIENT_ID
clientSecretRef: GMAIL_CLIENT_SECRET
refreshTokenRef: GMAIL_REFRESH_TOKEN
defaultUserId: me
timeoutMs: 30000
enableReceivedTrigger: false
enableSentTrigger: false
选项 B —— agent 预设(工具仅对该预设上的 agent 可见)。 将该行添加到预设的 agent.cordis.yml:
- id: gmail
name: '@google-workspace/dsh-gmail'
config:
clientIdRef: GMAIL_CLIENT_ID
clientSecretRef: GMAIL_CLIENT_SECRET
refreshTokenRef: GMAIL_REFRESH_TOKEN
重启该 profile(或 DSH 进程)。
验证
dsh --profile web --dump-config | grep -i gmail
然后询问 agent:“你有哪些 gmail 工具?”* —— 它应当列出 gmail_ 工具(共 63 个)。
🔑 配置凭据(OAuth2)
Gmail 需要 OAuth2 —— 没有 API 密钥途径。配置中只携带环境变量引用,绝不包含字面令牌;值在每次操作时通过 DSH 的凭据服务解析(进程环境变量 → 提供程序存储 → .env)。
| 环境变量 | 用途 |
| --- | --- |
| GMAIL_CLIENT_ID | OAuth 客户端 ID(例如 ....apps.googleusercontent.com)—— 必填 |
| GMAIL_CLIENT_SECRET | OAuth 客户端密钥(例如 GOCSPX-...)—— 必填 |
| GMAIL_REFRESH_TOKEN | 长期有效的刷新令牌 —— 可选;未设置时,运行 gmail_authorize,它会自动被捕获并存储 |
Google Cloud 设置(5 个步骤,约 5 分钟)
复制粘贴此重定向 URL —— 插件的 OAuth 回调监听它:
http://127.0.0.1:8765/oauth2callback
(可通过插件的 redirectPort 设置进行配置;保持两者同步)
1. 创建项目,访问 (或选择一个现有项目)。
2. 启用 API: APIs & Services → Library* → 启用 Gmail API 和 People API(People 仅用于联系人工具)。
3. 配置 OAuth 同意屏幕: APIs & Services → OAuth consent screen → 用户类型选择 External(对于 Workspace 则选择 Internal)→ 应用名称(例如 dsh-gmail)+ 你的支持邮箱 → 保存。将其保持在 Testing 状态(将你的 Google 账户添加为测试用户)或 发布 它;两者对你自己的账户都有效。
4. 创建 OAuth 客户端: APIs & Services → Credentials → Create Credentials → OAuth client ID → Web application → 在 Authorized redirect URIs 下准确添加:
http://127.0.0.1:8765/oauth2callback
→ 创建 → 复制 Client ID 和 Client secret。
5. 导出它们(或为相同名称配置 ctx.credentials 来源):
export GMAIL_CLIENT_ID='....apps.googleusercontent.com'
export GMAIL_CLIENT_SECRET='GOCSPX-...'
刷新令牌无需导出 —— 请参阅下面的两个选项。
选项 A(推荐)—— 从 harness 进行交互式登录
设置好 GMAIL_CLIENT_ID 和 GMAIL_CLIENT_SECRET 后,让 agent 运行 gmail_authorize(或自己运行):插件会在你的默认浏览器中打开 Google 同意页面,你登录后,刷新令牌会通过 harness 凭证服务自动捕获并存储 —— 无需手动生成令牌。每个账户只需执行一次。gmail_auth_status 会报告是否已存储凭证以及任何进行中的登录状态。
插件在同意时会请求以下作用域:
| 作用域 | 所需工具 |
| --- | --- |
| https://www.googleapis.com/auth/gmail.modify | 读取/写入邮件、标签、垃圾箱(大多数工具) |
| https://www.googleapis.com/auth/gmail.settings.basic | 设置工具(IMAP/POP/转发/休假/语言/代发) |
| https://www.googleapis.com/auth/gmail.compose | 草稿 |
| https://www.googleapis.com/auth/gmail.send | 发送/回复/转发 |
| https://www.googleapis.com/auth/contacts.readonly | 联系人工具 |
选项 B —— 手动刷新令牌
使用你的客户端 ID/密钥访问 Google OAuth Playground:选择上述作用域,授权,然后复制刷新令牌,再导出它:
export GMAIL_REFRESH_TOKEN='1//0...'
访问令牌按需从刷新令牌铸造,并在其有效期内缓存;401 会使缓存失效,并用一次新的交换重试一次。不要在同一同意请求中,将 gmail.metadata 与内容作用域(gmail.readonly/gmail.modify/mail.google.com)一起添加——Google 会将其视为受限作用域,并拒绝这种组合。
🧰 工具
所有工具名称均为 snake_case 的 gmail_(例如 gmail_send_email、gmail_fetch_emails),并保留了完整的参数范围以及重要警告:十六进制消息 ID、标签 ID 与显示名称、不可逆删除。
| 领域 | 工具 |
| --- | --- |
| 认证 | gmail_authorize(交互式 Google 登录——捕获并存储刷新令牌)、gmail_auth_status |
| 读取 | gmail_fetch_emails、gmail_fetch_message_by_message_id、gmail_fetch_message_by_thread_id、gmail_list_threads、gmail_list_messages(已弃用)、gmail_get_draft、gmail_list_drafts、gmail_get_attachment |
| 撰写 | gmail_send_email、gmail_create_email_draft、gmail_update_draft、gmail_send_draft、gmail_forward_message、gmail_reply_to_thread |
| 整理 | gmail_add_label_to_email、gmail_batch_modify_messages、gmail_modify_thread_labels、gmail_list_labels、gmail_get_label、gmail_create_label、gmail_patch_label、gmail_update_label、gmail_delete_label、gmail_remove_label(已弃用)、gmail_create_filter、gmail_list_filters、gmail_get_filter、gmail_delete_filter |
| 删除/移入回收站 | gmail_move_to_trash、gmail_untrash_message、gmail_delete_message、gmail_batch_delete_messages、gmail_move_thread_to_trash、gmail_untrash_thread、gmail_delete_thread、gmail_delete_draft |
| 导入 | gmail_import_message、gmail_insert_message |
| 管理 | gmail_get_profile、gmail_list_history、gmail_get_imap_settings、gmail_update_imap_settings、gmail_get_pop_settings、gmail_update_pop_settings、gmail_get_auto_forwarding、gmail_list_forwarding_addresses、gmail_get_vacation_settings、gmail_update_vacation_settings、gmail_get_language_settings、gmail_update_language_settings、gmail_list_send_as、gmail_get_send_as、gmail_patch_send_as、gmail_update_send_as、gmail_list_smime_info、gmail_list_cse_identities、gmail_list_cse_keypairs、gmail_stop_watch |
| 联系人 | gmail_get_contacts、gmail_get_people、gmail_search_people |
有意省略了两个工具:GMAIL_CREATE_PROMPT_POST 和 GMAIL_UPDATE_USER_ATTRIBUTES_VALUES,它们面向的是 Sanity Content Agent,而不是 Gmail。
关键约定(智能体在其提示词部分中会被告知这些内容)
- 消息 ID 是十六进制的 Gmail API ID(例如 19b11732c1b578fd)——绝不是 UUID、线程 ID、主题或日期。请从 gmail_fetch_emails / gmail_list_threads 获取它们。
- 标签参数使用标签 ID,绝不使用显示名称:系统标签使用其大写名称(INBOX、UNREAD、STARRED、SPAM、TRASH、CATEGORY_UPDATES……);自定义标签使用其内部 ID(Label_123,来自 gmail_list_labels)。
- 草稿 ID(r99885592323229922)与邮件 ID 不同;gmail_send_draft 会按原样发送草稿,无法添加收件人。
- 附件接受本地文件路径、公开 URL 或 { name, mimetype, base64 };经过 base64 编码后,邮件总大小必须保持在约 25 MB 以下。
- 不可逆操作(gmail_delete_message、gmail_batch_delete_messages、gmail_delete_thread、gmail_delete_label、gmail_delete_draft)会绕过回收站——除非用户明确要求永久删除,否则优先使用回收站相关工具。
🔔 触发器
在配置中启用:
config:
enableReceivedTrigger: true # poll in:inbox → emit gmail/message-received
enableSentTrigger: true # poll in:sent → emit gmail/message-sent
triggerIntervalMinutes: 5
当插件挂载后,每次轮询都会在插件作用域内发出一个 Cordis 事件,并带有触发载荷结构(sender、subject、message_id、thread_id、message_text、message_timestamp、attachment_list……)。首次轮询仅用于初始化已见集合,因此激活时绝不会重放邮箱。触发器仅在会话存活期间运行(agent-plane 轮询),与 harness schedule 服务类似。
ctx.on('gmail/message-received', (payload) => { / ... / })
ctx.on('gmail/message-sent', (payload) => { / ... / })
🧯 故障排除
| 症状 | 原因 / 修复方法 |
| --- | --- |
| 工具调用时出现 GMAIL_AUTH_FAILED(401) | 访问令牌/刷新令牌无效:用户撤销了访问权限、更改了密码/2FA、Workspace 管理员策略发生变更,或达到了 Google 每账户约 50 个刷新令牌的上限。使用 gmail_authorize 重新认证(或手动刷新 GMAIL_REFRESH_TOKEN)。 |
| 同意屏幕上显示“应用已被阻止”/未验证应用 | OAuth 客户端正在请求 Google 尚未验证的作用域。移除多余的作用域,或创建你自己的 OAuth 应用并提交作用域以供验证。 |
| “Gmail API has not been used in project” | 拥有凭据的 Cloud 项目未启用 Gmail API。在 APIs & Services* 下启用它,等待几分钟后重试。 |
| Error 400: invalid_scope | 授权 URL 中的作用域值不正确/格式错误。对照 Google OAuth 作用域文档 进行验证。 |
| 同意屏幕显示的应用名称错误 | 默认同意流程使用共享应用。创建你自己的 OAuth 应用并设置自定义重定向 URL(白标)。 |
| GMAIL_RATE_LIMITED(429/403) | Google 会强制执行每分钟/每日配额;共享 OAuth 应用会共享其配额。使用你自己的客户端以获得专用配额,并应用指数退避(客户端已对 429/5xx 重试最多 4 次)。 |
| GMAIL_API_ERROR (400) "Invalid id value" | 将非十六进制的 ID(UUID、线程 ID、主题、伪造值)作为 message_id 传入。请使用来自 gmail_fetch_emails/gmail_list_threads 的 ID。 |
| 标签静默未应用 | 传入的是显示名称而非标签 ID。运行 gmail_list_labels 并使用返回的 Label_N ID。 |
| 触发器感觉缓慢 | 触发器按 triggerIntervalMinutes(默认 5)轮询;请缩短该间隔,或使用 Google Pub/Sub webhook 以实现亚分钟级延迟。 |
🔒 安全
- 密钥绝不存储在配置中 —— 仅存储环境变量引用(GMAIL_CLIENT_ID / GMAIL_CLIENT_SECRET / GMAIL_REFRESH_TOKEN),在每次操作时通过 ctx.credentials 解析(进程环境变量 → 提供方存储 → .env)。为快速搭建支持字面量配置值,但不建议用于生产环境。
- 访问令牌仅缓存在内存中,绝不持久化,并会按需使用刷新令牌进行刷新。
- 破坏性工具在其描述中有明确标注(permanent、no recovery possible),并指示智能体在永久删除前与用户确认,对于可逆工作流优先使用回收站。
- 转发/回复收件人是明确的 —— 转发会保留内容,因此指示智能体在转发前核实收件人,以避免意外泄露。
- 最小权限:仅授予工作流所需的权限范围(若未使用,请移除 gmail.settings.basic 或 contacts.readonly —— 权限范围过大的客户端可能触发“应用已被阻止”的验证要求)。
📦 包结构
lib/
├── index.js # 插件入口:name / inject / Config / apply
├── auth.js # OAuth2 凭据解析 + 令牌刷新
├── authorize.js # 交互式 Google 登录(回环 OAuth 流程)
├── client.js # Gmail + People REST 客户端(401 刷新、退避)
├── mime.js # RFC 2822 MIME 构建器 + 载荷解析器
├── tools.js # 基于 @deepseek-ai/dsh-tools 的工具工厂
├── tools/ # 9 个模块中的 63 个工具定义
│ ├── messages.js # 14 个工具
│ ├── drafts.js # 6 个工具
│ ├── threads.js # 6 个工具
│ ├── labels.js # 7 个工具
│ ├── filters.js # 4 个工具
│ ├── settings.js # 20 个工具
│ ├── people.js # 3 个工具
│ ├── attachments.js # 1 个工具
│ └── authorize.js # 2 个工具(gmail_authorize、gmail_auth_status)
├── triggers.js # 轮询触发器
├── cordis.yml # 配置文件补丁行(宿主平面)
├── examples/ # agent.cordis.yml 预设行
└── docs/assets/ # 横幅图片
该插件仅使用 Node 内置模块以及四个可选的 @deepseek-ai/ 对等依赖;无需构建步骤。运行时要求:Node.js ≥ 20(全局 fetch)、DeepSeek Harness。
🧪 开发与验证
node --check lib/index.js && for f in lib/.js lib/tools/*.js; do node --check "$f"; done
每次发布前都会运行一次注册冒烟测试(导入 → Config({}) → 在桩 ctx.tools 上应用 → 断言全部 63 个工具、无重复、与预期工具集无重叠)。
📄 许可证
MIT扫码进群