gogcli 实战:用gog classroom submissions turn-in在终端中提交 Google Classroom 学生作业
【免费下载链接】gogcliGoogle Workspace in your terminal.项目地址: https://gitcode.com/GitHub_Trending/gogcl/gogcli
导读
gog classroom submissions turn-in是 gogcli(Google Workspace in your terminal)提供的 Classroom 作业提交命令,它把 Google Classroom API 的「学生提交作业」(turn in)操作封装为一条可复制的终端命令。本文将以该命令为骨架,讲解它的完整用法、三个必填参数的含义、全局 Flags 的实际作用,并结合 internal/cmd/classroom_submissions.go 的源码剖析其内部执行流程(账号解析 → dry-run 拦截 → Classroom API 调用 → 结构化输出),帮助你掌握在脚本、CI 与 Agent 场景下安全、可自动化地管理作业提交状态。
一、命令定位:submissions 家族中的「提交」动作
turn-in是gog classroom submissions子命令族的一员,与其并列的还有list、get、reclaim、return、grade。从源码看,ClassroomSubmissionsCmd 将这些动作统一定义在internal/cmd/classroom_submissions.go中:
list(别名ls):列出学生提交get(别名info,show):查看单个提交详情turn-in(别名turnin):提交作业(本文主角)reclaim(别名undo):回收提交(学生撤回已交作业)return(别名send):批改后返还提交grade(别名set,edit):设置草稿/正式分数
turn-in对应 Google Classroom 工作流中的「学生把作业交给老师」,在真实教学场景中通常用于:学生未能在截止前完成时由教师代为提交、测试环境自动化回归、以及脚本批量处理特定学生的提交状态。
二、完整用法与位置参数
命令的完整语法如下(其中(turnin)表示别名):
gog classroom (class) submissions (submission) turn-in (turnin) <courseId> <courseworkId> <submissionId>即三个必填位置参数依次为:
| 位置参数 | 含义 | 获取方式 |
|---|---|---|
<courseId> | 课程 ID 或课程别名 | gog classroom courses list |
<courseworkId> | 作业(CourseWork)ID | gog classroom coursework list <courseId> |
<submissionId> | 学生提交 ID | gog classroom submissions list <courseId> <courseworkId> |
一个最小可运行示例:
gog classroom submissions turn-in 123456789 987654321 555111333从源码看,这三个参数分别映射到ClassroomSubmissionsTurnInCmd结构体的三个字段(classroom_submissions.go#L180-L184),并在submissionAction中先做strings.TrimSpace去空格、再逐一校验非空,任一为空都会以usage("empty courseId")之类的错误立即返回,不会发起任何 API 请求。
2.1 别名速记
turn-in是官方命令名,同时支持别名turnin,两者等价:
gog classroom submissions turnin <courseId> <courseworkId> <submissionId>配合父级命令的别名(list→ls),你可以写出很短的命令行。
三、定位目标:先 list 再 turn-in 的完整工作流
由于submissionId是课程、作业、学生三重维度下的标识,最稳妥的取数方式是先用list命令拿到目标提交。gog classroom submissions list支持以下过滤器(见 gog-classroom-submissions-list.md):
# 查看某作业下所有「已创建但未提交」的学生作业 gog classroom submissions list <courseId> <courseworkId> --state CREATED --user student@example.com # 只看迟交的提交 gog classroom submissions list <courseId> <courseworkId> --late late其中--state接受逗号分隔的提交状态枚举:NEW,CREATED,TURNED_IN,RETURNED,RECLAIMED_BY_STUDENT;--user支持按用户 ID 或邮箱过滤;--max/--limit默认 100 条,--all/--all-pages可拉取全部分页,--fail-empty可在无结果时以退出码 3 结束(适合 CI 断言)。这些过滤器在源码中逐一映射到 Classroom List API 的参数(classroom_submissions.go#L57-L88)。
拿到submissionId之后,再执行提交操作,就构成了完整的「查找 → 提交」链路。
四、全局 Flags 详解
turn-in除了三个位置参数,还继承了 gogcli 的全局 Flags。下表完整列出(源自文档与gog schema --json生成的命令参考):
| Flag | 类型 | 默认值 | 说明 |
|---|---|---|---|
--access-token | string | 直接使用提供的 access token(绕过存储的 refresh token;token 约 1 小时过期) | |
-a--account--acct | string | 指定账号邮箱、别名或auto,用于已认证的 Google API 命令 | |
--client | string | OAuth client 名称(选择对应存储的凭据与 token 桶) | |
--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 配置/数据/状态/缓存根目录(等价于GOG_HOME) | |
-j--json--machine | bool | false | 以 JSON 输出到 stdout(最适合脚本) |
--no-input--non-interactive--noninteractive | bool | 永不提示,失败即退出(适合 CI) | |
-p--plain--tsv | bool | false | 输出稳定、可解析的纯文本(TSV,无颜色) |
--quota-project | string | 用于计费的 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 输出中为外部获取的文本字段包裹 untrusted-content 标记 |
五、源码级解析:turn-in内部到底做了什么
gog classroom submissions turn-in的执行路径非常清晰。命令的Run方法(classroom_submissions.go#L186-L188)把三个参数与动作名"turn-in"一起交给公共函数submissionAction(classroom_submissions.go#L210-L276),后者依次执行四个阶段:
5.1 参数校验
对三个 ID 逐一TrimSpace并判空,任一为空立即usage(...)报错返回。这意味着空参数不会消耗 API 配额,也不会触碰认证链路。
5.2 Dry-run 拦截
if err := dryRunExit(ctx, flags, "classroom.submissions."+action, map[string]any{ "course_id": courseID, "coursework_id": courseworkID, "submission_id": submissionID, "action": action, }); err != nil { return err }当指定-n/--dry-run时,命令会在访问 keyring 或发起任何 API 调用之前就打印出将要执行的操作(操作路径为classroom.submissions.turn-in,附带课程/作业/提交 ID)并成功退出。这是 gogcli 对破坏性操作的重要安全机制——你可以在真实执行前用 dry-run 验证参数是否正确。
5.3 账号解析与 Classroom 服务构建
requireAccount(flags)负责解析账号(支持--account/--acct/-a传入邮箱、别名或auto;ADC 模式等场景有专门的占位处理,见 internal/cmd/account.go)。随后classroomService(ctx, account)(定义于 internal/cmd/runtime_services.go#L241-L247)按需惰性初始化 Classroom API 客户端。
5.4 真正的 API 调用
case "turn-in": if _, err := svc.Courses.CourseWork.StudentSubmissions.TurnIn(courseID, courseworkID, submissionID, &classroom.TurnInStudentSubmissionRequest{}).Context(ctx).Do(); err != nil { return wrapClassroomError(err) }它调用的是 Google Classroom Go SDK 的StudentSubmissions.TurnIn方法,请求体为空的TurnInStudentSubmissionRequest。与reclaim(对应ReclaimStudentSubmissionRequest)、return(对应ReturnStudentSubmissionRequest)共用同一套submissionAction骨架,只是动作字符串不同,这体现了该模块「一次校验、多个动作复用」的设计。
所有 API 错误统一经过wrapClassroomError(internal/cmd/classroom_helpers.go#L15-L29)包装,会给出可操作的修复提示:
- 若返回
accessNotConfigured/Classroom API has not been used,提示需要先在 Google Cloud Console 启用 Classroom API; - 若返回
insufficientPermissions/insufficient authentication scopes,提示重新认证:gog auth add <account> --services classroom。
六、输出格式:终端可读与机器可解析
命令成功后,根据输出模式不同有两种结果:
默认(表格/键值文本)输出:
ok true course_id 123456789 coursework_id 987654321 submission_id 555111333 action turn-inJSON 模式(-j/--json):
{ "ok": true, "courseId": "123456789", "courseworkId": "987654321", "submissionId": "555111333", "action": "turn-in" }JSON 字段名使用 camelCase(courseId等),而纯文本键使用 snake_case(course_id),脚本解析时需注意这一差异。这两种输出都由 submissionAction 尾部按outfmt.IsJSON(ctx)分支生成。
七、实战示例与组合用法
# 1. 列出某作业的提交,找到目标学生 gog classroom submissions list 123456789 987654321 --user student@example.com # 2. 预演提交操作(不真正执行) gog classroom submissions turn-in 123456789 987654321 555111333 --dry-run # 3. 正式提交,并以 JSON 输出供脚本消费 gog classroom submissions turn-in 123456789 987654321 555111333 -j # 4. 在 CI 中组合使用:非交互、禁止提示、机器可读 gog classroom submissions turn-in 123456789 987654321 555111333 --no-input --json注意事项:
turn-in属于变更型(mutating)操作,--readonly模式下会被运行时拦截;若你的账号只有只读 OAuth 范围,调用会因权限不足而失败,需按提示用gog auth add <account> --services classroom重新授权;- 提交完成后,若需继续批改流程,可衔接
gog classroom submissions return <courseId> <courseworkId> <submissionId>返还作业,或gog classroom submissions grade <courseId> <courseworkId> <submissionId> --assigned 90打分; - 批量场景中建议先
list过滤出目标状态(如CREATED)再逐个 turn-in,避免对已提交的作业做无效操作。
八、相关命令与延伸阅读
- 父命令:gog classroom submissions(含全部 6 个子命令索引)
- 同类动作:
reclaim(回收)、return(返还)、grade(打分),它们的实现共用 submissionAction 骨架,行为一致 - 定位目标:gog classroom submissions list(含
--state/--late/--user过滤器) - 完整命令索引:Command index
- 源码入口:internal/cmd/classroom_submissions.go、internal/cmd/classroom_helpers.go、internal/cmd/runtime_services.go
【免费下载链接】gogcliGoogle Workspace in your terminal.项目地址: https://gitcode.com/GitHub_Trending/gogcl/gogcli
创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考