gogcligog youtube subscriptions list命令完全指南:分页、输出格式与源码实现解析
【免费下载链接】gogcliGoogle Workspace in your terminal.项目地址: https://gitcode.com/GitHub_Trending/gogcl/gogcli
gog youtube subscriptions list(别名gog yt subscriptions ls)是 gogcli 中用于列出已认证用户(authenticated user)所订阅频道的只读命令。它通过 OAuth 账户身份调用 YouTube Data API v3 的subscriptions.list,并支持单页读取、全量分页拉取以及表格 / JSON 多种输出模式,是订阅管理(配合subscribe/unsubscribe)与自动化脚本中最常用的人口命令之一。读完本文,你将掌握该命令的全部参数、分页与输出机制,并能从源码与测试层面理解其实现细节。
命令定位:为什么"订阅列表"必须使用账户 OAuth
与gog yt videos list、gog yt channels list等可以用API key读取公开数据的命令不同,订阅列表属于按用户(per-user)读取:subscriptions.list必须携带mine=true参数,只有登录用户的 OAuth 身份才能查询,因此不能使用 API key 模式。
该命令在命令树中的位置(internal/cmd/youtube.go):
type YouTubeSubscriptionsCmd struct { List YouTubeSubscriptionsListCmd `cmd:"" name:"list" aliases:"ls" help:"List subscriptions for authenticated user"` Subscribe YouTubeSubscriptionsSubscribeCmd `cmd:"" name:"subscribe" help:"Subscribe to a channel"` Unsubscribe YouTubeSubscriptionsUnsubscribeCmd `cmd:"" name:"unsubscribe" help:"Unsubscribe from a channel"` }官方用法(完整命令名,圆括号内为可省略的别名):
gog youtube (yt) subscriptions (subscription) list (ls) [flags]也就是说gog yt subscriptions list、gog youtube subscription ls、gog youtube subscriptions list三种写法等价。
从源码看,命令执行的第一步是强制要求账户参数(internal/cmd/youtube.go):
account, err := requireAccount(flags) if err != nil { return err } svc, err := getYouTubeServiceForAccount(ctx, account) if err != nil { return err }随后通过getYouTubeServiceForAccount(internal/cmd/youtube_services.go)构建服务,最终经由NewYouTubeForAccount(internal/googleapi/youtube.go)以 OAuth 身份初始化 YouTube Data API v3 客户端。这里使用的是youtube服务默认的youtube.readonly只读 scope(见 internal/googleauth/service.go),无需额外申请youtube.force-ssl扩展 scope——只有订阅/播放列表的写入操作才需要。
前置配置:添加 YouTube 账户
在运行本命令前,需要先完成账户授权(详见 docs/youtube.md):
gog auth add you@gmail.com --services youtube gog yt subscriptions list --max 50 --account you@gmail.com基本用法与快速验证
最简单的调用只需指定账户:
gog yt subscriptions list --account you@gmail.com输出为表格形式,表头固定为ID CHANNEL_ID TITLE SUBSCRIBED_AT(对应源码中的fmt.Fprintln(w, "ID\tCHANNEL_ID\tTITLE\tSUBSCRIBED_AT"),见 internal/cmd/youtube.go)。每行包含:订阅 ID、被订阅频道的 Channel ID、频道标题以及订阅时间,其中 Channel ID 取自订阅的snippet.resourceId.channelId(printSubscriptionRow)。
当没有任何订阅时,命令不会报错,而是在 stderr 输出一行No subscriptions后正常退出(internal/cmd/youtube.go),方便脚本据此判断空结果。
Flags 全量参考表
本命令继承了 gogcli 的全局根级 flags,并附加了三个订阅列表专属参数--max、--page、--all。以下为完整参数表(默认值均与当前仓库生成的命令参考 gog-youtube-subscriptions-list.md 保持一致):
| Flag | Type | Default | Help |
|---|---|---|---|
--access-token | string | Use provided access token directly (bypasses stored refresh tokens; token expires in ~1h) | |
-a--account--acct | string | Account email, alias, or auto for authenticated Google API commands | |
--all--all-pages--allpages | bool | Fetch all pages | |
--client | string | OAuth client name (selects stored credentials + token bucket) | |
--color | string | auto | Color output: auto|always|never |
--disable-commands | string | Comma-separated list of disabled commands; dot paths allowed | |
-n--dry-run--dryrun--noop--preview | bool | Do not make changes; print intended actions and exit successfully | |
--enable-commands | string | Comma-separated list of enabled command prefixes; dot paths allowed (restricts CLI) | |
--enable-commands-exact | string | Comma-separated list of exact enabled commands; dot paths allowed and parent commands do not enable children | |
-y--force--assume-yes--yes | bool | Skip confirmations for destructive commands | |
--gmail-no-send | bool | false | Block Gmail send operations (agent safety) |
-h--help | kong.helpFlag | Show context-sensitive help. | |
--home | string | Override gogcli config/data/state/cache root (equivalent to GOG_HOME) | |
-j--json--machine | bool | false | Output JSON to stdout (best for scripting) |
--max--limit | int64 | 50 | Max results per page |
--no-input--non-interactive--noninteractive | bool | Never prompt; fail instead (useful for CI) | |
--page--cursor | string | Page token | |
-p--plain--tsv | bool | false | Output stable, parseable text to stdout (TSV; no colors) |
--quota-project | string | Google Cloud project to bill for API usage (sent as X-Goog-User-Project; some APIs require it with --access-token or ADC) | |
--readonly | bool | false | Block mutating API requests at runtime; auth add also requests read-only OAuth scopes |
--results-only | bool | In JSON mode, emit only the primary result (drops envelope fields like nextPageToken) | |
--select--pick--project | string | In JSON mode, select comma-separated fields (best-effort; supports dot paths). Desire path: use --fields for most commands. | |
-v--verbose | bool | Enable verbose logging | |
--version | kong.VersionFlag | Print version and exit | |
--wrap-untrusted | bool | false | In JSON/raw output, wrap fetched text fields in external untrusted-content markers |
与订阅列表强相关的三个专属参数
订阅列表命令自身的参数结构定义在 internal/cmd/youtube.go:
type YouTubeSubscriptionsListCmd struct { Max int64 `name:"max" aliases:"limit" help:"Max results per page" default:"50"` Page string `name:"page" aliases:"cursor" help:"Page token"` All bool `name:"all" aliases:"all-pages,allpages" help:"Fetch all pages"` }--max/--limit(默认 50):每页返回的最大订阅数。注意该值存在硬性校验:validateYouTubeMax要求1 <= --max <= 50,超出范围会直接提示--max must be between 1 and 50(internal/cmd/youtube.go)。这是 YouTube Data API 对maxResults的上限约束。--page/--cursor:分页游标,传入上一页返回的nextPageToken即可从指定位置继续读取。--all/--all-pages/--allpages:是否自动抓取所有页。开启后命令会循环请求直到没有下一页,无需手动拼接 token,适合订阅数量很多的频道关注者。
分页机制:单页读取 vs 全量拉取
订阅列表的核心调用链在Run方法中(internal/cmd/youtube.go):
fetch := func(pageToken string) ([]*youtube.Subscription, string, error) { resp, callErr := svc.Subscriptions.List([]string{"snippet"}). Mine(true). MaxResults(c.Max). PageToken(pageToken). Do() if callErr != nil { return nil, "", callErr } return youtubeItemsOrEmpty(resp.Items), resp.NextPageToken, nil } items, nextPageToken, err := loadPagedItems(c.Page, c.All, fetch)三个要点:
Mine(true)是订阅列表的语义核心:它告诉 YouTube API 返回"当前认证用户"的订阅,这是该命令只能走账户 OAuth 的根因。- part 固定为
snippet:命令只请求snippet字段(含标题、订阅时间、被订阅频道的 resourceId),不请求contentDetails等更重的内容,保证列表响应轻量。 - 分页逻辑由通用助手
loadPagedItems承载(internal/cmd/paged_list_helpers.go):--all开启时调用collectAllPages循环翻页并合并全部结果,此时nextPageToken为空;否则只抓取当前页并原样透传下一页 token。
翻页的实用写法
方式一:手动逐页(单页 50 条)
gog yt subscriptions list --account you@gmail.com --max 50 gog yt subscriptions list --account you@gmail.com --max 50 --page NEXT_PAGE_TOKEN方式二:全量拉取(适合脚本与数据迁移)
gog yt subscriptions list --all --account you@gmail.com --json方式三:分页批量落地到文件
for t in "" $(gog yt subscriptions list --account you@gmail.com --json | jq -r '.nextPageToken // empty'); do gog yt subscriptions list --account you@gmail.com --page "$t" --json >> subs.jsonl done输出格式:表格、TSV 与 JSON
命令根据输出标志自动切换格式(internal/cmd/youtube.go):
- 默认(终端表格):Tab 分隔的文本行,表头
ID CHANNEL_ID TITLE SUBSCRIBED_AT;若还有下一页,会在 stderr 提示--all/--all-pages以便继续翻页(printNextPageHintWithAll,见 internal/cmd/output_helpers.go)。 --json/-j:输出结构化的{"items": [...], "nextPageToken": "..."}信封结构,nextPageToken直接供--page回传使用:
gog yt subscriptions list --all --account you@gmail.com --json--plain/-p:输出稳定的 TSV(无颜色、无额外修饰),适合管道处理。--results-only:在 JSON 模式下只输出主结果数组,丢弃nextPageToken等信封字段,适合只关心数据本身的场景。--select:在 JSON 模式下按逗号分隔的字段(支持点路径)做尽力而为的字段裁剪。
此外,人类可读的进度、提示与警告信息一律输出到stderr,保证 stdout 纯净、可被程序直接消费——这是 gogcli 面向自动化设计的统一约定(参见 docs/youtube.md 的"Automation and safety"小节)。
源码与测试印证
仓库中的单元测试直接验证了本命令的关键行为。以 internal/cmd/youtube_test.go 中的TestYouTubeSubscriptionsListMine为例:
- 断言请求路径为
/youtube/v3/subscriptions,且查询参数mine=true、maxResults=2(对应--max 2); - 通过注入的
Account服务工厂断言账户参数被正确传递(me@example.com); - 校验 stdout 包含订阅 ID(
SUB123)、频道 ID(UCcool)与标题(Cool Channel); - 校验
nextPageToken(tok1)作为翻页提示出现在 stderr 中。
这从测试层面确认了:账户参数 → OAuth 服务 →mine=true请求 → 表格输出 + 翻页提示的完整链路。
结合订阅管理闭环使用
subscriptions list返回的订阅 ID(SUB123之类的值)是unsubscribe --id的直接输入;也可以直接使用列表中的 Channel ID 通过unsubscribe --channel-id退订(gogcli 会自动帮你做订阅查找)。因此一个典型的管理闭环是:
# 1. 全量导出当前订阅 gog yt subscriptions list --all --account you@gmail.com --json > subs.json # 2. 从订阅 ID 退订 gog yt subscriptions unsubscribe --id SUBSCRIPTION_ID --account you@gmail.com --force # 3. 从频道 ID 订阅新频道 gog yt subscriptions subscribe --channel-id UC_x5XG1OV2P6uZZ5FSM9Ttw --account you@gmail.com订阅与退订均支持--dry-run预演(不会发起网络请求),退订为破坏性操作,默认要求确认,自动化场景请显式组合--no-input --force。关于subscribe/unsubscribe的完整参数,可查阅 gog-youtube-subscriptions.md 及其子命令参考;YouTube 模块的整体配置(API key、scope、权限问题)参见 docs/youtube.md。命令总索引位于 docs/commands/README.md。
常见问题与注意事项
account required错误:本命令不支持 API key 模式,必须提供--account(或--acct、配置默认账户)。这是requireAccount的硬性约束。--max超出 50 被拒绝:YouTube Data API 的maxResults上限为 50,gogcli 在本地即拦截,不会发起到 Google 的无效请求。- 空订阅列表不是错误:输出
No subscriptions到 stderr 并正常退出,脚本中可通过 stderr 内容或 JSON 空数组判断。 youtubeSignupRequired:若账户尚未拥有 YouTube 频道,相关读取可能报此错误,需先在 YouTube 站点初始化频道后重试(见 docs/youtube.md)。--results-only与分页:该标志会丢弃nextPageToken,如果同时需要全量数据,请优先使用--all一次性拉完。
【免费下载链接】gogcliGoogle Workspace in your terminal.项目地址: https://gitcode.com/GitHub_Trending/gogcl/gogcli
创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考