资讯详情

资讯详情

gogcli 实战:用 `gog gmail archive` 在终端批量归档 Gmail 邮件与线程

gogcli 实战用gog gmail archive在终端批量归档 Gmail 邮件与线程【免费下载链接】gogcliGoogle Workspace in your terminal.项目地址: https://gitcode.com/GitHub_Trending/gogcl/gogcli本文聚焦 Google Workspace 终端工具 gogcli 的gog gmail archive命令系统讲解归档在 Gmail API 语义下的真实含义移除 INBOX 标签而非删除邮件并覆盖按消息 ID、按线程、按搜索查询三种归档方式以及--max、--dry-run、--json等关键参数的实战用法。读完本文你将能够在终端中安全、批量、可脚本化地完成邮件收件箱清理并能结合源码理解其底层批量修改标签的实现机制。命令概览归档的本质是移除 INBOX 标签gog gmail archive的功能描述只有一句话Archive messages or explicit threads (remove from inbox)但其背后有一个容易误解的关键点Gmail 中没有独立的归档API归档在语义上等价于从收件箱中移除即给消息移除INBOX标签邮件仍然保留在所有邮件All Mail中可以被搜索到。这一点在源码中有明确印证。gogcli的归档命令定义在 internal/cmd/gmail_archive.go// GmailArchiveCmd archives messages (removes INBOX label). type GmailArchiveCmd struct { MessageIDs []string arg: optional: name:messageId help:Message IDs to archive, or thread IDs with --thread Query string name:query short:q help:Archive all messages matching this Gmail search query Max int64 name:max aliases:limit help:Max messages to archive (with --query) default:100 Thread bool name:thread help:Treat positional IDs as thread IDs and archive every message in each thread }非线程模式下命令最终调用gmailBulkLabelOp以移除标签INBOX为操作目标见 internal/cmd/gmail_archive.gofunc (c *GmailArchiveCmd) Run(ctx context.Context, flags *RootFlags) error { if c.Thread { return gmailArchiveThreads(ctx, flags, c.MessageIDs, c.Query) } return gmailBulkLabelOp(ctx, flags, c.MessageIDs, c.Query, c.Max, nil, []string{INBOX}, archived, gmail.archive) }从源码结构看gmailBulkLabelOp是一个被archive、trash、read、unread四个命令共用的批量标签操作框架通过传入不同的addLabels、removeLabels组合实现不同的邮件操作。归档就是不添加任何标签、只移除INBOX的特例。基本用法与位置参数命令的标准用法为gog gmail (mail,email) archive [messageId ...] [flags]gmail子命令同时提供mail与email两个别名因此以下写法等价gog gmail archive messageId gog mail archive messageId gog email archive messageId位置参数接受一个或多个消息 ID# 归档单封邮件 gog gmail archive 18abc123def45678 # 一次归档多封邮件 gog gmail archive 18abc123def45678 18def456abc12345 18fedcba09876543除了裸 IDgogcli还支持直接粘贴 Gmail 网页链接。链接解析逻辑位于 internal/cmd/webid.gonormalizeGmailMessageID会识别mail.google.com/gmail.google.com域名下的message_id、msg、permmsgid等查询参数并提取其中的十六进制消息 ID。这意味着你从浏览器地址栏复制的邮件链接可以原样作为位置参数传入。三种归档模式1. 按消息 ID 归档直接给出消息 ID 即可这是最精准、最小范围的操作适合处理单封或少量明确指定的邮件gog gmail archive 18abc123def45678当位置参数与--query同时提供时两者是并集关系先按查询收集匹配 ID再把位置参数中的 ID 追加进去见 internal/cmd/gmail_archive.go。2. 按线程归档--thread--thread模式把位置参数视为线程 ID并归档线程内的每一封邮件gog gmail archive --thread 18abc123def45678线程模式下同样支持 Gmail 网页链接。normalizeGmailThreadID见 internal/cmd/webid.go会解析两种经典链接格式查询参数形式https://mail.google.com/mail/?ththreadId片段形式https://mail.google.com/mail/u/0/#inbox/threadId因此你可以直接把收件箱中的会话链接粘贴进来gog gmail archive --thread \ https://mail.google.com/mail/u/0/#inbox/18abc123def45678 \ 18def456abc12345注意约束--thread与--query互斥。源码在gmailArchiveThreads中显式校验internal/cmd/gmail_archive.goif strings.TrimSpace(query) ! { return usage(--thread cannot be used with --query; provide thread IDs as positional arguments) }如果同时传入两者命令会以退出码 2 报错并提示。此外若未提供任何有效线程 ID同样会提示provide thread IDs with --thread。线程模式逐个调用Users.Threads.Modify接口逐线程移除INBOX标签并在结束时汇总成功与失败数量internal/cmd/gmail_archive.go。部分失败时命令会返回形如archived 2 of 3 threads; 1 failed的错误同时在 JSON 输出中给出每个线程的成功/失败明细。3. 按搜索查询批量归档-q/--query这是清理收件箱最高效的方式。用 Gmail 搜索语法描述目标邮件命令会先搜索匹配的邮件 ID再批量归档# 归档所有未读邮件 gog gmail archive --query is:unread # 归档一周前来自特定发件人的邮件 gog gmail archive -q from:newsletterexample.com older_than:7d # 归档所有邮件列表邮件 gog gmail archive -q list:devexample.com--query复用 Gmail 标准搜索语法in:inbox、is:unread、from:、older_than:、list:等可组合出高度精准的筛选条件。--max/--limit限制数量查询模式下默认最多处理 100 封默认值100可通过--max调整gog gmail archive -q older_than:30d --max 500注意两点约束均有源码与测试验证--max必须大于 0。gmailBulkLabelOp中校验--max must be 0internal/cmd/gmail_archive.go测试TestGmailBulkOps_QueryInvalidMaxFailsBeforeDryRun验证了传 0 或负数会报错internal/cmd/gmail_archive_test.go。--max仅对--query模式生效直接按 ID 归档时不限制数量。搜索实现searchMessageIDsinternal/cmd/gmail_archive.go会按每页最多 500 条分页拉取直到收集满--max或没有下一页为止。测试还验证了分页保护机制pageTokenGuardinternal/cmd/paging_guard.go若 API 重复返回相同的nextPageToken命令会中止并报repeated page token防止无限循环见 internal/cmd/gmail_archive_test.go。全局 Flags 详解gog gmail archive继承gog gmail的全部全局 flags下表为完整参数清单Flag类型默认值说明--access-tokenstring直接使用提供的 access token绕过已存储的 refresh tokentoken 约 1 小时后过期-a--account--acctstring指定账户邮箱、别名或auto用于需要认证的 Google API 命令--clientstringOAuth 客户端名称用于选择已存储的凭据和 token 桶--colorstringauto颜色输出auto|always|never--disable-commandsstring逗号分隔的禁用命令列表支持点路径-n--dry-run--dryrun--noop--previewbool不实际修改仅打印预期动作并以成功状态退出--enable-commandsstring逗号分隔的启用命令前缀列表支持点路径用于限制 CLI--enable-commands-exactstring逗号分隔的精确启用命令列表父命令不自动启用子命令-y--force--assume-yes--yesbool跳过破坏性命令的确认提示--gmail-no-sendboolfalse阻止 Gmail 发送操作Agent 安全选项-h--helpkong.helpFlag显示上下文相关的帮助信息--homestring覆盖 gogcli 的 config/data/state/cache 根目录等价于GOG_HOME-j--json--machineboolfalse向 stdout 输出 JSON最适合脚本化--max--limitint64100查询模式下最多归档的邮件数--no-input--non-interactive--noninteractivebool从不提示失败即报错适合 CI-p--plain--tsvboolfalse向 stdout 输出稳定、可解析的文本TSV无颜色-q--querystring归档所有匹配该 Gmail 搜索查询的邮件--quota-projectstring用于 API 计费的 Google Cloud 项目发送为X-Goog-User-Project头部分 API 与--access-token或 ADC 搭配时需要--readonlyboolfalse运行时阻止所有修改类 API 请求auth add也会申请只读 OAuth scope--results-onlyboolJSON 模式下只输出主结果丢弃nextPageToken等信封字段--select--pick--projectstringJSON 模式下选择逗号分隔的字段尽力而为支持点路径。多数命令推荐用--fields--threadbool将位置参数视为线程 ID归档线程内每封邮件-v--verbosebool启用详细日志--versionkong.VersionFlag打印版本并退出--wrap-untrustedboolfalseJSON/raw 输出中将获取的文本字段包裹在外部不可信内容标记中按使用目的可归类为认证与账户--account/-a/--acct、--client、--access-token、--quota-project。多账户场景下用-a指定目标邮箱--client用于选择不同的 OAuth 客户端凭据。安全与保护--dry-run、--force/-y、--readonly、--gmail-no-send、--no-input。归档虽是软操作不删除邮件但批量执行前仍建议先 dry-run。输出控制--json/-j、--plain/-p、--color、--results-only、--select、--wrap-untrusted。命令可见性--enable-commands、--enable-commands-exact、--disable-commands可用于限制 Agent 或脚本能执行的命令范围。Dry-run先预览再执行归档属于修改类操作gogcli 在所有修改命令入口都集成了 dry-run 保护。执行--dry-run时不会触碰认证、钥匙串或发起任何 API 调用而是打印将要执行的动作并以退出码 0 结束见 internal/cmd/dryrun.go。# 人类可读预览 gog gmail archive --query is:unread --dry-run # JSON 预览适合脚本解析 gog gmail archive --thread 18abc123def45678 --dry-run --jsondry-run 的 JSON 输出包含dry_run、op、request三个字段其中op固定为gmail.archiverequest描述具体动作。测试TestGmailBulkOps_DryRun_UsesSpecificOpsAndLabels验证了归档 dry-run 的语义操作名为gmail.archiveadded_labels为空数组、removed_labels为[INBOX]internal/cmd/gmail_archive_test.go。也就是说dry-run 会精确告诉你将移除哪些标签。另外注意dry-run 发生在账户认证之前因此即使未配置账户也能安全预览TestGmailArchiveCmd_DryRun_QueryMode_NoAccountRequired专门验证了这一点internal/cmd/gmail_archive_test.go。输出格式与脚本化实践默认情况下命令输出人类可读文本例如Archived 100 messages线程模式下的汇总输出为Archived 2 threadsJSON 输出--json/-j/--machinegog gmail archive -q is:unread --max 200 --json消息模式gmailBulkLabelOp的 JSON 结构包含action、count、addedLabels、removedLabels{ action: archived, count: 200, addedLabels: [], removedLabels: [INBOX] }线程模式gmailArchiveThreads的 JSON 结构更丰富包含逐线程结果internal/cmd/gmail_archive.go{ action: archived, count: 2, failed: 1, resource: thread, removedLabels: [INBOX], results: [ {threadId: 18abc123def45678, success: true}, {threadId: 18def456abc12345, success: false, error: googleapi: Error 404: not found} ] }--json与--dry-run组合可产出无副作用的机器可读预览非常适合在 CI 或脚本中做先校验、后执行的两阶段流程。TSV 输出--plain/-p/--tsvgog gmail archive --thread 18abc123def45678 --plainTSV 模式输出稳定、无颜色、易于awk/cut解析线程失败场景下每行输出线程ID\tarchived。无匹配时的行为查询模式下若没有匹配到任何邮件命令不会报错JSON 模式输出{action:archived,count:0}文本模式打印No messages found并正常退出internal/cmd/gmail_archive.go。这保证了脚本流水线不会因空收件箱而中断。底层实现批量标签操作与 1000 条分块理解归档的底层链路有助于预估大规模清理的行为。消息模式走gmailBulkLabelOpinternal/cmd/gmail_archive.go核心步骤归一化 ID对每个位置参数调用normalizeGmailMessageID空值被过滤若位置参数为空且无--query报错provide message IDs or --query。校验--max--query模式下--max必须大于 0。dry-run 检查若开启直接输出预期动作并返回。解析账户并创建 Gmail 服务调用requireAccount与gmailService。收集 ID有--query时通过searchMessageIDs分页搜索每页上限 500再追加位置参数中的 ID。标签名解析调用fetchLabelNameToIDinternal/cmd/gmail_labels.go拉取账户全部标签建立名称 → ID映射resolveLabelIDsinternal/cmd/gmail_labels_utils.go支持大小写不敏感匹配若传入的已是标签 ID 则原样透传。分块批量修改Gmail API 的BatchModifyMessages单次最多 1000 个 ID因此代码按 1000 条分块循环调用svc.Users.Messages.BatchModify任一分块失败会报出batch modify failed at offset %d便于定位internal/cmd/gmail_archive.go。输出汇总按 JSON / 文本模式输出归档数量。从源码结构看这一批量框架同时服务于四个命令归档移除INBOX、扔进垃圾箱添加TRASH并移除INBOX、标为已读移除UNREAD、标为未读添加UNREAD。如果后续有批量加星标批量打标签等需求复用同一管道即可扩展。与其他命令的关系gog gmail archive是 gogcli Gmail 命令族docs/commands/gog-gmail.md的一员与以下命令语义上易混淆使用时注意区分命令语义标签操作gog gmail archive从收件箱移除邮件仍可搜索移除INBOXgog gmail trash移入垃圾箱添加TRASH、移除INBOXgog gmail mark-read标为已读移除UNREADgog gmail unread标为未读添加UNREADgog gmail batch批量操作永久删除需要更宽的 Gmail scope视子命令而定归档不是删除邮件保留在所有邮件中也不计入删除配额适合作为收件箱整理的默认动作。需要彻底删除时再考虑gog gmail trash或gog gmail batch永久删除需要更宽的 Gmail scope见 docs/commands/gog-gmail.md 中的子命令说明。测试保障gogcli为归档命令提供了较完整的测试覆盖主要位于 internal/cmd/gmail_archive_test.go包括dry-run 语义验证opgmail.archive、removed_labels[INBOX]TestGmailBulkOps_DryRun_UsesSpecificOpsAndLabels查询模式免认证 dry-run--query--max预览无需配置账户TestGmailArchiveCmd_DryRun_QueryMode_NoAccountRequired线程模式 dry-run 与链接归一化验证 Gmail 网页链接可被解析为线程 IDTestGmailArchiveCmd_DryRun_ThreadMode线程/查询互斥--thread --query组合报错TestGmailArchiveCmd_ThreadModeRejectsQuery整线程归档mock HTTP 服务验证每个线程都收到RemoveLabelIds:[INBOX]的modify请求TestGmailArchiveCmd_ArchivesWholeThreads部分失败汇报单个线程 404 时 JSON 结果中该线程successfalse且带error字段TestGmailArchiveCmd_ReportsPartialThreadFailures--max合法性0 与负数直接报错TestGmailBulkOps_QueryInvalidMaxFailsBeforeDryRun分页安全重复nextPageToken时中止并报repeated page token防止分页死循环TestSearchMessageIDsRejectsRepeatedPageToken等。这些测试同时充当了命令行为规格读代码前先看测试能最快理解边界条件。实战建议先 dry-run 再执行批量清理收件箱属于影响面大的操作务必先用--dry-run --json确认将影响哪些邮件与线程。用--query限定范围并设置--max例如先归档 100 封验证效果确认无误后再放大数量。线程场景用--thread希望整段会话一起归档时直接粘贴 Gmail 网页会话链接即可gogcli会自动提取线程 ID。脚本化输出用--json或--plain两者都是稳定、可解析的格式配合--no-input可在 CI 中无交互运行。Agent 场景收紧权限--enable-commands-exact/--disable-commands可限制可用命令范围--readonly则会在运行时彻底阻止修改类请求作为归档这类写操作的安全兜底。延伸阅读命令族总览gog gmail全部命令索引Command index归档实现源码internal/cmd/gmail_archive.go归档测试用例internal/cmd/gmail_archive_test.goID 归一化与网页链接解析internal/cmd/webid.godry-run 机制实现internal/cmd/dryrun.go【免费下载链接】gogcliGoogle Workspace in your terminal.项目地址: https://gitcode.com/GitHub_Trending/gogcl/gogcli创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考
觉得有用,分享给同行:

为您的企业打造数字门面

稳重轻奢商务风格,端正雅致视觉,长效耐看不易过时。

立即咨询 →