gogcli 联系人管理:gog contacts other命令完整指南(Other Contacts 查询与检索)
【免费下载链接】gogcliGoogle Workspace in your terminal.项目地址: https://gitcode.com/GitHub_Trending/gogcl/gogcli
本指南以 gog-contacts-other 命令文档 为主体,结合 gogcli 仓库中
internal/cmd与internal/googleapi的源码实现,深入讲解如何在终端中通过gog contacts other子命令浏览与检索 Google 通讯录中的 "Other Contacts"(其他联系人)。读完本文,你将掌握other list/other search两个子命令的完整用法、全部参数语义、输出格式以及其背后的 People API 调用原理,可直接用于日常联系人与脚本化数据获取。
什么是 Other Contacts
Google 通讯录在 People API 中将联系人划分为多种来源(source type),其中 "Other Contacts" 是一类特殊的联系人集合:它们通常来自 Gmail 的历史往来(你曾经给某人发过邮件、但从未主动将其加入"我的联系人"),Google 会自动把它们归入 Other Contacts。这类联系人在移动端与网页端的通讯录中默认不展示,只有主动"转存"到我的联系人后才会出现在常用联系人列表中。
gogcli 将这一集合作为独立命令组gog contacts other暴露出来,与gog contacts(我的联系人)和gog contacts directory(组织通讯录/目录)并列。从源码结构可以清晰看到三者的并列关系:
- internal/cmd/contacts.go#L24 在顶层命令中注册
Other ContactsOtherCmd cmd:"" name:"other" help:"Other contacts"; - internal/cmd/contacts_directory.go#L210-L213 定义
ContactsOtherCmd,下辖List与Search两个子命令。
gog contacts other本身不执行任何动作,它是一个命令命名空间,用于组织对 Other Contacts 集合的只读查询操作(本命令组内没有增删改等变更操作)。
命令结构与用法
gog contacts other的完整调用路径如下:
gog contacts (contact) other <command>其中括号中的(contact)表示该位置的参数可选(别名语义),实际书写时直接使用contacts即可,例如:
gog contacts other list gog contacts other search "Alice"命令层级关系:
- 父命令:gog contacts(Google Contacts 顶层命令组)
- 当前命令:
gog contacts other(Other contacts) - 子命令:
- gog contacts other list —— 分页列出 Other Contacts
- gog contacts other search —— 按查询词搜索 Other Contacts
该层级定义可以在 internal/cmd/contacts_directory.go#L210-L213 中验证:ContactsOtherCmd通过cmd:"" name:"list"与cmd:"" name:"search"声明了两个子命令。
子命令一:gog contacts other list
列出当前账户下的 Other Contacts,等价于调用 People API 的otherContacts.list接口。
gog contacts other list [flags]专属参数
| 参数 | 别名 | 类型 | 默认值 | 说明 |
|---|---|---|---|---|
--max | --limit | int64 | 100 | 单页最大返回条数(PageSize) |
--page | --cursor | string | 分页游标/PageToken,用于翻页 | |
--all | --all-pages、--allpages | bool | 自动抓取全部分页 | |
--fail-empty | --non-empty、--require-results | bool | 无结果时以退出码 3 结束(适合脚本判断) |
源码实现在 internal/cmd/contacts_directory.go#L217-L222:
type ContactsOtherListCmd struct { Max int64 `name:"max" aliases:"limit" help:"Max results" default:"100"` Page string `name:"page" aliases:"cursor" help:"Page token"` All bool `name:"all" aliases:"all-pages,allpages" help:"Fetch all pages"` FailEmpty bool `name:"fail-empty" aliases:"non-empty,require-results" help:"Exit with code 3 if no results"` }分页行为
list采用游标式分页。首次调用无需指定--page;返回结果若包含nextPageToken(nextPageToken 非空),命令行会提示你使用--all/--all-pages自动拉取后续页。核心循环位于 internal/cmd/contacts_directory.go#L239-L254:每次请求以PageSize(c.Max)+ 可选PageToken调用svc.OtherContacts.List(),通过loadPagedItems(c.Page, c.All, fetch)统一处理单页与全量抓取。
使用建议:
- 数据量不大时,直接
gog contacts other list即可; - 需要完整导出时,加
--all自动翻页; - 在脚本中判断"是否为空",加
--fail-empty(退出码 3 表示无结果)。
输出示例(表格模式)
list的默认表格输出由 internal/cmd/contacts_presentation.go#L39-L46 的otherContactColumns()定义,包含四列:
RESOURCE NAME EMAIL PHONE otherContacts/c1 Ada Lovelace ada@example.com +1 555-0100 otherContacts/c2 Grace Hopper grace@example.com对应字段说明:
RESOURCE:People API 的资源名(otherContacts/xxx),可用于后续定位;NAME:主要显示名(primaryName);EMAIL:主要邮箱(primaryEmail);PHONE:主要电话号码(primaryPhone)。
底层数据读取使用了contactsOtherReadMask = "names,emailAddresses,phoneNumbers"(见 internal/cmd/contacts_directory.go#L215),因此列表只展示这三类字段,与表头一一对应。
子命令二:gog contacts other search
按关键词在 Other Contacts 中搜索,等价于 People API 的otherContacts.search接口。
gog contacts other search <query> ... [flags]<query>为位置参数,可传多个词,执行时内部以空格拼接为单一查询串(见 internal/cmd/contacts_directory.go#L313 的strings.Join(c.Query, " "))。
专属参数
| 参数 | 别名 | 类型 | 默认值 | 说明 |
|---|---|---|---|---|
--max | --limit | int64 | 50 | 最大返回条数(PageSize) |
search 与 list 的默认页大小不同(search 默认 50,list 默认 100),使用时需注意。定义见 internal/cmd/contacts_directory.go#L306-L309:
type ContactsOtherSearchCmd struct { Query []string `arg:"" name:"query" help:"Search query"` Max int64 `name:"max" aliases:"limit" help:"Max results" default:"50"` }搜索缓存预热机制
一个值得注意的实现细节:search在真正发起查询前会先执行一次"预热"请求,即 internal/cmd/contacts_search_cache.go#L25-L36 中的warmSearchOtherContactsCache:
func warmSearchOtherContactsCache(ctx context.Context, svc *people.Service) { _, err := svc.OtherContacts.Search(). Query(""). PageSize(1). ReadMask(contactsOtherReadMask). Context(ctx). Do() if err != nil { return } waitForContactsSearchWarmup(ctx) }该函数先以空查询、PageSize(1)触发一次搜索,触发 Google 侧对 Other Contacts 索引的构建,随后等待约 5 秒(contactsSearchWarmupDelay = 5 * time.Second,见 internal/cmd/contacts_search_cache.go#L10)。这是因为 People API 的otherContacts.search依赖异步索引,新写入的联系人可能尚未可搜;预热能显著提升搜索结果的新鲜度。测试 internal/cmd/execute_contacts_test.go#L190(TestExecute_ContactsOtherSearch_WarmsCache)专门验证了这一预热行为。
因此search命令的执行耗时通常会比list多几秒,这是预期行为,并非卡死。
使用示例
# 搜索名字/邮箱包含 Ada 的其他联系人 gog contacts other search "Ada" # 多关键词搜索(内部以空格连接) gog contacts other search "Alice Smith" # 限制返回数量 gog contacts other search "ada" --max 20 # 以 JSON 输出供脚本消费 gog contacts other search "ada" --json输出格式:表格 / JSON / TSV
两个子命令均遵循 gogcli 统一的输出模型:
- 默认输出为终端友好的彩色表格(可用
--color never关闭); -j/--json/--machine:输出 JSON 到 stdout,适合脚本与 LLM 消费;-p/--plain/--tsv:输出稳定的制表符分隔文本,无颜色,适合解析。
JSON 结构
以list为例(见 internal/cmd/contacts_directory.go#L258-L286),JSON 输出为:
{ "contacts": [ { "resource": "otherContacts/c1", "name": "Ada Lovelace", "email": "ada@example.com", "phone": "+1 555-0100" } ], "nextPageToken": "Cg0..." }search的 JSON 输出同样包含contacts数组(字段同上),但不含nextPageToken(见 internal/cmd/contacts_directory.go#L336-L356)。
搭配--results-only可丢弃nextPageToken等外围字段,只输出主结果;搭配--select可按逗号分隔字段名(支持点路径)做字段裁剪。
空结果与脚本语义
list在空结果时打印No results,若同时指定--fail-empty,则返回退出码 3(见 internal/cmd/contacts_directory.go#L289-L292);search在空结果时打印No results并以成功状态退出(见 internal/cmd/contacts_directory.go#L359-L362)。
这一差异对脚本编写很重要:判断"列表为空"用--fail-empty,判断"搜索无命中"直接解析输出即可。
全局标志
gog contacts other及其两个子命令都继承 gogcli 的全局标志体系(由根命令注入,--help上下文相关)。以下为完整清单(摘自 gog-contacts-other 命令文档):
| Flag | Type | Default | Help |
|---|---|---|---|
--access-token | string | 直接使用提供的访问令牌(绕过存储的刷新令牌;令牌约 1 小时过期) | |
-a--account--acct | string | 账户邮箱、别名或 auto(用于需要认证的 Google API 命令) | |
--client | string | OAuth 客户端名称(选择存储的凭据 + 令牌桶) | |
--color | string | auto | 颜色输出:auto|always|never |
--disable-commands | string | 逗号分隔的禁用命令列表;支持点路径 | |
-n--dry-run--dryrun--noop--preview | bool | 不执行变更;打印预期动作并以成功退出 | |
--enable-commands | string | 逗号分隔的启用命令前缀;支持点路径(限制 CLI 范围) | |
--enable-commands-exact | string | 逗号分隔的精确启用命令;支持点路径,父命令不会启用子命令 | |
-y--force--assume-yes--yes | bool | 跳过破坏性命令的确认 | |
--gmail-no-send | bool | false | 阻止 Gmail 发送操作(Agent 安全) |
-h--help | kong.helpFlag | 显示上下文相关帮助 | |
--home | string | 覆盖 gogcli 的 config/data/state/cache 根目录(等价于 GOG_HOME) | |
-j--json--machine | bool | false | 向 stdout 输出 JSON(最适合脚本) |
--no-input--non-interactive--noninteractive | bool | 从不提示;直接失败(适合 CI) | |
-p--plain--tsv | bool | false | 向 stdout 输出稳定、可解析的文本(TSV;无颜色) |
--quota-project | string | 用于 API 计费的 Google Cloud 项目(作为 X-Goog-User-Project 发送;部分 API 与 --access-token 或 ADC 联用时必需) | |
--readonly | bool | false | 运行时阻止变更类 API 请求;auth add 同时只请求只读 OAuth 范围 |
--results-only | bool | JSON 模式下只输出主结果(丢弃 nextPageToken 等外围字段) | |
--select--pick--project | string | JSON 模式下按逗号分隔选择字段(尽力而为;支持点路径)。大多数命令推荐使用 --fields | |
-v--verbose | bool | 启用详细日志 | |
--version | kong.VersionFlag | 打印版本并退出 | |
--wrap-untrusted | bool | false | JSON/raw 输出中,用外部不可信内容标记包裹获取的文本字段 |
对gog contacts other而言,最常用的组合是:
# 全量列出并以 JSON 输出,供下游脚本使用 gog contacts other list --all --json # 在 CI 中搜索,失败即退出、无结果退出码 3 语义由 --fail-empty 提供(list 场景) gog contacts other list --fail-empty --no-input --json # 指定账户(多账户场景) gog contacts other search "Ada" --account work@example.com源码实现与调用链
gog contacts other的执行链路如下:
- 命令解析:kong 解析
gog contacts other list/search,命中 internal/cmd/contacts_directory.go#L210 定义的ContactsOtherCmd; - 账户解析:
requireAccount(flags)确定目标账户(配合--account/--acct/ 默认 auto); - 服务构造:
peopleOtherContactsService(ctx, account)(见 internal/cmd/runtime_services.go#L401-L407)经由运行时的Services.PeopleOther工厂获取 People API 客户端; - API 调用:
list调用svc.OtherContacts.List()(internal/cmd/contacts_directory.go#L240);search先warmSearchOtherContactsCache预热,再调用svc.OtherContacts.Search()(internal/cmd/contacts_directory.go#L327-L332);
- 输出渲染:表格走
outfmt.WriteTable+otherContactColumns(),JSON 走outfmt.WriteJSON。
People API 客户端由 internal/googleapi/people.go#L19 的NewPeopleOtherContacts创建,工厂方法注册于 internal/googleapi/factory.go#L154-L155。
只读安全语义
other命令组整体为只读操作(无创建/更新/删除子命令)。配合全局--readonly标志可进一步确保运行时不会发出任何变更类 API 请求;结合--no-input可用于 CI 流水线。
测试覆盖
仓库为 Other Contacts 命令提供了完整测试:
- internal/cmd/execute_contacts_more_commands_test.go 用 httptest 模拟
otherContacts:search与/otherContacts分页响应,覆盖 JSON 输出与--max校验; - internal/cmd/execute_contacts_test.go#L190 验证 search 前的缓存预热行为;
- internal/cmd/contacts_presentation_test.go#L37 覆盖
other contacts表格列渲染。
进阶:与备份功能的联动
Other Contacts 数据还会出现在 gogcli 的备份功能中:gog backup会通过fetchBackupOtherContacts拉取 Other Contacts 并计入备份统计(contacts.other计数),见 internal/cmd/backup_services.go#L175-L199,其读取掩码为names,emailAddresses,phoneNumbers(internal/cmd/backup_services.go#L409),与contactsOtherReadMask保持一致。这意味着你既可以用gog contacts other单独查询,也可以依赖gog backup将 Other Contacts 一并纳入定期备份。
常见问题
Q:为什么gog contacts other search比 list 慢?A:search 会先执行一次空查询预热请求,并等待约 5 秒(internal/cmd/contacts_search_cache.go#L10),这是为了让 Google 侧异步索引就绪,属于设计行为。
Q:gog contacts other list能拿到所有其他联系人吗?A:单次调用最多返回--max(默认 100)条。数据量更大时需使用--all(自动翻页)或手动逐页传--page。
Q:Other Contacts 与"我的联系人"(contacts list)有何区别?A:gog contacts other对应 People API 的otherContacts集合(历史往来自动归类的联系人),而 gog contacts list 对应people集合(用户主动保存的联系人),两者是相互独立的资源命名空间(otherContacts/xxxvspeople/xxx)。
相关资源
- gog contacts other list 命令文档
- gog contacts other search 命令文档
- gog contacts 父命令文档(含 create/get/update/delete/export 等完整联系人操作)
- gog contacts directory 组织目录命令
- 命令索引 查看全部命令
【免费下载链接】gogcliGoogle Workspace in your terminal.项目地址: https://gitcode.com/GitHub_Trending/gogcl/gogcli
创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考