beervid-app-cli 0.2.2 → 0.2.4

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (35) hide show
  1. package/README.md +45 -0
  2. package/SKILL.md +204 -376
  3. package/dist/cli.mjs +117 -151
  4. package/docs/database-schema.md +231 -0
  5. package/docs/oauth-callback.md +282 -0
  6. package/docs/retry-and-idempotency.md +295 -0
  7. package/docs/tt-poll-task.md +239 -0
  8. package/docs/tts-product-cache.md +256 -0
  9. package/example/express/README.md +58 -0
  10. package/example/express/package.json +20 -0
  11. package/example/express/server.ts +431 -0
  12. package/example/express/tsconfig.json +12 -0
  13. package/example/nextjs/.env.example +3 -0
  14. package/example/nextjs/README.md +54 -0
  15. package/example/nextjs/app/api/oauth/callback/route.ts +34 -0
  16. package/example/nextjs/app/api/oauth/url/route.ts +30 -0
  17. package/example/nextjs/app/api/products/route.ts +43 -0
  18. package/example/nextjs/app/api/publish/tt/route.ts +116 -0
  19. package/example/nextjs/app/api/publish/tts/route.ts +58 -0
  20. package/example/nextjs/app/api/status/[shareId]/route.ts +41 -0
  21. package/example/nextjs/app/layout.tsx +9 -0
  22. package/example/nextjs/app/page.tsx +80 -0
  23. package/example/nextjs/lib/beervid-client.ts +107 -0
  24. package/example/nextjs/next.config.ts +4 -0
  25. package/example/nextjs/package.json +19 -0
  26. package/example/nextjs/tsconfig.json +23 -0
  27. package/example/standard/README.md +51 -0
  28. package/example/standard/api-client.ts +181 -0
  29. package/example/standard/get-oauth-url.ts +44 -0
  30. package/example/standard/package.json +18 -0
  31. package/example/standard/query-products.ts +141 -0
  32. package/example/standard/tsconfig.json +12 -0
  33. package/example/standard/tt-publish-flow.ts +194 -0
  34. package/example/standard/tts-publish-flow.ts +246 -0
  35. package/package.json +3 -1
package/SKILL.md CHANGED
@@ -8,39 +8,56 @@ description: >
8
8
  当用户在 BEERVID 项目上下文中提到"发布视频"、"绑定账号"、"查询视频数据"、"挂车发布"、"BEERVID 第三方应用"、"BEERVID_APP_KEY"等关键词时,应触发此 skill。
9
9
  ---
10
10
 
11
- # BEERVID 第三方应用 Open API 集成开发指南
11
+ # BEERVID 第三方应用 Open API 集成指南
12
12
 
13
- 本 skill 专用于 **BEERVID 面向第三方应用开放的 Open API**,覆盖 6 大能力模块。
13
+ 本 skill **BEERVID 第三方应用 Open API** 的入口导航,重点提供:
14
14
 
15
- > **与 BEERVID 内部 API 的区别:** BEERVID 平台有两套 API 体系:
16
- >
17
- > - **第三方应用 Open API(本 skill)**:面向外部开发者,通过 `BEERVID_APP_KEY` 认证,API 路径前缀 `/api/v1/open/`,用于第三方应用集成 TikTok 视频发布、账号管理等能力。
18
- > - **BEERVID 内部 API**:BEERVID 自身产品使用的接口,认证方式和接口设计不同,不在本 skill 覆盖范围内。
19
- > 详细的请求/响应示例和错误码说明见 [`references/api-reference.md`](./references/api-reference.md)。
15
+ - 何时使用这套 API
16
+ - TT 与 TTS 两条业务流如何判断
17
+ - 关键参数如何在各接口之间传递
18
+ - 该去哪里找详细接口、接入文档、示例工程和 CLI 实现
20
19
 
21
- ## 环境配置
20
+ 不要把这里当成完整 API 手册。详细请求/响应、字段示例、错误码和长示例统一下沉到引用文档,按需读取。
22
21
 
23
- | 环境变量 | 说明 | 示例 |
24
- | ---------------------- | -------------------------------- | ------------------------- |
25
- | `BEERVID_APP_KEY` | API 密钥,放入请求头 `X-API-KEY` | `k9aqh41e...` |
26
- | `BEERVID_APP_BASE_URL` | API 基础地址 | `https://open.beervid.ai` |
22
+ ## 适用范围
27
23
 
28
- ## 认证方式
24
+ 如果问题满足以下任一条件,就应使用本 skill:
29
25
 
30
- 所有请求通过 HTTP 请求头携带密钥认证:
26
+ - 请求路径是 `/api/v1/open/` 前缀
27
+ - 认证依赖 `BEERVID_APP_KEY` 或请求头 `X-API-KEY`
28
+ - 需求涉及第三方应用身份的 TikTok 授权、上传、发布、查询
29
+ - 代码里出现 `openApiGet`、`openApiPost`、`openApiUpload`
30
+ - 需求涉及 TT 普通视频发布或 TTS 挂车视频发布
31
+
32
+ 以下内容 **不属于** 本 skill:
33
+
34
+ - BEERVID 自身产品内部 API
35
+ - 与第三方开放平台无关的业务接口
36
+ - 认证方式不是 `BEERVID_APP_KEY` 的接口体系
37
+
38
+ ## 最小背景
39
+
40
+ ### 环境变量
41
+
42
+ | 变量 | 用途 |
43
+ | ---------------------- | ------------------------------------------------------- |
44
+ | `BEERVID_APP_KEY` | Open API 密钥,请求头使用 `X-API-KEY` |
45
+ | `BEERVID_APP_BASE_URL` | Open API 基础地址,默认通常为 `https://open.beervid.ai` |
46
+
47
+ ### 认证方式
31
48
 
32
49
  | 场景 | 请求头 | 值 |
33
50
  | ------------- | ---------------- | -------------------------------- |
34
- | 常规 API 调用 | `X-API-KEY` | `BEERVID_APP_KEY` 环境变量值 |
51
+ | 常规 API 调用 | `X-API-KEY` | `BEERVID_APP_KEY` |
35
52
  | 视频上传 | `X-UPLOAD-TOKEN` | 上传凭证接口返回的 `uploadToken` |
36
53
 
37
- ## 统一响应格式
54
+ ### 统一响应格式
38
55
 
39
- 所有端点返回相同的响应信封:
56
+ 所有端点都返回统一信封:
40
57
 
41
- ```typescript
58
+ ```ts
42
59
  interface OpenApiResponse<T> {
43
- code: number; // 0 = 成功,非零 = 错误
60
+ code: number;
44
61
  message: string;
45
62
  data: T;
46
63
  error: boolean;
@@ -48,439 +65,250 @@ interface OpenApiResponse<T> {
48
65
  }
49
66
  ```
50
67
 
51
- **错误判定:** `code !== 0 || !success` 即为失败。建议统一抛出异常:
52
-
53
- ```
54
- Open API 错误 [<path>]: <message> (code: <code>)
55
- ```
56
-
57
- ## 请求函数封装建议
58
-
59
- 建议封装三个基础请求函数,共享认证和错误处理逻辑:
60
-
61
- ```typescript
62
- // GET 请求,自动拼接 query 参数
63
- async function openApiGet<T>(
64
- path: string,
65
- params?: Record<string, string>,
66
- ): Promise<OpenApiResponse<T>>;
67
-
68
- // POST 请求,JSON body
69
- async function openApiPost<T>(
70
- path: string,
71
- body?: Record<string, unknown>,
72
- ): Promise<OpenApiResponse<T>>;
73
-
74
- // 文件上传,FormData body(不设 Content-Type,让浏览器/runtime 自动处理 boundary)
75
- async function openApiUpload<T>(
76
- path: string,
77
- formData: FormData,
78
- params?: Record<string, string>,
79
- ): Promise<OpenApiResponse<T>>;
80
- ```
81
-
82
- ## 能力模块总览
83
-
84
- ### 1. 账号授权管理
85
-
86
- 处理 TikTok 账号的 OAuth 授权绑定,支持两种账号类型:
87
-
88
- | 账号类型 | 标识 | 用途 |
89
- | ---------------- | -------------------- | -------------------------- |
90
- | TT(普通账号) | `accountType: 'TT'` | 普通视频发布、视频数据查询 |
91
- | TTS(Shop 账号) | `accountType: 'TTS'` | 挂车视频发布、商品查询 |
92
-
93
- **业务流程:**
94
-
95
- ```
96
- 获取 OAuth URL → 用户跳转授权 → 回调绑定 → 拉取账号信息 → 异步同步头像
97
- ```
98
-
99
- **涉及端点:**
100
-
101
- - `GET /api/v1/open/thirdparty-auth/tt-url` — 获取 TT OAuth 链接
102
- - `GET /api/v1/open/thirdparty-auth/tts-url` — 获取 TTS OAuth 链接(返回 `crossBorderUrl`)
103
- - `POST /api/v1/open/account/info` — 查询账号详情(头像、粉丝数、accessToken 等)
104
-
105
- **安全建议:** OAuth 回调应使用 State Token 防止 CSRF,推荐 JWT 格式、短过期时间、一次性消费。
106
-
107
- ### 2. 视频上传
108
-
109
- 上传流程分两步:先获取上传凭证,再直接上传到 BEERVID 服务。
110
-
111
- **业务流程:**
112
-
113
- ```
114
- 请求上传凭证 → 获得 uploadToken + uploadUrl → 直传文件
115
- ```
116
-
117
- **涉及端点:**
118
-
119
- - `POST /api/v1/open/upload-token/generate` — 生成上传凭证
120
- - `POST /api/v1/open/file-upload` — 普通视频上传(返回 `fileUrl`)
121
- - `POST /api/v1/open/file-upload/tts-video?creatorUserOpenId=xxx` — 挂车视频上传(返回 `videoFileId`)
68
+ 失败判定统一按 `code !== 0 || !success` 处理即可。
122
69
 
123
- **上传认证:** 固定使用 `X-UPLOAD-TOKEN` 请求头,值为上传凭证接口返回的 `uploadToken`。
70
+ ## 先判断你在哪条业务流
124
71
 
125
- **客户端上传建议:** 使用 XHR(非 fetch)以支持上传进度回调(`xhr.upload.onprogress`)和 AbortSignal 取消。
72
+ ### TT 普通账号
126
73
 
127
- ### 3. 视频发布
74
+ - `accountType: 'TT'`
75
+ - 用于普通视频发布
76
+ - 可查询视频数据
77
+ - 发布后通常需要轮询状态
128
78
 
129
- 支持两种发布模式,参数和后续流程不同:
79
+ ### TTS Shop 账号
130
80
 
131
- | 模式 | publishType | 关键参数 | 返回值 | 后续 |
132
- | -------- | ----------- | ------------------------------------------------------------- | --------- | ---------- |
133
- | 普通发布 | `NORMAL` | `businessId` + `videoUrl` | `shareId` | 需轮询状态 |
134
- | 挂车发布 | `SHOPPABLE` | `creatorUserOpenId` + `fileId` + `productId` + `productTitle` | `videoId` | 立即完成 |
81
+ - `accountType: 'TTS'`
82
+ - 用于挂车视频发布和商品查询
83
+ - 发布挂车视频时依赖商品信息
84
+ - 发布后通常立即完成,不走 TT 的轮询链路
135
85
 
136
- **涉及端点:**
86
+ ## 六类核心能力
137
87
 
138
- - `POST /api/v1/open/tiktok/video/publish` — 普通视频发布
139
- - `POST /api/v1/open/tts/shoppable-video/publish` — 挂车视频发布
88
+ 只保留能力定位,详细接口说明去看引用文档:
140
89
 
141
- **挂车发布约束:** `productTitle` 最大 29 字符,超出应自动截断。
90
+ | 能力 | 作用 | 详细资料 |
91
+ | ------------ | --------------------------------------------- | -------------------------------------------------------------------------------------------------------------------------- |
92
+ | 账号授权 | 获取 TT/TTS OAuth URL、回调绑定、拉取账号详情 | [`references/api-reference.md`](./references/api-reference.md), [`docs/oauth-callback.md`](./docs/oauth-callback.md) |
93
+ | 视频上传 | 先换上传凭证,再直传文件 | [`references/api-reference.md`](./references/api-reference.md) |
94
+ | 视频发布 | TT 普通发布或 TTS 挂车发布 | [`references/api-reference.md`](./references/api-reference.md) |
95
+ | 状态轮询 | 仅 TT 普通发布需要轮询 | [`references/api-reference.md`](./references/api-reference.md), [`docs/tt-poll-task.md`](./docs/tt-poll-task.md) |
96
+ | 视频数据查询 | 查询播放、点赞、评论、分享等统计 | [`references/api-reference.md`](./references/api-reference.md) |
97
+ | 商品查询 | 为 TTS 挂车发布提供商品列表 | [`references/api-reference.md`](./references/api-reference.md), [`docs/tts-product-cache.md`](./docs/tts-product-cache.md) |
142
98
 
143
- ### 4. 发布状态轮询
99
+ ## 核心流程速记
144
100
 
145
- 仅用于 TT 普通视频,TTS 挂车视频发布后立即完成无需轮询。
101
+ ### TT 普通视频发布
146
102
 
147
- **状态流转:**
148
-
149
- ```
150
- PROCESSING_DOWNLOAD PUBLISH_COMPLETE(仅当携带非空 post_ids 时才算完成)
151
- FAILED(失败,携带 reason)
103
+ ```text
104
+ 获取 TT OAuth URL
105
+ -> 用户授权回调得到 ttAbId
106
+ -> ttAbId 作为 businessId 持久化
107
+ -> 获取上传凭证
108
+ -> 上传普通视频,拿到 fileUrl
109
+ -> 发布普通视频,拿到 shareId
110
+ -> 轮询发布状态,直到 status = PUBLISH_COMPLETE 且 post_ids 非空
111
+ -> 从 post_ids[0] 得到 videoId
112
+ -> 查询视频数据
152
113
  ```
153
114
 
154
- **涉及端点:**
155
-
156
- - `POST /api/v1/open/tiktok/video/status` — 参数 `{ businessId, shareId }`
157
-
158
- **同步策略建议:** 建议实现多重保障机制:
159
-
160
- 1. 用户主动轮询 — 用户在界面上触发状态刷新
161
- 2. 定时任务 — Cron 定期扫描未完成记录并同步状态
162
- 3. 异步队列 — 发布后投递消息,由消费者异步拉取状态
163
-
164
- ### 5. 视频数据查询
115
+ ### TTS 挂车视频发布
165
116
 
166
- 发布完成后拉取视频的播放量、点赞、评论、分享等统计数据。
167
-
168
- **涉及端点:**
169
-
170
- - `POST /api/v1/open/tiktok/video/query` 参数 `{ businessId, itemIds: string[] }`
171
-
172
- **响应格式兼容:** API 存在新旧两种字段命名,调用方需同时兼容:
173
-
174
- | 数据项 | 新版(camelCase) | 旧版(snake_case) |
175
- | -------- | ----------------- | ------------------ |
176
- | 视频 ID | `itemId` | `item_id` |
177
- | 缩略图 | `thumbnailUrl` | `thumbnail_url` |
178
- | 分享链接 | `shareUrl` | `share_url` |
179
- | 播放量 | `videoViews` | `video_views` |
180
-
181
- 兼容写法:
182
-
183
- ```typescript
184
- const list = data.videoList ?? data.videos ?? [];
185
- const video = list[0];
186
- const views = video?.videoViews ?? video?.video_views ?? 0;
117
+ ```text
118
+ 获取 TTS OAuth URL
119
+ -> 用户授权回调得到 ttsAbId
120
+ -> ttsAbId 作为 creatorUserOpenId 持久化
121
+ -> 查询商品,得到 productId + productTitle
122
+ -> 获取上传凭证
123
+ -> 上传 TTS 视频,拿到 videoFileId/fileId
124
+ -> 发布挂车视频
187
125
  ```
188
126
 
189
- **约束:** 仅拥有 TT 授权的账号才可查询视频数据。TTS-only 账号无此能力。
127
+ ## 关键参数链路
190
128
 
191
- ### 6. TTS 商品查询
129
+ 这是主文件里最值得保留的部分,因为它决定了接口如何串起来:
192
130
 
193
- 为挂车发布提供商品选择列表,支持 `shop`(店铺商品)和 `showcase`(橱窗商品)两种来源。
131
+ | 参数 | 含义 | 产出来源 |
132
+ | ------------------------ | -------------------- | -------------------------------------------------- |
133
+ | `businessId` | TT 账号业务 ID | OAuth 回调参数 `ttAbId` |
134
+ | `creatorUserOpenId` | TTS 账号 OpenId | OAuth 回调参数 `ttsAbId` |
135
+ | `accountId` | 平台账号 ID | 即 `ttAbId` 或 `ttsAbId`,用于查询账号详情 |
136
+ | `uploadToken` | 上传凭证 | `upload-token/generate` 返回 |
137
+ | `fileUrl` | 普通上传后的视频 URL | `file-upload` 返回 |
138
+ | `videoFileId` / `fileId` | TTS 视频文件 ID | `file-upload/tts-video` 返回 |
139
+ | `shareId` | TT 普通发布追踪 ID | `tiktok/video/publish` 返回 |
140
+ | `videoId` | TikTok 视频 ID | TTS 发布直接返回;TT 从状态查询 `post_ids[0]` 获取 |
141
+ | `productId` | 商品 ID | `tts/products/query` 返回的商品列表 |
142
+ | `productTitle` | 商品标题 | 同上,最多 29 字符,超出应先截断 |
143
+ | `itemIds` | 视频 ID 数组 | 来源于 `videoId`,用于查询视频数据 |
194
144
 
195
- **涉及端点:**
145
+ ```text
146
+ TT:
147
+ ttAbId -> businessId -> publish -> shareId
148
+ -> poll-status (只有 status = PUBLISH_COMPLETE 且 post_ids 非空才算完成)
149
+ -> post_ids[0] -> videoId -> query-video
196
150
 
197
- - `POST /api/v1/open/tts/products/query` — 参数 `{ creatorUserOpenId, productType, pageSize, pageToken? }`
198
-
199
- **分页机制:** 使用 Base64 编码的游标,结构为 `{ shopToken, showcaseToken }`。建议同时查询两种 `productType` 并按 `id` 去重合并。
200
-
201
- **图片格式特殊处理:** 商品图片返回格式为 `{height=200, url=https://xxx.jpg, width=200}`,需正则提取:
202
-
203
- ```typescript
204
- const match = imageStr.match(/url=([^,}]+)/);
205
- const url = match?.[1] ?? "";
151
+ TTS:
152
+ ttsAbId -> creatorUserOpenId -> query-products -> productId/productTitle
153
+ creatorUserOpenId -> upload-tts-video -> fileId -> shoppable-publish -> videoId
206
154
  ```
207
155
 
208
- ## 错误处理最佳实践
209
-
210
- 使用 BEERVID API 时推荐以下错误处理策略:
211
-
212
- | 策略 | 场景 | 做法 |
213
- | ------------ | ------------------------ | ------------------------------------------- |
214
- | 参数校验前置 | 所有 API 调用前 | 缺少必填项立即返回错误,不发起请求 |
215
- | 权限检查 | 需要特定授权的操作 | 调用前校验账号类型和授权状态 |
216
- | 统一异常捕获 | API 调用层 | 捕获 Open API 错误并转为业务友好的错误信息 |
217
- | 部分成功处理 | API 成功但本地持久化失败 | 返回成功但标记 `dbSaved: false` |
218
- | 单条隔离 | 批量/定时任务 | 单条失败不中断整体流程 |
219
- | 静默异步 | 次要操作(如头像同步) | 失败不阻塞主流程 |
220
- | 队列重试 | 异步消费者 | 限制最大重试次数(建议 3 次),设定重试间隔 |
221
-
222
- ## 关键参数来源说明
156
+ ## 实现时优先遵循的约束
223
157
 
224
- 各接口间通过参数串联,理解每个参数的产出来源是正确集成的前提:
158
+ ### API 封装
225
159
 
226
- | 参数 | 含义 | 产出来源 |
227
- | ------------------------ | ---------------- | ----------------------------------------------------------------------------- |
228
- | `businessId` | TT 账号业务 ID | OAuth 授权回调直接返回(回调参数 `ttAbId`),持久化后作为所有 TT 操作的入参 |
229
- | `creatorUserOpenId` | TTS 账号 OpenId | OAuth 授权回调直接返回(回调参数 `ttsAbId`),持久化后作为所有 TTS 操作的入参 |
230
- | `accountId` | 平台账号 ID | 即 `ttAbId` 或 `ttsAbId`,传入 `account/info` 接口获取账号详情 |
231
- | `uploadToken` | 上传凭证 | 调用 `POST /api/v1/open/upload-token/generate` 返回 |
232
- | `fileUrl` | 上传后的视频 URL | 普通上传 `POST /api/v1/open/file-upload` 返回 |
233
- | `videoFileId` / `fileId` | TTS 视频文件 ID | TTS 上传 `POST /api/v1/open/file-upload/tts-video` 返回 |
234
- | `shareId` | 普通发布追踪 ID | 普通发布 `POST /api/v1/open/tiktok/video/publish` 返回,用于轮询发布状态 |
235
- | `videoId` | TikTok 视频 ID | 挂车发布直接返回;普通发布从状态轮询结果的 `post_ids[0]` 中获取 |
236
- | `productId` | 商品 ID | 查询商品 `POST /api/v1/open/tts/products/query` 返回的商品列表中的 `id` 字段 |
237
- | `productTitle` | 商品标题 | 同上,商品列表中的 `title` 字段(最多 29 字符) |
238
- | `itemIds` | 视频 ID 数组 | 来自 `videoId`,用于查询视频统计数据 |
160
+ 建议统一封装三个基础请求函数:
239
161
 
240
- **参数传递链路图:**
162
+ - `openApiGet`
163
+ - `openApiPost`
164
+ - `openApiUpload`
241
165
 
242
- ```
243
- OAuth 回调
244
- ├─ ttAbId → businessId ──────────→ publish → shareId → poll-status → post_ids[0] → videoId → query
245
- └─ ttsAbId → creatorUserOpenId ──→ upload/tts-video → fileId ──→ shoppable/publish → videoId
246
- └──→ products/query → productId + productTitle ──→ shoppable/publish
247
- ```
248
-
249
- ## 完整业务流程参考
166
+ 这三个函数应共享:
250
167
 
251
- ### 普通视频发布(TT)
252
-
253
- **前置条件:** 需要 `businessId`。如已持久化则直接使用,否则先完成授权流程获取。
254
-
255
- ```
256
- [无 businessId 时] 授权获取 businessId:
257
- 1. 获取 OAuth URL GET /api/v1/open/thirdparty-auth/tt-url
258
- 2. 用户跳转授权 回调返回 ttAbId → 即 businessId
259
- 3. 获取账号详情 POST /api/v1/open/account/info → 持久化账号信息
260
-
261
- [有 businessId 后] 发布流程:
262
- 1. 获取上传凭证 POST /api/v1/open/upload-token/generate
263
- 2. 上传视频文件 POST /api/v1/open/file-upload(返回 fileUrl)
264
- 3. 发布视频 POST /api/v1/open/tiktok/video/publish(返回 shareId)
265
- 4. 轮询发布状态 POST /api/v1/open/tiktok/video/status(直到 PUBLISH_COMPLETE 且返回非空 post_ids)
266
- 5. 拉取视频数据 POST /api/v1/open/tiktok/video/query(获取播放量等)
267
- ```
168
+ - 基础地址拼接
169
+ - `X-API-KEY` 注入
170
+ - 统一响应解包
171
+ - 错误抛出格式
268
172
 
269
- ### 挂车视频发布(TTS)
173
+ ### 常见业务约束
270
174
 
271
- **前置条件:** 需要 `creatorUserOpenId`。如已持久化则直接使用,否则先完成授权流程获取。
175
+ - TT 普通视频发布后需要轮询;只有 `PUBLISH_COMPLETE` 且 `post_ids` 非空才算成功完成;TTS 挂车视频通常不需要
176
+ - 仅 TT 授权账号可查询视频数据
177
+ - `productTitle` 最多 29 字符,超出时应提前截断
178
+ - 商品图片字段可能是特殊字符串格式,解析细节见 [`docs/tts-product-cache.md`](./docs/tts-product-cache.md)
179
+ - 视频查询接口可能同时返回 camelCase 与 snake_case 字段,兼容细节见 [`references/api-reference.md`](./references/api-reference.md)
272
180
 
273
- ```
274
- [无 creatorUserOpenId 时] 授权获取 creatorUserOpenId:
275
- 1. 获取 OAuth URL GET /api/v1/open/thirdparty-auth/tts-url
276
- 2. 用户跳转授权 回调返回 ttsAbId → 即 creatorUserOpenId
277
- 3. 获取账号详情 POST /api/v1/open/account/info → 持久化账号信息
278
-
279
- [有 creatorUserOpenId 后] 发布流程:
280
- 1. 查询商品列表 POST /api/v1/open/tts/products/query(用户选择商品)
281
- 2. 获取上传凭证 POST /api/v1/open/upload-token/generate
282
- 3. 上传视频文件 POST /api/v1/open/file-upload/tts-video(返回 videoFileId)
283
- 4. 发布挂车视频 POST /api/v1/open/tts/shoppable-video/publish(立即完成)
284
- ```
181
+ ### 上传侧建议
285
182
 
286
- 详细的请求/响应示例见 [`references/api-reference.md`](./references/api-reference.md)
183
+ - 上传前先换取 `uploadToken`
184
+ - 上传请求头使用 `X-UPLOAD-TOKEN`
185
+ - 如需上传进度与取消能力,优先用 XHR 而非裸 `fetch`
287
186
 
288
- ## CLI 命令
187
+ ## CLI 使用原则
289
188
 
290
- 统一使用已安装的 `beervid` 命令;
189
+ 本仓库已经提供 `beervid` CLI;如果用户要“直接操作 API”或“快速验证链路”,优先复用 CLI 能力,不必手写一遍完整流程。
291
190
 
292
- **前置条件:** 设置 APP_KEY 后即可使用(任选一种方式):
191
+ ### CLI 前置
293
192
 
294
193
  ```bash
295
- # 方式一:通过 config 命令持久化(推荐,设置一次永久生效)
296
194
  beervid config --app-key "your-api-key"
297
-
298
- # 方式二:通过环境变量(优先级高于 config)
299
- export BEERVID_APP_KEY="your-api-key"
300
- export BEERVID_APP_BASE_URL="https://open.beervid.ai" # 可选,有默认值
195
+ export BEERVID_APP_BASE_URL="https://open.beervid.ai"
301
196
  ```
302
197
 
303
- > **注意:** 当参数值以 `-` 开头时(如 `businessId`、`creatorUserOpenId`),必须使用 `=` 连接选项名和值,否则 CLI 会将其误判为选项标志:
304
- >
305
- > ```bash
306
- > # 正确
307
- > beervid publish-tt-flow --business-id=-0006dmtMOdKRY...
308
- >
309
- > # 错误 会报 "Unknown option `-0`"
310
- > beervid publish-tt-flow --business-id -0006dmtMOdKRY...
311
- > ```
312
-
313
- ### 命令一览
314
-
315
- | 命令 | 功能 | 核心参数 |
316
- | -------------------------- | ------------------------------ | --------------------------------------------------- |
317
- | `beervid config` | 设置/查看全局配置 | `--app-key <key> [--base-url <url>] [--show]` |
318
- | `beervid get-oauth-url` | 获取 OAuth 授权链接 | `--type tt\|tts` |
319
- | `beervid get-account-info` | 查询账号信息 | `--type TT\|TTS --account-id <id>` |
320
- | `beervid upload` | 上传视频(支持本地文件和 URL) | `--file <路径或URL> [--type tts --creator-id <id>]` |
321
- | `beervid publish` | 发布视频(普通/挂车) | `--type normal\|shoppable` + 对应参数 |
322
- | `beervid poll-status` | 轮询发布状态 | `--business-id <id> --share-id <id>` |
323
- | `beervid query-video` | 查询视频数据 | `--business-id <id> --item-ids <id1,id2>` |
324
- | `beervid query-products` | 查询 TTS 商品 | `--creator-id <id>` |
325
- | `beervid publish-tt-flow` | TT 完整发布流程 | `--business-id <id> --file <路径或URL>` |
326
- | `beervid publish-tts-flow` | TTS 完整发布流程 | `--creator-id <id> --file <路径或URL>` |
198
+ ### CLI 命令一览
199
+
200
+ | 命令 | 功能 | 常用参数 |
201
+ | -------------------------- | --------------------- | ---------------------------------------------------------------------------- | ------------------------- |
202
+ | `beervid config` | 设置或查看全局配置 | `--app-key`, `--base-url`, `--show` |
203
+ | `beervid get-oauth-url` | 获取 OAuth 授权链接 | `--type tt | tts` |
204
+ | `beervid get-account-info` | 查询账号信息 | `--type TT | TTS`, `--account-id` |
205
+ | `beervid upload` | 上传视频 | `--file`, `--type tts`, `--creator-id`, `--token` |
206
+ | `beervid publish` | 发布普通或挂车视频 | `--type normal | shoppable` 加对应业务参数 |
207
+ | `beervid poll-status` | 轮询 TT 发布状态 | `--business-id`, `--share-id`, `--interval`, `--max-polls` |
208
+ | `beervid query-video` | 查询视频数据 | `--business-id`, `--item-ids` |
209
+ | `beervid query-products` | 查询 TTS 商品 | `--creator-id`, `--product-type`, `--cursor` |
210
+ | `beervid publish-tt-flow` | 执行 TT 完整发布流程 | `--business-id`, `--file`, `--caption` |
211
+ | `beervid publish-tts-flow` | 执行 TTS 完整发布流程 | `--creator-id`, `--file`, `--interactive`, `--product-id`, `--product-title` |
327
212
 
328
213
  ### 使用示例
329
214
 
330
- #### 设置全局配置
215
+ 最常用的最小示例如下:
331
216
 
332
217
  ```bash
333
- # 设置 APP_KEY(持久化到 ~/.beervid/config.json)
334
- beervid config --app-key k9aqh41e...
335
-
336
- # 设置自定义 API 地址
337
- beervid config --base-url https://custom.api.com
338
-
339
- # 查看当前配置(APP_KEY 脱敏显示)
340
- beervid config --show
341
- ```
342
-
343
- #### 获取授权链接
218
+ # 设置 APP Key
219
+ beervid config --app-key "your-api-key"
344
220
 
345
- ```bash
221
+ # 获取授权链接
346
222
  beervid get-oauth-url --type tt
347
223
  beervid get-oauth-url --type tts
348
- ```
349
224
 
350
- #### 查询账号信息
351
-
352
- ```bash
225
+ # 查询账号信息
353
226
  beervid get-account-info --type TT --account-id 7281234567890
354
- ```
355
-
356
- #### 上传视频
357
-
358
- ```bash
359
- # 本地文件上传
360
- beervid upload --file ./my-video.mp4
361
227
 
362
- # 远程 URL 上传(自动下载后上传)
228
+ # 上传普通视频(--file 同时支持本地文件路径和 URL 地址)
229
+ beervid upload --file ./video.mp4
363
230
  beervid upload --file https://example.com/video.mp4
364
231
 
365
- # TTS 挂车上传
366
- beervid upload --file ./video.mp4 --type tts --creator-id open_user_abc
367
-
368
- # 使用已有的上传凭证(跳过自动获取)
369
- beervid upload --file ./video.mp4 --token upt.xxx
370
- ```
371
-
372
- #### 发布视频
232
+ # 上传 TTS 视频(--file 同时支持本地文件路径和 URL 地址)
233
+ beervid upload --file ./video.mp4 --type tts --creator-id=open_user_abc
373
234
 
374
- ```bash
375
- # 普通发布
376
- beervid publish --type normal \
377
- --business-id biz_12345 \
378
- --video-url https://cdn.beervid.ai/uploads/xxx.mp4 \
379
- --caption "Amazing video! #viral"
235
+ # 普通发布(--video-url 需要传可访问的视频 URL)
236
+ beervid publish --type normal --business-id=biz_12345 --video-url https://cdn.beervid.ai/uploads/xxx.mp4 --caption "My video"
380
237
 
381
238
  # 挂车发布
382
- beervid publish --type shoppable \
383
- --creator-id open_user_abc \
384
- --file-id vf_abc123 \
385
- --product-id prod_789 \
386
- --product-title "Premium Widget" \
387
- --caption "Product review"
388
- ```
239
+ beervid publish --type shoppable --creator-id=open_user_abc --file-id vf_abc123 --product-id prod_789 --product-title "Premium Widget" --caption "Product review"
389
240
 
390
- #### 轮询发布状态
241
+ # 轮询状态
242
+ beervid poll-status --business-id=biz_12345 --share-id share_abc123
391
243
 
392
- ```bash
393
- # 默认每 5 秒轮询一次,最多 60 次
394
- beervid poll-status --business-id biz_12345 --share-id share_abc123
395
-
396
- # 自定义间隔和次数
397
- beervid poll-status --business-id biz_12345 --share-id share_abc123 --interval 5 --max-polls 30
398
- ```
244
+ # 查询视频数据
245
+ beervid query-video --business-id=biz_12345 --item-ids 7123456789012345678
399
246
 
400
- #### 查询视频数据
247
+ # 查询商品
248
+ beervid query-products --creator-id=open_user_abc
401
249
 
402
- ```bash
403
- # 单个视频
404
- beervid query-video --business-id biz_12345 --item-ids 7123456789012345678
250
+ # TT 一键完整流程(--file 同时支持本地文件路径和 URL 地址)
251
+ beervid publish-tt-flow --business-id=biz_12345 --file ./video.mp4 --caption "My video"
252
+ beervid publish-tt-flow --business-id=biz_12345 --file https://example.com/video.mp4 --caption "My video"
405
253
 
406
- # 多个视频
407
- beervid query-video --business-id biz_12345 --item-ids 7123456789012345678,7123456789012345679
254
+ # TTS 一键完整流程(--file 同时支持本地文件路径和 URL 地址)
255
+ beervid publish-tts-flow --creator-id=open_user_abc --file ./video.mp4
256
+ beervid publish-tts-flow --creator-id=open_user_abc --file https://example.com/video.mp4
408
257
  ```
409
258
 
410
- #### 查询商品列表
259
+ ### CLI 特别注意
411
260
 
412
- ```bash
413
- # 全部商品(shop + showcase 合并去重)
414
- beervid query-products --creator-id open_user_abc
261
+ 当参数值本身以 `-` 开头时,必须写成 `--option=value`,否则 CLI 会把值误判为新的选项。
415
262
 
416
- # 仅店铺商品
417
- beervid query-products --creator-id open_user_abc --product-type shop
263
+ ## 读哪份文档
418
264
 
419
- # 分页查询
420
- beervid query-products --creator-id open_user_abc --cursor eyJ...
421
- ```
265
+ ### 接口细节
422
266
 
423
- #### TT 完整发布流程
267
+ 当你需要以下内容时,直接读取 [`references/api-reference.md`](./references/api-reference.md):
424
268
 
425
- ```bash
426
- # 上传 -> 发布 -> 轮询 -> 查询视频数据
427
- beervid publish-tt-flow \
428
- --business-id biz_12345 \
429
- --file ./video.mp4 \
430
- --caption "Amazing video! #viral"
431
- ```
269
+ - 具体端点路径
270
+ - 请求参数
271
+ - 响应字段
272
+ - 错误码
273
+ - 新旧字段兼容方式
432
274
 
433
- #### TTS 完整发布流程
275
+ ### 接入设计
434
276
 
435
- ```bash
436
- # 自动选择销量最高商品
437
- beervid publish-tts-flow \
438
- --creator-id open_user_abc \
439
- --file ./video.mp4
440
-
441
- # 交互式选择商品
442
- beervid publish-tts-flow \
443
- --creator-id open_user_abc \
444
- --file ./video.mp4 \
445
- --interactive
446
-
447
- # 手动指定商品
448
- beervid publish-tts-flow \
449
- --creator-id open_user_abc \
450
- --file ./video.mp4 \
451
- --product-id prod_789 \
452
- --product-title "Premium Widget"
453
- ```
277
+ 按场景读取:
454
278
 
455
- ### 完整业务流程示例(CLI 串联)
279
+ - OAuth 回调与 State Token:[`docs/oauth-callback.md`](./docs/oauth-callback.md)
280
+ - 数据表设计:[`docs/database-schema.md`](./docs/database-schema.md)
281
+ - TT 轮询任务:[`docs/tt-poll-task.md`](./docs/tt-poll-task.md)
282
+ - TTS 商品缓存:[`docs/tts-product-cache.md`](./docs/tts-product-cache.md)
283
+ - 重试与幂等:[`docs/retry-and-idempotency.md`](./docs/retry-and-idempotency.md)
456
284
 
457
- **普通视频从上传到数据查询:**
285
+ ### 示例工程
458
286
 
459
- ```bash
460
- # 1. 上传视频
461
- beervid upload --file ./video.mp4
462
- # 输出: { "fileUrl": "https://cdn.beervid.ai/uploads/xxx.mp4", ... }
287
+ 当用户需要“可运行参考实现”时,按技术栈读取:
463
288
 
464
- # 2. 发布视频
465
- beervid publish --type normal --business-id biz_123 --video-url https://cdn.beervid.ai/uploads/xxx.mp4 --caption "My video"
466
- # 输出: { "shareId": "share_abc", ... }
289
+ - 纯脚本示例:[`example/standard/README.md`](./example/standard/README.md)
290
+ - Express 示例:[`example/express/README.md`](./example/express/README.md)
291
+ - Next.js API Route 示例:[`example/nextjs/README.md`](./example/nextjs/README.md)
467
292
 
468
- # 3. 轮询状态直到完成
469
- beervid poll-status --business-id biz_123 --share-id share_abc
470
- # 输出: 视频 ID: 7123456789012345678
293
+ ## 推荐工作方式
471
294
 
472
- # 4. 查询数据
473
- beervid query-video --business-id biz_123 --item-ids 7123456789012345678
474
- ```
295
+ 处理相关需求时,优先按这个顺序行动:
475
296
 
476
- **TT 一键完整流程:**
297
+ 1. 先判断是 TT 还是 TTS,是 API 集成还是 CLI 使用。
298
+ 2. 再确认当前缺的是哪一段链路:授权、上传、发布、轮询、查询、商品。
299
+ 3. 主流程和参数链路在本文件中快速定位。
300
+ 4. 需要具体字段、示例或错误码时,再读取对应 `references/` 或 `docs/`。
301
+ 5. 需要代码落地时,优先复用现有 `src/commands/`、`src/client/`、`src/workflows/` 和 `example/`。
477
302
 
478
- ```bash
479
- beervid publish-tt-flow --business-id biz_123 --file ./video.mp4 --caption "My video"
480
- ```
303
+ ## 不要在主文件重复维护的内容
481
304
 
482
- **TTS 一键完整流程:**
305
+ 以下内容不应继续扩写回 `SKILL.md`,避免再次膨胀:
483
306
 
484
- ```bash
485
- beervid publish-tts-flow --creator-id open_user_abc --file ./video.mp4
486
- ```
307
+ - 单个端点的完整请求/响应示例
308
+ - CLI 的长命令样例清单
309
+ - 各种错误码详表
310
+ - 数据库字段大表
311
+ - OAuth 安全细节展开说明
312
+ - 轮询/缓存/重试的长篇策略说明
313
+
314
+ 这些内容已经分别存在于 `references/`、`docs/`、`example/` 中,应按需引用,不要复制。