gogcli `gog chat dm send`:在终端发送 Google Chat 私信的完整实战指南
2026/9/16 21:49:30 网站建设 项目流程

gogcligog chat dm send:在终端发送 Google Chat 私信的完整实战指南

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

本篇指南围绕 gogcli 的gog chat dm send命令展开,讲解如何在终端(脚本、CI 或 Agent 工作流中)向指定 Google Workspace 用户发送 Google Chat 私信。读完本文,你将掌握该命令的参数与别名、--thread回复线程的用法、dry-run 预览与 JSON 输出的行为细节,并能对照仓库源码理解它“先建 DM space、再发 Message”的完整调用链与安全边界。

命令概览

gog chat dm send是 gog chat 命令族 中用于发送私信(Direct Message)的子命令。其用法如下(createpostsend的等价别名,在内部实现中通过 chat_dm.go 的aliases:"create,post"声明):

gog chat dm send (create,post) <email> [flags]
  • 位置参数<email>:收件人邮箱(必填);
  • --text:消息文本(必填);
  • --thread:可选,指定要回复的线程。

它与同级子命令 gog chat dm space(查找或创建 DM space)共享同一套底层逻辑——send实际上会先执行space的 setup 动作,再投递消息。命令文档页由gog schema --json自动生成,修改后应通过make docs-commands重新生成(参见 生成文档页 顶部说明)。

内部实现:从邮箱到消息投递的完整调用链

结合 internal/cmd/chat_dm.go 中的ChatDMSendCmd.Run实现,一次gog chat dm send的执行顺序如下:

  1. 参数校验(先于一切副作用)

    • <email>去除首尾空白后必须非空,并经过validatePlainEmail校验——必须是纯邮箱字符串,形如Tester <x@example.com>的“姓名 + 邮箱”写法会被直接拒绝;
    • --text去除空白后必须非空;
    • --thread若提供,会先按spaces/_/threads/...模板预校验格式(chat_dm.go),非法线程资源以 usage 错误(退出码 2)提前失败。
    • 测试用例 TestExecute_ChatDM_InvalidEmailFailsBeforeDryRun 明确验证了这一点:非法邮箱、"Tester <x@example.com>"格式、以及带多余分段的--thread值,都会在创建任何 chat 服务之前就报错,测试断言工厂函数不应被调用。
  2. Dry-run 提前退出:校验通过后调用dryRunExit(实现见 internal/cmd/dryrun.go)。当带有-n/--dry-run等 flag 时,命令打印计划操作chat.dm.send及其请求体(emailtextthread)后以退出码 0 结束,不触碰认证密钥环、不发起任何 API 调用

  3. 账号解析与 Workspace 限制requireAccount(flags)-a/--account(邮箱、别名或auto)解析当前认证账号;随后requireWorkspaceAccount强制要求账号为 Google Workspace 账号——消费级 Gmail(@gmail.com)账号会被拒绝,chat_helpers.go 中的错误信息为 “chat requires a Google Workspace account (non-gmail.com)”。

  4. 获取 Chat API 客户端chatService(见 runtime_services.go)从运行时服务注册表中取出按账号绑定的*chat.Service,认证所需 scope 包括chat.spaceschat.messages(见 internal/googleauth/service.go)。

  5. setup DM spacesetupDMSpace(chat_dm.go)调用Spaces.Setup,请求体为SpaceType: "DIRECT_MESSAGE"的 space 加上一个HUMAN类型、Nameusers/<email>的 membership。邮箱会经normalizeUser(chat_helpers.go)规范化为users/前缀资源名。从源码结构看,发送前无条件执行一次 setup,依赖 Google Chatspaces.setup的幂等性来复用已存在的 DM space,并以此拿到 space 资源名作为下一步的发送目标。

  6. 构建并发送消息:以&chat.Message{Text: text}构造消息;若提供了--thread,此时用真实 space 名重新规范化线程资源名(normalizeThread(space.Name, thread),见 chat_dm.go),并通过Spaces.Messages.Create(space, message)发送。附带线程时还会设置MessageReplyOption("REPLY_MESSAGE_FALLBACK_TO_NEW_THREAD")——即线程已失效时回退为新建线程,而不是直接报错。

  7. 结果输出

    • JSON 模式(-j):输出{"message": <完整消息对象>},便于脚本解析;
    • 文本模式:逐行输出resource\t<spaces/.../messages/...>thread\t<spaces/.../threads/...>(若响应中存在),见 chat_dm.go。

--thread参数的两种合法写法

normalizeThread(chat_helpers.go)对线程资源做了双轨校验,--thread可以传:

  • 完整资源名spaces/<spaceID>/threads/<threadID>——必须恰好 4 段且结构正确,否则报invalid thread resource
  • 裸线程 ID:可以只传线程 ID(允许带threads/前缀),命令会将其拼接到 setup 得到的 DM space 之下。

注意裸 ID 中不能再包含/,否则视为非法。这一行为同样被 TestExecute_ChatDM_InvalidEmailFailsBeforeDryRun 中的--thread "spaces/AAA/threads/t1/extra"(5 段)用例覆盖。

常用实战示例

以下命令均可直接复制运行(前提:已用gog auth add添加了一个 Workspace 账号):

# 最基本的私信 gog chat dm send user@example.com --text "ping" # 使用 send 的别名 post gog chat dm post user@example.com --text "hello" # 回复某个已有线程(完整资源名或裸线程 ID 均可) gog chat dm send user@example.com --text "follow up" \ --thread "spaces/<spaceID>/threads/<threadID>" # dry-run:不真正发送,打印意图后以 0 退出 gog chat dm send user@example.com --text "ping" --dry-run # JSON 输出,便于脚本处理 gog chat dm send user@example.com --text "ping" --json # 指定账号(多账号环境)与只读保护 gog chat dm send user@example.com --text "ping" -a work@company.com gog chat dm send user@example.com --text "ping" --readonly # 会拦截该变更类请求

--dry-run的 JSON 输出形态为{"dry_run": true, "op": "chat.dm.send", "request": {"email": ..., "text": ..., "thread": ...}},可直接接入自动化管道的预检环节。

完整 Flags 参考

下表完整继承自 命令参考页(由gog schema --json生成)。除命令专属的--text--thread外,其余为全局 flag,在gog所有子命令上语义一致:

FlagTypeDefaultHelp
--access-tokenstringUse provided access token directly (bypasses stored refresh tokens; token expires in ~1h)
-a
--account
--acct
stringAccount email, alias, or auto for authenticated Google API commands
--clientstringOAuth client name (selects stored credentials + token bucket)
--colorstringautoColor output: auto|always|never
--disable-commandsstringComma-separated list of disabled commands; dot paths allowed
-n
--dry-run
--dryrun
--noop
--preview
boolDo 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
-y
--force
--assume-yes
--yes
boolSkip confirmations for destructive commands
--gmail-no-sendboolfalseBlock Gmail send operations (agent safety)
-h
--help
kong.helpFlagShow context-sensitive help.
--homestringOverride gogcli config/data/state/cache root (equivalent to GOG_HOME)
-j
--json
--machine
boolfalseOutput JSON to stdout (best for scripting)
--no-input
--non-interactive
--noninteractive
boolNever prompt; fail instead (useful for CI)
-p
--plain
--tsv
boolfalseOutput 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
--project
stringIn JSON mode, select comma-separated fields (best-effort; supports dot paths). Desire path: use --fields for most commands.
--textstringMessage text (required)
--threadstringReply to thread (spaces/.../threads/...)
-v
--verbose
boolEnable verbose logging
--versionkong.VersionFlagPrint version and exit
--wrap-untrustedboolfalseIn JSON/raw output, wrap fetched text fields in external untrusted-content markers

对本命令而言,几个值得重点关注的 flag:

  • -n/--dry-run:在参数校验之后、任何认证与 API 调用之前生效,适合把“发消息”这种变更操作纳入可回放的脚本;
  • -j/--json--results-only:JSON 模式下响应外层包裹message字段;加--results-only可只保留主结果、丢弃nextPageToken之类的外层字段;--select支持点路径字段裁剪(尽力而为);
  • --readonly:运行时拦截变更类 API 请求——dm send属于变更操作,开启后会失败,这为 Agent 场景提供了“只读模式”的硬边界(配套的 Agent 安全策略见 safety-profiles);
  • --no-input:永不交互式提示,遇到需要确认的场景直接失败,适合 CI;
  • --wrap-untrusted:在 JSON 输出中为取回的文本字段包裹外部不可信内容标记,供下游 LLM/Agent 消费时隔离提示注入风险(本项目中 chat 线程列表的测试 验证了该包裹行为)。

行为边界与测试佐证

  • Workspace 账号是硬前提:消费级 Gmail 账号执行chat dm send会直接得到 usage 错误,而不是走到 API 层(requireWorkspaceAccount,chat_helpers.go)。
  • 端到端行为有测试覆盖:TestExecute_ChatDMSend_JSON 用 fake Chat 服务端完整演练了真实请求序列——先POST /spaces:setup拿到spaces/dm1,再POST /spaces/dm1/messages断言请求体中的text等于ping,最后校验 stdout 包含spaces/dm1/messages/m1。这与前文“先 setup 再 Create”的调用链一一对应;TestExecute_ChatDMSpace_JSON 则断言了 setup 请求体中 membership 的name被规范化为users/user@example.com
  • 错误即退出码 2 的 usage 错误:缺--text、非法邮箱等属于使用错误,以ExitError{Code: 2}返回,脚本可通过退出码区分“用法错误”与“API 错误”。

小结

gog chat dm send用一条命令封装了 Google Chat 私信的两个 API 步骤(spaces.setup+spaces.messages.create),并通过参数前置校验、Workspace 账号限制、dry-run 通道和--readonly硬边界,使其既能用于人工交互,也能安全地嵌入脚本与 Agent 工作流。更多 chat 相关能力(空间管理、消息列表/搜索、表情回应)可参考 docs/commands 下 gog-chat.md 及其子页面,命令总入口见 命令索引。

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

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

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

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

立即咨询