gog 的 Gmail 技能手册:用 gogcli 在终端安全地操作 Gmail
2026/9/16 13:22:52 网站建设 项目流程

gog 的 Gmail 技能手册:用 gogcli 在终端安全地操作 Gmail

【免费下载链接】gogcliGoogle Workspace in your terminal.项目地址: https://gitcode.com/GitHub_Trending/gogcl/gogcli

导读

gog(gogcli)是一个把 Google Workspace 装进终端命令行的工具,而.agents/skills/gog-gmail/SKILL.md正是为 AI Agent 与开发者准备的Gmail 操作技能卡片:它规定了「在动手前先验证环境、默认只读、写操作必须先声明」的安全工作流,并给出了 Gmail 全部 22 个一级子命令的用途索引。读完本文,你将掌握用gog搜索、读取、收发与归档 Gmail 的标准姿势,理解--readonly--gmail-no-send--wrap-untrusted等安全护栏在源码层的落地方式,以及如何借助schema机器可读契约在脚本或 Agent 中不猜命令语法。

技能定位:这份 SKILL.md 是给谁用的

gog-gmail/SKILL.md由 scripts/gen-agent-skills.mjs 自动生成(文件头注释明确写了do not edit),它与.agents/skills/目录下 gog-admin、gog-calendar、gog-drive 等二十多个技能卡片组成一套Agent 能力清单。每个技能卡的配套.agents/skills/gog-gmail/agents/openai.yaml会把它暴露给 Agent:

interface: display_name: "gog Gmail" short_description: "Operate Gmail safely with gog" default_prompt: "Use $gog-gmail to perform this Gmail task safely."

这份文档面向的读者有两类:

  • AI Agent / LLM 调用者:需要稳定的 JSON 输出、确定的退出码、非交互模式,以及防止误写误删的命令护栏;
  • 终端自动化脚本作者:需要把「检查认证 → 只读搜索 → 条件性写入」固化为可重复的 shell 流程。

在深入 Gmail 命令之前,SKILL 要求先阅读共享规则文档 .agents/skills/gog/SKILL.md,其中规定了所有服务共用的 auth、输出、安全与 live-write 规则——本文后续的护栏讲解同样适用于该文档。

Safe start:动手前必须完成的四步校验

SKILL 文档给出的安全起点是一个三段式 bash 片段,对应三个截然不同的目的:

gog auth list --check --json --no-input gog schema gmail --json gog --readonly --account user@example.com gmail search 'newer_than:7d' --max 10 --json --wrap-untrusted
  1. gog auth list --check --json --no-input:验证认证状态。--check会实际检查令牌有效性,--json让输出可被脚本解析,--no-input保证在自动化环境中不出现交互式提示——认证失败就直接报错退出,而不是挂起等待输入。
  2. gog schema gmail --json:拉取 Gmail 服务的机器可读契约(命令语法、稳定退出码、有效安全状态)。SKILL 明确警告「不要猜命令语法」(Do not guess command syntax),一切以gog gmail <command> --helpgog schema gmail <command> --json为准。
  3. 只读搜索--readonly在运行时层面阻断一切变更类 API 请求;--account user@example.com显式指定账号;--json --wrap-untrusted让 Google 返回的文本内容被包进「外部不可信内容」标记,供 Agent 安全解析。

SKILL 随后给出四条操作铁律:

  • 显式选账号:始终用--account指定账号,避免隐式默认账号带来的错误操作风险;
  • Agent 解析 Google 内容:一律使用--json --wrap-untrusted
  • 不得变更数据:任务不涉及写操作时必须带--readonly
  • 自动化环境:使用--no-input;对支持的写操作先用--dry-run预览;
  • 任何写/删操作前:确认确切的账号、对象与变更内容。

命令总览:Gmail 的 22 个一级子命令

SKILL 文档用一张表列出了gog gmail的全部一级子命令。对照源码 internal/cmd/gmail.go 中的GmailCmd结构体,这张表与代码里的cmd:标签一一对应,并且按group分成了读(Read)、组织(Organize)、写(Write)、管理(Admin)四类:

命令用途代码分组
archive归档消息或显式线程(从收件箱移除)Organize
attachment下载单个附件Read
autoreply对匹配消息只回复一次Write
batch批量操作(永久删除需要更宽的 Gmail scope;普通删除请用 trash)Organize
drafts草稿操作Write
forward转发消息给新收件人(别名fwdWrite
get获取单条消息(full\|metadata\|rawRead
historyGmail 历史记录Read
import将 RFC822/EML 消息导入 GmailWrite
labels标签操作Organize
mark-read标记消息已读(别名read-messagesOrganize
messages消息操作Read
raw输出原始 Gmail API 响应 JSON(Users.Messages.Get,无损,供脚本与 LLM 使用)Read
reply回复消息Write
reply-all回复所有参与者(别名replyallWrite
search用 Gmail 查询语法搜索线程(别名find,query,ls,listRead
send发送邮件Write
settings设置与管理(含 filters/delegates/forwarding/autoforward/sendas/vacation/watch 子组)Admin
thread线程操作(get、modify)Read
track邮件打开追踪Write
trash移入回收站Organize
unread标记消息未读(别名mark-unreadOrganize
url打印线程的 Gmail 网页 URLRead

源码提示:GmailCmd中还声明了watchautoforwarddelegatesfiltersforwardingsendasvacationhidden:""字段,它们作为独立隐藏命令存在,同时在GmailSettingsCmd中被正式暴露为settings的子命令(见 internal/cmd/gmail.go)。

SKILL 特别强调两点使用纪律:

  • 拿不准命令语法时,先gog gmail <command> --help看旗标、gog schema gmail <command> --json看机器可读契约;
  • batch的永久删除语义:永久删除需要更宽的 Gmail scope(https://mail.google.com/,日常「删除」应该走gmail trash,这与共享规则文档 .agents/skills/gog/SKILL.md 中「gmail batch delete 永久删除消息、需要更宽 OAuth scope,优先用 gmail trash」的说明完全一致。

核心场景一:只读搜索(Read)

gmail search是 Agent 与脚本使用频率最高的入口。命令定义在 internal/cmd/gmail_search.go 的GmailSearchCmd中,关键参数如下:

参数类型/默认说明
query位置参数(可多段,自动拼接)Gmail 查询语法,如'newer_than:7d''from:example@example.com'
--from-contactstring解析一个 Google 联系人,自动扩展出from:(email OR email)追加到查询
--max/--limitint64,默认 10最大结果数(源码中validateGmailMaxResults会做上限校验)
--page/--cursorstring分页游标
--all/--all-pages/--allpagesbool拉取全部分页
--countbool输出全量匹配数(totalMatches精确值或totalMatchesAtLeast下界)
--oldestbool显示首封消息日期而非最后一封
--fail-empty/--non-empty/--require-resultsbool无结果时以退出码 3 退出,便于管道判断
--timezone/-z--localstring输出时区(IANA 名称,默认取GOG_TIMEZONE→ 配置 → 本地)

从源码调用链可以看到它的完整流程(internal/cmd/gmail_search.go):

  1. 校验--max上限 →requireAccount解析账号;
  2. 拼接 query;若给了--from-contact,调用gmailFromContactQuery解析联系人并展开from:子句;
  3. 通过gmailService拿到 Gmail API client,调用svc.Users.Threads.List("me")(即搜索的是线程 Thread而非单条消息);
  4. loadPagedItems处理分页(--page游标 /--all全量);
  5. 若指定--count,调用countGmailThreadMatches统计全量匹配数并写入 payload;
  6. 解析标签 ID → 名称映射,按--oldest/时区渲染线程详情;
  7. JSON 模式下输出{"threads": [...], "nextPageToken": ...}信封结构。

因此--results-only可以去掉信封、只留下threads数组,配合--select做字段投影(如--results-only --select id),这是脚本里「只取 ID 列表」的标准姿势。

读消息时的内容安全

SKILL 的共享规则建议正文检查优先用--sanitize-content(除非明确需要原始 payload)。该开关的实现在 internal/cmd/gmail_sanitize.go:

  • sanitizeGmailText:先做 HTML 反转义,再用正则https?://[^\s<>"']把 URL 替换为[url removed]`——这是对邮件正文中不可信链接的主动降险;
  • sanitizeGmailBody:HTML 正文先经extractSanitizedHTMLText抽取纯文本,再压缩空白为单空格并TrimSpace
  • 输出结构gmailSanitizedMessageOutput只保留 ID、ThreadID、LabelIDs、Snippet、InternalDate、SizeEstimate、Headers、Body、Attachments 等字段,去掉了原始 MIME 中的可执行风险面。

配合--wrap-untrusted(JSON/raw 输出把外部拉取的文本字段包进不可信内容标记),这两层共同保证「Agent 拿到的 Gmail 内容是可以安全解析的文本,而不是可以注入指令的原始 HTML」。

核心场景二:发送、回复与转发(Write)

SKILL 对写操作给出的原则是:先确认账号、对象 ID 与确切变更,优先用支持--dry-run的命令

共享规则文档提供了回复邮件的推荐姿势——不要用gmail send手工重建回复 MIME,而是用一等公民命令:

gog --account user@example.com gmail reply <messageId> --body-file reply.txt gog --account user@example.com gmail reply-all <messageId> --body-file reply.txt \ --bcc introducer@example.com --remove former-participant@example.com

reply/reply-all会自动继承主题、默认引用原文、保留显示名与内联图片,并把--to/--cc/--bcc视为「追加式」的放置或移动;--no-quote可省略原文。其余写命令还包括forwardimport(RFC822/EML 导入)、draftsautoreply(对匹配消息只回复一次)、sendtrack(邮件打开追踪)。

--gmail-no-send的实现级护栏

「除非任务是发邮件,否则一律加--gmail-no-send」这条规则在源码里有完整的三层落地,见 internal/cmd/gmail_no_send.go:

var gmailSendCommandPaths = map[string]struct{}{ "send": {}, "gmail.send": {}, "gmail.reply": {}, "gmail.reply-all": {}, "gmail.replyall": {}, "gmail.autoreply": {}, "gmail.forward": {}, "gmail.fwd": {}, "gmail.drafts.send": {}, }

enforceGmailNoSend在命令解析层(kong.Context)拦截:

  1. 命令路径不在发送集合内 → 直接放行;
  2. 命中发送集合且给了--gmail-no-send→ 报错Gmail sending is blocked by --gmail-no-send
  3. 再检查全局配置键gmail_no_send按账号的 no-send 名单(config no-send),逐层拦截。

注释里特别说明:这一层守卫在--dry-run下同样生效(因为 dry-run 在 post-auth 检查到达之前就退出了),且按账号守卫只在存在 no-send 配置时才解析账号,避免无谓地触发 keyring 读取。这解释了为什么 SKILL 要求「对支持的写操作先--dry-run」——即使预览,发送类命令也会被完整护栏罩住。

发现机制:schema 与生成的命令文档

SKILL 反复强调「不要猜语法」,其背后的可执行机制是三层发现路径:

gog gmail --help # 服务级帮助 gog gmail <command> --help # 命令级帮助(全部旗标) gog schema gmail <command> --json # 机器可读契约

仓库同步维护了gog schema --json自动生成的命令参考文档(文件头注明Generated from gog schema --json. Do not edit this page by hand; run make docs-commands),例如:

  • docs/commands/gog-gmail.md ——gog gmail服务页,含全部子命令索引与全局旗标表(--readonly--gmail-no-send--wrap-untrusted--dry-run--enable-commands--disable-commands等);
  • docs/commands/gog-gmail-search.md ——search子命令的完整旗标表,包括--count--fail-empty--from-contact--oldest--timezone等;
  • docs/commands/README.md —— 全部命令索引。

手动编写 Agent 工具描述或 shell 封装时,直接引用这些生成文档即可获得与二进制完全同步的参数定义,不必人工维护。

组合实战:把安全搜索固化成可复用流程

综合 SKILL 与共享规则文档,一个「安全且 Agent 友好」的 Gmail 只读流程可以写成:

# 1. 先验证认证(自动化环境必须 --no-input) gog auth list --check --json --no-input || gog auth doctor --check --json --no-input # 2. 只读搜索最近 7 天邮件,JSON + 不可信内容包裹 gog --readonly --account user@example.com \ gmail search 'newer_than:7d' --max 10 --json --wrap-untrusted # 3. 取某条消息的安全化正文(优先 --sanitize-content) gog --readonly --account user@example.com \ gmail get <messageId> --sanitize-content --json --wrap-untrusted # 4. 线程级查看 gog --readonly --account user@example.com \ gmail thread get <threadId> --sanitize-content --json --wrap-untrusted

需要追加命令级运行守卫时,用共享规则中的--enable-commands/--disable-commands把 CLI 收窄到白名单:

gog --readonly --enable-commands gmail.search,gmail.get --gmail-no-send \ --account user@example.com gmail search 'from:example@example.com' --json

这条命令同时叠加了只读、命令白名单、禁发邮件三层限制,即使 Agent 的后续行为失控,也无法越出「搜索 + 读取」的范围。

写给 Agent 与自动化脚本的关键约定

最后汇总 SKILL 与配套源码对自动化场景的硬性约定:

  1. stdout 只放数据:人类可读的提示与进度走 stderr,stdout 专供--json/--plain(TSV)结构化输出;
  2. 稳定退出码--fail-empty无结果退出码为 3,配合--json可被脚本直接判断分支;
  3. 不可信内容处理:读 Google 内容一律--json --wrap-untrusted,正文检查优先--sanitize-contentraw子命令保留无损原始响应,但仅供需要完整 payload 的场景;
  4. 绝不输出敏感信息:不得打印 access token、refresh token、OAuth client secret 或 keyring 密码;服务环境下的GOG_KEYRING_BACKEND=fileGOG_KEYRING_PASSWORDHOME必须由启动gog的进程提供;
  5. 破坏性命令需--force:除非用户明确要求该确切的变更,Agent 不得自行追加--force
  6. 临时对象要清理:测试创建类命令时使用带临时前缀的命名,验证后立即删除或移入回收站。

延伸阅读

  • .agents/skills/gog/SKILL.md —— 所有服务共享的认证、输出、安全与 live-write 规则(Gmail 技能的前置文档)
  • internal/cmd/gmail.go —— Gmail 命令注册表与子命令分组
  • internal/cmd/gmail_no_send.go ——--gmail-no-send三层护栏实现
  • internal/cmd/gmail_sanitize.go ——--sanitize-content正文清洗实现
  • docs/commands/gog-gmail.md 与 docs/commands/gog-gmail-search.md —— 由schema生成的命令与旗标权威参考
  • docs/agent-skills.md 与 docs/safety-profiles.md —— Agent 技能清单与安全配置文件说明

【免费下载链接】gogcliGoogle Workspace in your terminal.项目地址: https://gitcode.com/GitHub_Trending/gogcl/gogcli

创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考

需要专业的网站建设服务?

联系我们获取免费的网站建设咨询和方案报价,让我们帮助您实现业务目标

立即咨询