gogcli `gog gmail messages search` 命令完全指南:用 Gmail 查询语法在终端搜索邮件
发布时间:2026/9/17 20:04:09 作者:尧图编辑部 阅读量:1,286

gogcligog gmail messages search命令完全指南用 Gmail 查询语法在终端搜索邮件【免费下载链接】gogcliGoogle Workspace in your terminal.项目地址: https://gitcode.com/GitHub_Trending/gogcl/gogcligog gmail messages search是 Google Workspace 命令行工具 gogcli 中用于在终端搜索 Gmail 邮件的核心只读命令它直接对接 Gmail 官方查询语法from:、to:、subject:、in:、is:、newer_than:等并支持分页、计数、正文提取、附件元数据与多种输出格式。本文以 docs/commands/gog-gmail-messages-search.md 为骨架结合 internal/cmd/gmail_messages.go、internal/cmd/gmail_search_request.go 等源码实现完整讲解该命令的用法、全部参数、底层工作原理与实战技巧。读完本文你将能够在终端中精确检索邮件、批量导出正文、接入脚本流水线并理解 gogcli 在分页与计数上做的工程化设计。命令概览与定位gog gmail messages search归属于gog gmail messages命令组子命令还包括 gog gmail messages modify其官方帮助信息为Search messages using Gmail query syntax该命令在命令组中标记为group:Read只读操作并注册了大量别名方便不同输入习惯gog gmail (mail,email) messages (message,msg,msgs) search (find,query,ls,list) query ... [flags]从源码看internal/cmd/gmail_messages.go#L24-L27GmailMessagesCmd只包含两个子命令search别名find,query,ls,list和modify别名update,edit,set。因此以下写法完全等价gog gmail messages search from:example.com gog gmail messages find from:example.com gog email msg query from:example.com gog mail msgs ls from:example.com其中query是一个可变参数[]string见 internal/cmd/gmail_messages.go#L30可以传入多个单词实现层会先用空格拼接再整体作为查询串strings.Join(c.Query, )。这意味着带空格的查询条件不需要手动加引号例如gog gmail messages search subject:meeting notes等价于subject:meeting notes当然如果你的 shell 环境特殊手动加引号同样安全。若最终拼接结果为空命令会直接报missing query错误internal/cmd/gmail_messages.go#L57-L60。基础用法示例搜索发件人为特定域名的邮件默认返回前 10 条--max默认值为 10gog gmail messages search from:example.com组合多个条件——未读的垃圾邮件最多返回 1000 条gog gmail messages search in:spam is:unread --max 1000按时间窗口搜索最近 7 天包含附件的邮件gog gmail messages search has:attachment newer_than:7dgogcli 对查询串做了一个有价值的优化会把查询中的系统标签词转换成 Gmail API 的labelIds参数一并下发见 internal/cmd/gmail_search_labels.go。例如in:spam is:unread会被拆解为qin:spam is:unreadlabelIdsSPAM,UNREAD用 internal/cmd/execute_gmail_messages_search_text_test.go#L282-L315 中的测试TestExecute_GmailMessagesSearch_AppliesSystemLabelFilters验证了这一点测试断言请求中的q参数原样保留为in:spam is:unread同时labelIds参数携带了SPAM和UNREAD。该转换覆盖查询写法转换后的系统标签 IDis:unread/label:unreadUNREADis:starred/label:starredSTARREDis:important/label:importantIMPORTANTin:inbox/label:inboxINBOXin:sent/label:sentSENTin:draft/in:drafts/label:draft(s)DRAFTin:spam/is:spam/label:spamSPAMin:trash/label:trashTRASHcategory:primaryCATEGORY_PERSONALcategory:socialCATEGORY_SOCIALcategory:promotionsCATEGORY_PROMOTIONScategory:updatesCATEGORY_UPDATEScategory:forumsCATEGORY_FORUMS需要说明的是该转换是保守的如果查询中出现OR或者花括号{}Gmail 的复杂布尔语法转换会整体放弃只靠q参数查询以-开头的否定条件也会被跳过internal/cmd/gmail_search_labels.go#L18-L40。这是纯优化不影响查询结果语义。命令级参数详解gog gmail messages search继承了 gogcli 的全局参数体系同时定义了本命令特有的搜索参数。下表完整列出该命令的全部可用参数来源docs/commands/gog-gmail-messages-search.mdFlagTypeDefaultHelp--access-tokenstringUse provided access token directly (bypasses stored refresh tokens; token expires in ~1h)-a--account--acctstringAccount email, alias, or auto for authenticated Google API commands--all--all-pages--allpagesboolFetch all pages--body-formatstringtextBody format preference when --include-body is set: text or html--clientstringOAuth client name (selects stored credentials token bucket)--colorstringautoColor output: auto|always|never--countboolReport the whole-query count as totalMatches (exact) or totalMatchesAtLeast (lower bound); free with --all unless --page is set; unavailable with --results-only--disable-commandsstringComma-separated list of disabled commands; dot paths allowed-n--dry-run--dryrun--noop--previewboolDo not make changes; print intended actions and exit successfully--enable-commandsstringComma-separated list of enabled command prefixes; dot paths allowed (restricts CLI)--enable-commands-exactstringComma-separated list of exact enabled commands; dot paths allowed and parent commands do not enable children--fail-empty--non-empty--require-resultsboolExit with code 3 if no results-y--force--assume-yes--yesboolSkip confirmations for destructive commands--fullboolShow full message bodies without truncation (implies --include-body)--gmail-no-sendboolfalseBlock Gmail send operations (agent safety)-h--helpkong.helpFlagShow context-sensitive help.--homestringOverride gogcli config/data/state/cache root (equivalent to GOG_HOME)--include-attachmentsboolInclude each messages attachment metadata--include-bodyboolInclude decoded message body (JSON is full; text output truncates only unusually large bodies)-j--json--machineboolfalseOutput JSON to stdout (best for scripting)--localboolUse local timezone (default behavior, useful to override --timezone)--max--limitint6410Max results--no-input--non-interactive--noninteractiveboolNever prompt; fail instead (useful for CI)--page--cursorstringPage token-p--plain--tsvboolfalseOutput stable, parseable text to stdout (TSV; no colors)--quota-projectstringGoogle Cloud project to bill for API usage (sent as X-Goog-User-Project; some APIs require it with --access-token or ADC)--readonlyboolfalseBlock mutating API requests at runtime; auth add also requests read-only OAuth scopes--results-onlyboolIn JSON mode, emit only the primary result (drops envelope fields like nextPageToken)--select--pick--projectstringIn JSON mode, select comma-separated fields (best-effort; supports dot paths). Desire path: use --fields for most commands.-z--timezonestringOutput timezone (IANA name, e.g. America/New_York, UTC). Default: GOG_TIMEZONE, config, then local--use-indexed-attachment-idsboolUse 0-based indexes as attachment ids everywhere (output, the download argument, and saved filenames)-v--verboseboolEnable verbose logging--versionkong.VersionFlagPrint version and exit--wrap-untrustedboolfalseIn JSON/raw output, wrap fetched text fields in external untrusted-content markers其中本命令专属、决定搜索行为的关键参数在 internal/cmd/gmail_messages.go#L29-L43 中定义包括Query位置参数搜索查询串--max/--limit默认10最大返回条数源码要求--max必须大于 0internal/cmd/gmail_search_request.go#L26-L31否则报--max must be 0测试见 internal/cmd/gmail_max_validation_test.go--page/--cursor分页游标配合返回的nextPageToken翻页--all/--all-pages/--allpages一次性抓取所有页--fail-empty/--non-empty/--require-results无结果时以退出码 3 结束适合脚本判空--count统计整个查询的真实匹配数--timezone/-z与--local控制日期显示时区--include-body、--body-format、--full控制正文提取--include-attachments、--use-indexed-attachment-ids控制附件元数据--results-only、--select/--pick控制 JSON 输出结构。其余为 gogcli 全局参数账号选择--account、OAuth 客户端--client、只读保护--readonly、JSON 输出-j/--json、TSV 输出-p/--plain、CI 友好的--no-input等适用于所有命令。其中--readonly会在运行时拦截所有变更类 API 请求与本命令的只读属性天然契合适合把搜索命令放进受保护环境。结果数量与分页--max、--page 与 --allGmail API 的messages.list单次最多返回一页gogcli 单页请求受 Gmail 上限约束分页探测页大小被固定在 500见 internal/cmd/gmail_search_count.go#L12-L14。gogcli 通过 internal/cmd/paged_list_helpers.go 中的loadPagedItems统一处理三种模式单页模式默认只取第一页返回nextPageToken供继续翻页--page token从指定游标开始取下一页--all循环抓取直到没有nextPageToken一次性返回全部结果此时nextPageToken不再输出。示例——先取第一页gog gmail messages search from:example.com --max 10 --json返回的 JSON 中nextPageToken字段即游标把它传给--page继续gog gmail messages search from:example.com --max 10 --page 17989675150306773312 --json在文本模式下表格输出到 stdout而分页提示如Showing page 2; use --page token or --all/--all-pages to fetch more写到 stderr保证 stdout 始终可被管道消费internal/cmd/gmail_messages.go#L157。--count准确的整库匹配数--count回答一个很容易被忽略的问题当前这页只是结果集的一部分整个查询到底有多少封邮件匹配其实现位于 internal/cmd/gmail_search_count.go计数通过一次额外的messages.list探测请求完成只请求messages/id,nextPageToken字段开销极小若单页装得下全部结果nextPageToken为空则计数是精确的JSON 中写入totalMatches否则是下界写入totalMatchesAtLeast见gmailMatchCount.applyinternal/cmd/gmail_search_count.go#L28-L34绝不把下界冒充总数文本模式下计数输出到 stderr例如Showing 3 of 6 matches.或Showing 10 of at least 500 matches.internal/cmd/gmail_search_count.go#L76-L86三个特例resolveGmailMatchCountinternal/cmd/gmail_search_count.go#L105-L125配合--all且未指定--page时已抓取的条目就是全量计数免费不再发额外请求配合--results-only时计数无效计数属于 envelope 字段--results-only恰恰要丢弃 envelope命令会在 stderr 说明并跳过额外请求其余情况发起探测请求。源码注释特别解释了为何不用 Gmail 自带的resultSizeEstimate实测它会对任意非空查询饱和在固定值 201几乎是个有没有结果的布尔量无法真实反映匹配数internal/cmd/gmail_search_count.go#L36-L47。这是一个值得在文章里强调的实现取舍gogcli 宁可在窄查询场景多花一次轻量请求也要给出可信的计数并在无法精确时明确标注至少。--fail-empty脚本判空gog gmail messages search from:example.com --fail-empty无匹配时退出码为 3配合--no-input可在 CI 或 shell 脚本中直接判断是否存在某类邮件。输出格式表格、TSV 与 JSON文本表格默认默认输出对齐的文本表格列定义见 internal/cmd/gmail_presentation.go#L33-L68 的gmailMessageColumnsID THREAD DATE FROM SUBJECT LABELS [BODY] [ATTACHMENTS]基础列固定为ID、THREAD、DATE、FROM、SUBJECT、LABELS传入--include-body时追加BODY列传入--include-attachments时追加ATTACHMENTS列显示文件名、MIME 类型与人类可读大小如invite.ics (text/calendar, 2.0 KB)。TSV / plain-p/--plain/--tsv输出无颜色、以 Tab 分隔的稳定文本便于awk、cut等工具进一步处理gog gmail messages search from:example.com --plain | cut -f5 # 取 SUBJECT 列--color never可以进一步关闭所有着色。JSON-j/--json/--machine输出结构化 JSON最适合脚本化消费{ messages: [ { id: 18f0..., threadId: 18f0..., date: 2026-09-10T15:04:05-07:00, internalDateIso: 2026-09-10T15:04:05-07:00, from: Example no-replyexample.com, subject: Receipt, labels: [INBOX], body: Total €99.99, attachments: [ {filename: invite.ics, mimeType: text/calendar, size: 2048, attachmentId: att-ics} ] } ], nextPageToken: ... }字段结构对应源码中的messageItem类型internal/cmd/gmail_messages.go#L223-L240。值得留意的是internalDateIso与date的区别date解析的是发件人写在邮件头里的Date头而internalDateIso是 Gmail 服务器接收时间internalDate转成的 RFC3339二者在头部异常或时区错乱时可能不一致脚本解析应以internalDateIso为准。--results-only去掉 envelopenextPageToken、计数等只输出messages数组本身--select/--pick按逗号分隔的字段选择子集支持点路径属于尽力而为的字段裁剪。正文提取--include-body、--body-format 与 --full--include-body解码并返回正文。JSON 模式返回完整正文文本模式会对超长正文截断默认上限 20,000 字符并附加明确的提示... [truncated; use --full or --json]internal/cmd/gmail_messages.go#L20-L21--body-formattext默认或html。text 模式从 multipart 结构中优先抽取纯文本部分测试 internal/cmd/execute_gmail_messages_search_text_test.go#L83-L200 验证了Total €99.99的正确解码同时 HTML 源码不被混入html 模式返回 HTML 原文BestBodyHTML--full不截断正文且源码中自动隐含--include-bodyinternal/cmd/gmail_messages.go#L46-L48。正文截断的取舍在测试 internal/cmd/execute_gmail_messages_search_text_test.go#L202-L280 中被严格验证超长正文必须截断并带可操作的提示标记而--full必须完整输出且不含截断标记。附件元数据--include-attachments 与 --use-indexed-attachment-ids--include-attachments在输出中列出每封邮件的附件信息文件名、MIME、大小、attachmentId。注意文本表格刻意不展示 attachmentId——因为 Gmail 每次抓取都会生成新的临时 token不适合作为稳定句柄attachmentId 只在 JSON 中给出internal/cmd/gmail_presentation.go#L49-L51--use-indexed-attachment-ids全程改用 0 起始的索引作为附件 ID影响输出、下载参数与保存文件名便于按位置确定性操作附件。该参数同时受环境变量GOG_GMAIL_USE_INDEXED_ATTACHMENT_IDS控制。底层实现原理一次搜索请求的完整链路从源码看一次gog gmail messages search的执行流程internal/cmd/gmail_messages.go#L45-L159如下参数预处理--full隐含--include-body校验--max 0确定账号拼接查询串把多个query位置参数TrimSpace后以空格拼接空查询直接报错第一步列表请求调用svc.Users.Messages.List(me)通过applyGmailMessageListOptionsinternal/cmd/gmail_search_request.go#L44-L52设置q、maxResults、labelIds若查询命中系统标签与pageToken且只请求messages(id,threadId),nextPageToken字段——第一轮只拿 ID 列表不拉全文分页聚合按--page/--all语义通过loadPagedItems收集消息 ID计数可选--count时发一次只取 ID 的探测请求计算全量匹配数详情并发抓取fetchMessageDetailsinternal/cmd/gmail_messages.go#L242-L355对每条消息执行Messages.Get——不带正文/附件时使用formatmetadata并只请求必要的 summary 字段性能最优需要正文或附件时使用formatfull。并发度受信号量限制为 10结果按原始顺序重组任一条失败即整体报错附带 message ID 便于定位标签名解析通过一次labels.list把标签 ID 映射为可读名称internal/cmd/gmail_messages.go#L114-L116时区处理按--timezone/--local/环境变量/配置的优先级解析输出时区格式化Date头与internalDateinternal/cmd/gmail_messages.go#L119-L121输出按文本表格 / TSV / JSON 三种模式渲染空结果时输出No results并按--fail-empty决定退出码 3有分页时在 stderr 打印下一页提示。这套先列表拿 ID、再并发拿详情、最后统一渲染的设计让--max很小时只产生少量请求而--all大规模抓取时又能通过并发保持吞吐。实战场景与联动建议场景一审计某段时间来自特定域名的邮件gog gmail messages search from:vendor.com newer_than:30d --count --max 500 --plain--count给出总数精确或至少--plain便于后续管道处理。场景二把搜索结果喂给其他命令搜索返回的消息id是 gogcli 其他 Gmail 命令的输入。例如先搜索再对某封邮件做标签修改gog gmail messages search subject:invoice is:unread --max 5 --plain | head -5 gog gmail messages modify 18f0... --add Important --remove UNREADmodify子命令的用法见 gog gmail messages modify对应源码 internal/cmd/gmail_messages.go#L161-L221。场景三抓取正文做离线分析gog gmail messages search from:alertsexample.com newer_than:1d --all --include-body --json --results-only用--all保证不遗漏分页--json --results-only输出可直接进入jq的数组。场景四在 CI 或 Agent 环境中使用gog gmail messages search in:inbox is:unread --fail-empty --no-input --readonly--fail-empty让无结果以退出码 3 呈现--no-input禁止交互提示--readonly作为运行时兜底拦截一切变更请求再配合全局的--gmail-no-send阻断 Gmail 发送类操作可以构造一个只读、可预测的自动化环境。测试与验证gogcli 为gog gmail messages search提供了覆盖多种行为的 HTTP mock 测试使用httptest模拟 Gmail API 响应可作为行为规范的补充文档阅读internal/cmd/execute_gmail_messages_search_text_test.go文本模式输出、JSON --include-body的 multipart 解码、--body-format html、正文截断与--full、系统标签到labelIds的转换internal/cmd/gmail_max_validation_test.go--max非法值的校验同时覆盖了gmail search与gmail messages search两条命令路径internal/cmd/gmail_search_count_test.go--count的精确/下界判定与--results-only冲突处理。此外命令文档由gog schema --json自动生成文档头部标注 Generated fromgog schema --json. Do not edit this page by hand完整命令索引见 docs/commands/README.md。小结gog gmail messages search是 gogcli 里 Gmail 只读能力的主力入口它把 Gmail 查询语法带进了终端用--max/--page/--all解决分页用--count给出诚实的结果计数用--include-body/--include-attachments实现正文与附件元数据提取并提供表格、TSV、JSON 三种输出形态。从源码可以看到它的一贯工程取向——能省则省先 ID 后并发详情、标签词转labelIds、不能省就讲清楚计数精确/下界明确标注、截断带提示、nextPageToken与计数走 stderr 保持 stdout 可解析。无论是日常查信、脚本巡检还是 Agent 自动化这条命令都值得优先掌握。【免费下载链接】gogcliGoogle Workspace in your terminal.项目地址: https://gitcode.com/GitHub_Trending/gogcl/gogcli创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考