news 2026/9/20 5:12:20

gogcli 实战指南:用 `gog maps places search` 在终端里做 Google Places 文本搜索

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
gogcli 实战指南:用 `gog maps places search` 在终端里做 Google Places 文本搜索

gogcli 实战指南:用gog maps places search在终端里做 Google Places 文本搜索

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

本篇聚焦 gogcli(Google Workspace in your terminal)中的gog maps places search子命令:如何完成 Places API 密钥配置、如何按文本搜索地点、如何以 TSV/JSON 两种格式消费结果,并结合源码拆解命令从参数解析到 HTTP 请求的完整调用链。读完你不仅能直接复制命令用于脚本与 Agent 工作流,还能理解该命令底层调用的 Places API v1 接口形态(places:searchText、字段掩码、密钥鉴权头)与错误边界。

命令概览与别名体系

gog maps places search是 gogcli Maps 子树下的地点文本搜索命令,官方文档页 gog-maps-places-search.md 给出的标准用法为:

gog maps (map) places (place) search (find) <query> ... [flags]

括号中的内容是别名:命令树在 internal/cmd/maps.go 中用 kong 标签注册,maps可写作mapplaces可写作placesearch可写作find。也就是说下面三种写法等价:

gog maps places search "cafe in Berlin" gog map place find "cafe in Berlin"

query是位置参数,且支持多段——从源码看,参数定义为Query []string,运行时用空格把所有片段拼接成一个查询串(见 MapsPlacesSearchCmd.Run),所以不必担心 shell 引号截断,gog maps places search cafe in Berlin与加引号效果一致;若拼接后为空则直接报missing query

该命令在 Maps 子树中属于 Places 分支(docs/commands/gog-maps-places.md),与gog maps places details平级,同级的还有directionsdistancegeocodereverse-geocode(见 docs/commands/gog-maps.md 对应的 internal/cmd/maps.go 命令树定义)。完整命令索引见 docs/commands/README.md。

Places API 密钥的三种配置方式

gog maps places search使用 Google API 密钥(而非 OAuth 账号)鉴权。密钥解析入口是 placesAPIKey,其读取逻辑由 internal/config/keys.go 中的KeyPlacesAPIKey规格定义,按以下优先级取第一个非空值:

  1. 环境变量GOG_PLACES_API_KEY
  2. 环境变量GOOGLE_PLACES_API_KEY
  3. 配置文件中的places_api_key项(通过gog config set places_api_key <key>写入,配置项在 internal/config/config.go 中映射为places_api_keyJSON 字段)。

该键被标记为Sensitive: true,即配置读写路径会对其做脱敏处理。三个来源都缺失时,命令给出明确的排障提示:

Google Maps/Places API key required. Set GOG_PLACES_API_KEY, GOOGLE_PLACES_API_KEY, or run 'gog config set places_api_key <key>'

因此最省事的落地方式是:

gog config set places_api_key AIza... # 写入配置 # 或临时使用环境变量(适合 CI): GOG_PLACES_API_KEY=AIza... gog maps places search "coffee"

命令参数详解

该命令自身只有两个查询参数,其余为全局通用 flag:

参数类型说明
<query> ...位置参数(多值)文本搜索查询串,多个片段会以空格拼接;空串直接报 usage 错误
--languagestringBCP-47 语言代码,作为请求体languageCode下发
--regionstringCLDR 地区代码,作为请求体regionCode下发,用于结果本地化偏好

--language--region会经strings.TrimSpace处理后装入googleapi.PlacesLookupOptions(见 internal/cmd/maps.go),仅当非空时才写入请求,即不传时对 API 默认行为零影响。

全局常用 Flag

文档页列出的完整 Flag 表覆盖所有 gogcli 全局 flag,这里挑出与脚本化、Agent 场景最相关的几项(完整表格以 gog-maps-places-search.md 为准):

Flag类型默认作用
-j/--json/--machineboolfalse以 JSON 输出到 stdout,最适合脚本消费
-p/--plain/--tsvboolfalse输出稳定可解析的 TSV 文本(无颜色)
--select/--pickstringJSON 模式下选取逗号分隔字段(支持点路径,尽力而为)
--results-onlyboolJSON 模式只输出主结果,丢弃nextPageToken等信封字段
--colorstringauto颜色输出:auto/always/never
-n/--dry-run等别名bool不产生变更,仅打印意图动作
--no-input/--non-interactivebool从不交互提问,失败即退出(CI 友好)
-a/--accountstring账号邮箱、别名或auto(本命令走 API 密钥,一般用不到)
--access-tokenstring直接使用给定 access token(本命令不使用 OAuth)
--quota-projectstring计费项目(X-Goog-User-Project
--enable-commands/--disable-commandsstring以点路径限制/禁用命令前缀,做 CLI 收窄
--wrap-untrustedboolfalse在 JSON/raw 输出中用“外部不可信内容”标记包裹抓取到的文本字段
-y/--forcebool跳过破坏性命令确认
-v/--verbosebool开启详细日志
--homestring覆盖 gogcli 配置/数据/状态/缓存根目录(等价GOG_HOME

输出格式:人类可读 TSV 与 JSON

输出由 writeMapsPlace 统一生成,分两条路径:

  • JSON 模式-j):以{"place": {...}}信封输出完整Place对象,字段为idnameformatted_addressgoogle_maps_uri
  • 人类模式:按行输出字段\t值,且只打印非空字段——id恒输出,nameaddressmaps_uri仅在有值时出现;若拿到空结果则向 stderr 打印No place并正常退出。

一个典型用法是把它接入脚本取地图链接:

gog maps places search "Brandenburg Gate Berlin" -j \ | jq -r '.place.google_maps_uri'

或取坐标线索做后续处理:

gog maps places search "Eiffel Tower" -p # id ChIJd8... # name Eiffel Tower # address Avenue Gustave Eiffel, 75007 Paris, France # maps_uri https://maps.google.com/?cid=...

注意--select是“尽力而为”的字段筛选(帮助文本明确建议多数命令优先用--fields思路),而--results-only用于裁掉信封字段——对本命令这种单结果输出,两者通常不是必需的。

源码级剖析:从 Run 到 HTTP 请求

调用链

MapsPlacesSearchCmd.Run(internal/cmd/maps.go)的流程为:

  1. 拼接并 Trim 查询串,为空则返回missing query
  2. 调 newMapsPlacesClient:先经placesAPIKey取密钥,再用googleapi.NewPlacesClient构建客户端,并用环境变量GOG_PLACES_BASE_URL覆盖默认 base URL(测试与本地调试钩子);
  3. 调用client.TextSearch(ctx, query, opts),随后交给writeMapsPlace输出。

TextSearch 的接口形态

核心 HTTP 逻辑在 internal/googleapi/places.go:

  • 端点POST {baseURL}/places:searchText,默认 base URL 为https://places.googleapis.com/v1(Places API v1);
  • 请求体{"textQuery": <query>},非空时追加languageCoderegionCode
  • 鉴权与字段掩码:密钥放在X-Goog-Api-Key请求头,X-Goog-FieldMask固定为places.id,places.displayName,places.formattedAddress,places.googleMapsUri——即客户端只索取这四个字段,响应体被限制在 2 MB 内读取(io.LimitReader),HTTP 超时 10 秒(见 NewPlacesClient);
  • 结果策略:命令只返回places数组中的第一个匹配项,映射为Place{ID, Name, FormattedAddress, GoogleMapsURI};数组为空时报no places matched: <query>

也就是说,gog maps places search的语义是“取最佳匹配的单条结果”。如果你需要完整结果列表,可以走 gogcli 的通用 raw API 通道(参见 raw-api.md),或基于id接着调gog maps places details <placeId>取详情。

错误边界

doJSON 与非 2xx 状态处理(placesAPIError)会解析 Google 标准error.message/error.status,包装为places API error <code> <status>: <message>形式抛出——密钥无效、配额超限等场景在终端里会直接看到 Google 的原始错误信息,便于排障。

测试证据:如何验证这个命令的行为

单元测试 internal/cmd/maps_test.go 中的TestMapsPlacesSearch给出了一个可直接参考的端到端验证方式:

  1. 起一个httptest本地服务器,断言请求为POST /places:searchText且携带X-Goog-Api-Key: test-key
  2. 通过GOG_PLACES_API_KEY=test-keyGOG_PLACES_BASE_URL=<测试服务器地址>两个环境变量把真实客户端指向 mock;
  3. []string{"cafe"}构造查询运行命令,断言 JSON 输出包含 place id、名称与 maps URI。

这个模式也说明了GOG_PLACES_BASE_URL的设计意图:无需真实密钥即可离线复现、调试整个 Places 搜索链路。同文件的TestMapsDirectionsTestMapsGeocode对 directions/geocode 分支采用同样手法。

小结与关联命令

  • gog maps places search是 Places API v1 文本搜索的极简封装:多段 query 拼接、单条最佳结果、四字段精简输出、密钥三级配置(GOG_PLACES_API_KEYGOOGLE_PLACES_API_KEYconfig set places_api_key);
  • 拿到id后可用gog maps places details <id>(docs/commands/gog-maps-places-details.md)深入取详情,二者共用同一PlacesClientPlacesLookupOptions
  • 路线、距离矩阵、地理编码由同文件内的MapsDirectionsCmd/MapsDistanceCmd/MapsGeocodeCmd/MapsReverseGeocodeCmd提供,同样受GOG_MAPS_BASE_URL覆盖钩子与同一密钥配置约束(见 internal/cmd/maps.go);
  • 该命令为只读查询,--dry-run--readonly等安全 flag 语义与其它命令一致,可直接纳入 CI 或 Agent 工作流(配合--no-input-j-p获得稳定、可解析的输出)。

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

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

版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/9/19 5:06:50

用Python将机械设计考试题doc转化为可自测题库

简介&#xff1a;机械设计考试真题与答案解析汇总文档&#xff0c;主要面向机械类本科生、考研备考生及需要复习机械设计基础的从业者。内容覆盖齿轮接触与弯曲疲劳强度计算、螺纹连接防松、联轴器与离合器区别、链传动动载荷控制等高频考点&#xff0c;还涉及阿基米德蜗杆轴面…

作者头像 李华
网站建设 2026/9/20 5:14:11

FDAtool设计IIR滤波器:二阶节系数导出与C语言定点实现

简介&#xff1a;这份PDF文档围绕MATLAB FDAtool在IIR数字滤波器设计中的参数生成与C语言代码导出展开&#xff0c;面向数字信号处理学习者、嵌入式开发人员及需要将滤波器移植到C环境的工程师。内容从角频率与采样频率的关系、通带与阻带截止频率等基本概念切入&#xff0c;对…

作者头像 李华
网站建设 2026/9/20 5:04:07

深入解析ThreadLocal机制与内存泄漏防范

1. ThreadLocal 核心机制解析ThreadLocal 是 Java 并发编程中的重要工具类&#xff0c;它为每个线程提供了独立的变量副本&#xff0c;实现了线程间的数据隔离。但它的内部实现远比表面看起来复杂得多&#xff0c;涉及精巧的哈希策略、自动清理机制和性能优化设计。1.1 ThreadL…

作者头像 李华