使用 gws CLI 创建 Google Form 反馈表单并通过 Gmail 分享的完整实战指南
【免费下载链接】cliGoogle Workspace CLI — one command-line tool for Drive, Gmail, Calendar, Sheets, Docs, Chat, Admin, and more. Dynamically built from Google Discovery Service. Includes AI agent skills.项目地址: https://gitcode.com/gh_mirrors/cli413/cli
导读
本文基于 gws(Google Workspace CLI)的 recipe 技能 recipe-create-feedback-form,讲解如何用一条命令创建 Google Forms 反馈表单、从响应中提取表单链接(responderUri),再借助gws gmail +send帮助命令把表单链接发给活动参与者或团队成员。读完本文,你将掌握「创建表单 → 提取链接 → 邮件分发」的完整闭环,并理解gws forms与gws gmail +send背后的参数语义、底层实现与安全约束,可直接复制命令用于活动反馈、会议回执、客户满意度调查等真实场景。
前置条件:技能与运行环境
该 recipe 的元数据(skills/recipe-create-feedback-form/SKILL.md)声明了两项硬性依赖:
| 依赖类型 | 名称 | 用途 |
|---|---|---|
| 可执行文件(bins) | gws | 所有命令的执行载体 |
| 技能(skills) | gws-forms、gws-gmail | 提供表单 API 与邮件发送的用法参考 |
PREREQUISITE:执行本 recipe 前需先加载
gws-forms与gws-gmail两个技能,对应文档见 gws-forms 与 gws-gmail。
gws的安装方式在项目 README 中有完整说明:推荐从 GitHub Releases 下载预编译二进制放入$PATH,也可以使用npm install -g @googleworkspace/cli、cargo install --git ... --locked或 Homebrewbrew install googleworkspace-cli安装。安装后需先完成认证:
# 交互式 OAuth 登录(本地桌面最常用) gws auth login # 或使用服务账号(服务器/CI 场景) export GOOGLE_WORKSPACE_CLI_CREDENTIALS_FILE=/path/to/service-account.json认证方式、全局 flags 与安全规则的完整参考见 gws-shared。其中与本文最相关的全局 flag 包括:
--format <json|table|yaml|csv>:输出格式,默认json--dry-run:本地校验请求而不实际调用 API--sanitize <TEMPLATE>:通过 Model Armor 对响应做内容安全过滤
第一步:创建 Google Form
创建反馈表单使用 Forms API 的forms.create方法:
gws forms forms create --json '{"info": {"title": "Event Feedback", "documentTitle": "Event Feedback Form"}}'这里gws forms forms create的语法遵循 gws-shared 中定义的统一 CLI 格式:gws <service> <resource> [sub-resource] <method> [flags],即「服务 = forms → 资源 = forms → 方法 = create」;--json携带请求体,必须用单引号包裹,避免 shell 展开内部的 JSON 双引号。
create方法的字段约束(重要)
在动手之前需要理解 gws-forms 中关于create的官方约束:
Important:Only the
form.info.titleandform.info.document_titlefields are copied to the new form. All other fields including the form description, items and settings are disallowed. To create a new form and add items, you must first callforms.createto create an empty form with a title and (optional) document title, and then callforms.updateto add the items.
即forms create只允许携带info.title(表单标题)与info.documentTitle(文档标题,对应表单在 Google Drive 中的文件名),表单的描述、题目(items)与设置字段一概不允许出现在首次创建请求中。因此上述命令就是创建表单的「最小完备」写法:
info.title:"Event Feedback"—— 表单内部标题info.documentTitle:"Event Feedback Form"—— 创建后表单文档在 Drive 中的名称
如果需要在创建后追加题目(如「整体满意度」「改进建议」等问题),必须先create空表单,再调用forms.batchUpdate添加题目,batchUpdate方法同样在 gws-forms 的 API Resources 列表中列出。查看响应结构、参数类型与默认值,可随时使用 schema 自省命令:
gws schema forms.forms.create # 查看 create 的请求/响应结构 gws forms --help # 浏览该服务下所有资源与方法第二步:从响应中提取表单链接
forms.create的响应是结构化 JSON,其中包含面向填写者的表单 URL 字段responderUri。recipe 中明确要求:
Get the form URL from the response (
responderUrifield)
典型响应片段形如:
{ "formId": "1FAIpQLSe...", "info": { "title": "Event Feedback", "documentTitle": "Event Feedback Form" }, "responderUri": "https://docs.google.com/forms/d/e/1FAIpQLSe.../viewform" }提取该字段的两种常见做法:
# 直接查看完整 JSON,人工复制 responderUri 值 gws forms forms create --json '{"info": {"title": "Event Feedback", "documentTitle": "Event Feedback Form"}}' # 借助 jq 自动抽取,便于脚本化(需要 jq) gws forms forms create --json '{"info": {"title": "Event Feedback", "documentTitle": "Event Feedback Form"}}' | jq -r '.responderUri'得到responderUri后,将其赋值给下文命令中的FORM_URL占位符。
第三步:通过 Gmail 分享表单链接
分发环节使用 Gmail 服务的+send帮助命令(helper command)。+前缀是 gws 中手写帮助命令的命名约定,与 Discovery 自动生成的 API 方法名天然区分、不会冲突(见 README 的 Helper Commands 章节)。recipe 给出的原始命令:
gws gmail +send --to attendees@company.com --subject 'Please share your feedback' --body 'Fill out the form: FORM_URL'其中FORM_URL需替换为上一步提取的responderUri。
+send完整参数参考
根据 gws-gmail-send 技能文档,+send的完整 flags 如下:
| Flag | 必填 | 默认值 | 说明 |
|---|---|---|---|
--to | ✓ | — | 收件人邮箱,多个地址用逗号分隔 |
--subject | ✓ | — | 邮件主题 |
--body | ✓ | — | 邮件正文(纯文本;配合--html则为 HTML) |
--from | — | — | 发件人地址(send-as 别名;省略时使用账号默认地址) |
--attach/-a | — | — | 附件文件路径,可重复指定多次,总量上限 25MB |
--cc | — | — | 抄送地址,逗号分隔 |
--bcc | — | — | 密送地址,逗号分隔 |
--html | — | — | 将--body视为 HTML(默认按纯文本处理) |
--dry-run | — | — | 仅展示将要发送的请求,不实际执行 |
--draft | — | — | 保存为草稿而非立即发送 |
针对反馈表单分发场景的扩展示例:
# 多个收件人 gws gmail +send --to attendees@company.com,organizer@company.com \ --subject 'Please share your feedback' \ --body 'Fill out the form: https://docs.google.com/forms/d/e/.../viewform' # HTML 正文 + 抄送 gws gmail +send --to attendees@company.com --cc manager@company.com \ --subject 'Event Feedback' \ --body '<p>Thank you for attending! Please fill out our feedback form:</p><p><a href="FORM_URL">Feedback Form</a></p>' \ --html # 先 dry-run 预览,再正式发送 gws gmail +send --to attendees@company.com --subject 'Please share your feedback' \ --body 'Fill out the form: FORM_URL' --dry-run+send的底层实现与安全防护
从源码 crates/google-workspace-cli/src/helpers/gmail/send.rs 可以确认+send的实现路径:handle_send首先调用parse_send_args解析参数(--to为空会直接抛出--to must specify at least one recipient校验错误),随后create_send_raw_message基于mail_builder::MessageBuilder组装 RFC 5322 格式的原始消息,由库自动处理 MIME 编码与 base64,最后派发到 Gmail API。该文件还内置了大量单元测试,覆盖多收件人、CC/BCC 隔离、HTML 正文、multipart 附件,以及--from/--cc中的CRLF 注入防护(test_send_crlf_injection_in_from_does_not_create_header等用例验证恶意换行无法伪造额外邮件头),因此你可以放心地把从命令输出中抓取到的 URL 直接拼进--body。
需要注意:+send属于写操作,gws-gmail-send 与 gws-shared 的安全规则均要求——执行写/删除命令前必须先与用户确认,生产脚本中建议先--dry-run校验请求。
端到端完整流程
将三步串联起来的完整可运行流程如下:
# 1. 创建表单(仅允许 info.title 与 info.documentTitle) gws forms forms create --json '{"info": {"title": "Event Feedback", "documentTitle": "Event Feedback Form"}}' # 2. 从响应中复制 responderUri 字段值,例如: # FORM_URL=https://docs.google.com/forms/d/e/1FAIpQLSe.../viewform # 3. 邮件分发(替换 FORM_URL 为实际链接) gws gmail +send --to attendees@company.com --subject 'Please share your feedback' --body 'Fill out the form: FORM_URL'进阶:给表单加题目并回收响应
由于create不允许携带题目,一个更完整的反馈闭环通常还需要:
(1)用batchUpdate添加题目:
gws forms forms batchUpdate --params '{"formId": "FORM_ID"}' \ --json '{"requests": [{"createItem": {"item": {"title": "How was the event?", "questionItem": {"question": {"required": true, "choiceQuestion": {"type": "RADIO", "options": [{"value": "Excellent"}, {"value": "Good"}, {"value": "Fair"}, {"value": "Poor"}]}}}}, "location": {"index": 0}}]}'(2)查看已收集的响应:参考 recipes.toml 中同主题的collect-form-responsesrecipe:
gws forms forms get --params '{"formId": "FORM_ID"}' # 表单详情 gws forms forms responses list --params '{"formId": "FORM_ID"}' --format table # 响应列表常见问题排查
- API 未启用(403
accessNotConfigured):GCP 项目中未开启 Forms API 或 Gmail API 时会报此错,按 README Troubleshooting 章节操作:点击报错中的enable_url在 Cloud Console 启用对应 API,等待数秒后重试;也可直接运行gws auth setup自动启用所需 API。 - zsh 下
!被解释:若在 zsh 中拼接含!的参数(如查询语法),需使用双引号包裹并转义内部引号,详见 gws-shared 的 Shell Tips。 - 测试模式 scope 超限:未验证的 OAuth 应用仅支持约 25 个 scope,登录时建议按需选择:
gws auth login -s forms,gmail,避免加载整个 recommended scope 预设。 - 发送失败但本地没问题:先
--dry-run检查请求体,再确认--to/--subject/--body三个必填参数均已提供,--to至少需要一个非空收件人。
小结
本 recipe 的精髓在于「两个服务、三条命令」:gws forms forms create负责按 Forms API 约束创建最小表单并返回responderUri,gws gmail +send负责把链接安全地分发到收件箱。配合 gws-forms 的batchUpdate/responses方法,即可在纯命令行环境下完成「创建 → 分发 → 收集」的完整反馈闭环,整个过程天然输出结构化 JSON,适合人工操作,也适合 AI Agent 编排执行。
【免费下载链接】cliGoogle Workspace CLI — one command-line tool for Drive, Gmail, Calendar, Sheets, Docs, Chat, Admin, and more. Dynamically built from Google Discovery Service. Includes AI agent skills.项目地址: https://gitcode.com/gh_mirrors/cli413/cli
创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考