beervid-app-cli 0.2.6 → 0.2.7
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.
- package/README.md +19 -0
- package/dist/cli.d.ts +2 -0
- package/dist/cli.mjs +165 -73
- package/dist/index.d.ts +255 -0
- package/dist/index.mjs +1 -0
- package/package.json +11 -2
- package/skills/beervid-app-cli/FAQ.md +214 -0
- package/skills/beervid-app-cli/QUICKSTART.md +206 -0
- package/skills/beervid-app-cli/SKILL.md +52 -9
- package/skills/beervid-app-cli/docs/database-schema.md +12 -2
- package/skills/beervid-app-cli/docs/oauth-callback.md +70 -21
- package/skills/beervid-app-cli/docs/performance-and-limits.md +153 -0
- package/skills/beervid-app-cli/docs/security-best-practices.md +132 -0
- package/skills/beervid-app-cli/docs/testing-guide.md +689 -0
- package/skills/beervid-app-cli/docs/troubleshooting.md +468 -0
- package/skills/beervid-app-cli/example/express/README.md +6 -0
- package/skills/beervid-app-cli/example/express/server.ts +23 -5
- package/skills/beervid-app-cli/example/nextjs/README.md +6 -0
- package/skills/beervid-app-cli/example/nextjs/app/api/oauth/callback/route.ts +22 -6
- package/skills/beervid-app-cli/example/nextjs/app/api/publish/tts/route.ts +2 -2
- package/skills/beervid-app-cli/example/standard/README.md +6 -0
- package/skills/beervid-app-cli/example/standard/tts-publish-flow.ts +1 -1
- package/skills/beervid-app-cli/references/api-reference.md +37 -11
- package/skills/beervid-app-cli/skill.json +36 -0
package/README.md
CHANGED
|
@@ -30,6 +30,14 @@ node dist/cli.mjs --help
|
|
|
30
30
|
node dist/cli.mjs config --show
|
|
31
31
|
```
|
|
32
32
|
|
|
33
|
+
### 导出类型
|
|
34
|
+
|
|
35
|
+
构建后包根会导出 CLI 相关类型,可直接在 TypeScript 中引用:
|
|
36
|
+
|
|
37
|
+
```ts
|
|
38
|
+
import type { PublishCommandOptions, PublishTTFlowCommandOptions } from 'beervid-app-cli'
|
|
39
|
+
```
|
|
40
|
+
|
|
33
41
|
### 在 Claude Code / Codex / Antigravity 中使用(以下说明面向 AI Agent)
|
|
34
42
|
|
|
35
43
|
#### 方式一:通过 `npx skills add` 安装(推荐)
|
|
@@ -52,6 +60,9 @@ npx skills add Lupeiwen0/beervid-app-cli
|
|
|
52
60
|
```text
|
|
53
61
|
skills/beervid-app-cli/
|
|
54
62
|
SKILL.md
|
|
63
|
+
skill.json
|
|
64
|
+
QUICKSTART.md
|
|
65
|
+
FAQ.md
|
|
55
66
|
references/
|
|
56
67
|
docs/
|
|
57
68
|
example/
|
|
@@ -117,6 +128,14 @@ beervid publish-tts-flow --creator-id open_user_abc --file ./video.mp4 --interac
|
|
|
117
128
|
beervid publish-tts-flow --creator-id open_user_abc --file ./video.mp4 --product-id prod_123 --product-title "Widget"
|
|
118
129
|
```
|
|
119
130
|
|
|
131
|
+
## TT / TTS 账号关联说明
|
|
132
|
+
|
|
133
|
+
- TTS 账号可用于挂车发布和商品查询,但不能直接查询视频数据。
|
|
134
|
+
- 如果同一达人既要走 TTS 挂车发布,又要查询该账号的视频数据,需要分别完成 TTS 和 TT 两种 OAuth 授权。
|
|
135
|
+
- 官方当前没有提供 `uno_id` 这类可直接关联 TT/TTS 账号的稳定字段。
|
|
136
|
+
- 当前推荐在授权后调用 `account/info`,以两边返回的 `username` 作为关联键,在你方系统里建立 TT 和 TTS 的软关联。
|
|
137
|
+
- 真正调用 API 时仍然使用各自的业务主键:TTS 用 `creatorUserOpenId`,TT 用 `businessId`;`username` 只用于你方系统内的关联映射。
|
|
138
|
+
|
|
120
139
|
详细用法见 [SKILL.md](./skills/beervid-app-cli/SKILL.md)。完整 API 参考见 [references/api-reference.md](./skills/beervid-app-cli/references/api-reference.md)。
|
|
121
140
|
|
|
122
141
|
## 落地文档
|
package/dist/cli.d.ts
ADDED
package/dist/cli.mjs
CHANGED
|
@@ -173,6 +173,20 @@ function getRawOptionValues(rawArgs, optionName) {
|
|
|
173
173
|
function getRawOptionValue(rawArgs, optionName) {
|
|
174
174
|
return getRawOptionValues(rawArgs, optionName).at(-1);
|
|
175
175
|
}
|
|
176
|
+
function parseStrictInteger(value, optionName) {
|
|
177
|
+
if (value === void 0) return void 0;
|
|
178
|
+
const normalized = String(value).trim();
|
|
179
|
+
if (!/^-?\d+$/.test(normalized)) {
|
|
180
|
+
console.error(`\u9519\u8BEF: ${optionName} \u5FC5\u987B\u4E3A\u6574\u6570`);
|
|
181
|
+
process.exit(1);
|
|
182
|
+
}
|
|
183
|
+
const parsed = Number(normalized);
|
|
184
|
+
if (!Number.isSafeInteger(parsed)) {
|
|
185
|
+
console.error(`\u9519\u8BEF: ${optionName} \u8D85\u51FA\u5B89\u5168\u6574\u6570\u8303\u56F4`);
|
|
186
|
+
process.exit(1);
|
|
187
|
+
}
|
|
188
|
+
return parsed;
|
|
189
|
+
}
|
|
176
190
|
|
|
177
191
|
// src/commands/oauth.ts
|
|
178
192
|
function register(cli2) {
|
|
@@ -309,12 +323,21 @@ function register3(cli2) {
|
|
|
309
323
|
}
|
|
310
324
|
|
|
311
325
|
// src/commands/publish.ts
|
|
312
|
-
var MAX_PRODUCT_TITLE_LENGTH =
|
|
326
|
+
var MAX_PRODUCT_TITLE_LENGTH = 30;
|
|
313
327
|
var VALID_PUBLISH_TYPES = ["normal", "shoppable"];
|
|
328
|
+
function parseNonNegativeInt(value, optionName) {
|
|
329
|
+
const parsed = parseStrictInteger(value, optionName);
|
|
330
|
+
if (parsed === void 0) return void 0;
|
|
331
|
+
if (parsed < 0) {
|
|
332
|
+
console.error(`\u9519\u8BEF: ${optionName} \u5FC5\u987B\u4E3A\u5927\u4E8E\u7B49\u4E8E 0 \u7684\u6574\u6570`);
|
|
333
|
+
process.exit(1);
|
|
334
|
+
}
|
|
335
|
+
return parsed;
|
|
336
|
+
}
|
|
314
337
|
function register4(cli2) {
|
|
315
|
-
cli2.command("publish", "\u53D1\u5E03 TikTok \u89C6\u9891\uFF08\u666E\u901A/\u6302\u8F66\uFF09").option("--type <type>", "\u53D1\u5E03\u7C7B\u578B: normal\uFF08\u9ED8\u8BA4\uFF09\u6216 shoppable").option("--business-id <id>", "TT \u8D26\u53F7 businessId\uFF08\u666E\u901A\u53D1\u5E03\u5FC5\u586B\uFF09").option("--video-url <url>", "\u4E0A\u4F20\u540E\u7684\u89C6\u9891 URL\uFF08\u666E\u901A\u53D1\u5E03\u5FC5\u586B\uFF09").option("--creator-id <id>", "TTS \u8D26\u53F7 creatorUserOpenId\uFF08\u6302\u8F66\u53D1\u5E03\u5FC5\u586B\uFF09").option("--file-id <id>", "\u4E0A\u4F20\u8FD4\u56DE\u7684 videoFileId\uFF08\u6302\u8F66\u53D1\u5E03\u5FC5\u586B\uFF09").option("--product-id <id>", "\u5546\u54C1 ID\uFF08\u6302\u8F66\u53D1\u5E03\u5FC5\u586B\uFF09").option("--product-title <title>", "\u5546\u54C1\u6807\u9898\uFF0C\u6700\u591A
|
|
338
|
+
cli2.command("publish", "\u53D1\u5E03 TikTok \u89C6\u9891\uFF08\u666E\u901A/\u6302\u8F66\uFF09").option("--type <type>", "\u53D1\u5E03\u7C7B\u578B: normal\uFF08\u9ED8\u8BA4\uFF09\u6216 shoppable").option("--business-id <id>", "TT \u8D26\u53F7 businessId\uFF08\u666E\u901A\u53D1\u5E03\u5FC5\u586B\uFF09").option("--video-url <url>", "\u4E0A\u4F20\u540E\u7684\u89C6\u9891 URL\uFF08\u666E\u901A\u53D1\u5E03\u5FC5\u586B\uFF09").option("--creator-id <id>", "TTS \u8D26\u53F7 creatorUserOpenId\uFF08\u6302\u8F66\u53D1\u5E03\u5FC5\u586B\uFF09").option("--file-id <id>", "\u4E0A\u4F20\u8FD4\u56DE\u7684 videoFileId\uFF08\u6302\u8F66\u53D1\u5E03\u5FC5\u586B\uFF09").option("--product-id <id>", "\u5546\u54C1 ID\uFF08\u6302\u8F66\u53D1\u5E03\u5FC5\u586B\uFF09").option("--product-title <title>", "\u5546\u54C1\u6807\u9898\uFF0C\u6700\u591A 30 \u5B57\u7B26\uFF08\u6302\u8F66\u53D1\u5E03\u5FC5\u586B\uFF09", {
|
|
316
339
|
type: [String]
|
|
317
|
-
}).option("--caption <text>", "\u89C6\u9891\u63CF\u8FF0/\u6587\u6848\uFF08\u53EF\u9009\uFF09").action(
|
|
340
|
+
}).option("--caption <text>", "\u89C6\u9891\u63CF\u8FF0/\u6587\u6848\uFF08\u53EF\u9009\uFF09").option("--brand-organic", "\u6807\u8BB0\u4E3A\u54C1\u724C\u6709\u673A\u5185\u5BB9\uFF08TT \u666E\u901A\u53D1\u5E03\u53EF\u9009\uFF09").option("--branded-content", "\u6807\u8BB0\u4E3A\u54C1\u724C\u5185\u5BB9\uFF08TT \u666E\u901A\u53D1\u5E03\u53EF\u9009\uFF09").option("--disable-comment", "\u7981\u7528\u8BC4\u8BBA\uFF08TT \u666E\u901A\u53D1\u5E03\u53EF\u9009\uFF09").option("--disable-duet", "\u7981\u7528\u5408\u62CD\uFF08TT \u666E\u901A\u53D1\u5E03\u53EF\u9009\uFF09").option("--disable-stitch", "\u7981\u7528\u62FC\u63A5\uFF08TT \u666E\u901A\u53D1\u5E03\u53EF\u9009\uFF09").option("--thumbnail-offset <n>", "\u7F29\u7565\u56FE\u504F\u79FB\uFF08TT \u666E\u901A\u53D1\u5E03\u53EF\u9009\uFF0C>= 0\uFF09").action(
|
|
318
341
|
async (options) => {
|
|
319
342
|
const publishType = (options.type ?? "normal").toLowerCase();
|
|
320
343
|
const businessId = getRawOptionValue(cli2.rawArgs, "--business-id");
|
|
@@ -374,13 +397,34 @@ function register4(cli2) {
|
|
|
374
397
|
);
|
|
375
398
|
process.exit(1);
|
|
376
399
|
}
|
|
400
|
+
const publishOptions = {
|
|
401
|
+
caption: options.caption
|
|
402
|
+
};
|
|
403
|
+
if (options.brandOrganic) publishOptions.isBrandOrganic = true;
|
|
404
|
+
if (options.brandedContent) publishOptions.isBrandedContent = true;
|
|
405
|
+
if (options.disableComment) publishOptions.disableComment = true;
|
|
406
|
+
if (options.disableDuet) publishOptions.disableDuet = true;
|
|
407
|
+
if (options.disableStitch) publishOptions.disableStitch = true;
|
|
408
|
+
const thumbnailOffset = parseNonNegativeInt(
|
|
409
|
+
options.thumbnailOffset,
|
|
410
|
+
"--thumbnail-offset"
|
|
411
|
+
);
|
|
412
|
+
if (thumbnailOffset !== void 0) {
|
|
413
|
+
publishOptions.thumbnailOffset = thumbnailOffset;
|
|
414
|
+
}
|
|
377
415
|
console.log("\u666E\u901A\u89C6\u9891\u53D1\u5E03\u4E2D...");
|
|
378
416
|
data = await openApiPost(
|
|
379
417
|
"/api/v1/open/tiktok/video/publish",
|
|
380
418
|
{
|
|
381
419
|
businessId,
|
|
382
420
|
videoUrl: options.videoUrl,
|
|
383
|
-
caption:
|
|
421
|
+
caption: publishOptions.caption ?? "",
|
|
422
|
+
...publishOptions.isBrandOrganic !== void 0 ? { isBrandOrganic: publishOptions.isBrandOrganic } : {},
|
|
423
|
+
...publishOptions.isBrandedContent !== void 0 ? { isBrandedContent: publishOptions.isBrandedContent } : {},
|
|
424
|
+
...publishOptions.disableComment !== void 0 ? { disableComment: publishOptions.disableComment } : {},
|
|
425
|
+
...publishOptions.disableDuet !== void 0 ? { disableDuet: publishOptions.disableDuet } : {},
|
|
426
|
+
...publishOptions.disableStitch !== void 0 ? { disableStitch: publishOptions.disableStitch } : {},
|
|
427
|
+
...publishOptions.thumbnailOffset !== void 0 ? { thumbnailOffset: publishOptions.thumbnailOffset } : {}
|
|
384
428
|
}
|
|
385
429
|
);
|
|
386
430
|
console.log("\n\u53D1\u5E03\u5DF2\u63D0\u4EA4\uFF08\u9700\u8F6E\u8BE2\u72B6\u6001\uFF09:");
|
|
@@ -481,81 +525,106 @@ function register5(cli2) {
|
|
|
481
525
|
|
|
482
526
|
// src/commands/query-video.ts
|
|
483
527
|
function register6(cli2) {
|
|
484
|
-
cli2.command("query-video", "\u67E5\u8BE2\u89C6\u9891\u7EDF\u8BA1\u6570\u636E").option("--business-id <id>", "TT \u8D26\u53F7 businessId\uFF08\u5FC5\u586B\uFF09").option("--item-ids <ids>", "\u89C6\u9891 ID\uFF0C\u652F\u6301\u91CD\u590D\u4F20\u53C2\u6216\u9017\u53F7\u5206\u9694\uFF08\
|
|
485
|
-
|
|
486
|
-
|
|
487
|
-
|
|
488
|
-
|
|
489
|
-
|
|
490
|
-
|
|
491
|
-
|
|
492
|
-
].filter(Boolean);
|
|
493
|
-
console.error(`\u7F3A\u5C11\u5FC5\u586B\u53C2\u6570: ${missing.join(", ")}
|
|
528
|
+
cli2.command("query-video", "\u67E5\u8BE2\u89C6\u9891\u7EDF\u8BA1\u6570\u636E").option("--business-id <id>", "TT \u8D26\u53F7 businessId\uFF08\u5FC5\u586B\uFF09").option("--item-ids <ids>", "\u89C6\u9891 ID\uFF0C\u652F\u6301\u91CD\u590D\u4F20\u53C2\u6216\u9017\u53F7\u5206\u9694\uFF08\u53EF\u9009\uFF1B\u4E0D\u4F20\u5219\u67E5\u8BE2\u5168\u90E8\uFF09").option("--cursor <n>", "\u5206\u9875\u6E38\u6807\uFF08\u53EF\u9009\uFF09").option("--max-count <n>", "\u6BCF\u9875\u6570\u91CF\uFF08\u53EF\u9009\uFF0C10-20\uFF09").action(async () => {
|
|
529
|
+
const businessId = getRawOptionValue(cli2.rawArgs, "--business-id");
|
|
530
|
+
const rawItemIdArgs = getRawOptionValues(cli2.rawArgs, "--item-ids");
|
|
531
|
+
const rawCursor = getRawOptionValue(cli2.rawArgs, "--cursor");
|
|
532
|
+
const rawMaxCount = getRawOptionValue(cli2.rawArgs, "--max-count");
|
|
533
|
+
if (!businessId) {
|
|
534
|
+
const missing = [!businessId && "--business-id"].filter(Boolean);
|
|
535
|
+
console.error(`\u7F3A\u5C11\u5FC5\u586B\u53C2\u6570: ${missing.join(", ")}
|
|
494
536
|
`);
|
|
495
|
-
|
|
496
|
-
|
|
497
|
-
|
|
537
|
+
console.error(
|
|
538
|
+
"\u7528\u6CD5: beervid query-video --business-id <id> [--item-ids <id1,id2,...>] [--cursor <n>] [--max-count <n>]"
|
|
539
|
+
);
|
|
540
|
+
process.exit(1);
|
|
541
|
+
}
|
|
542
|
+
const itemIds = rawItemIdArgs.flatMap((value) => value.split(",")).map((id) => id.trim()).filter(Boolean);
|
|
543
|
+
if (rawItemIdArgs.length > 0 && itemIds.length === 0) {
|
|
544
|
+
console.error("\u9519\u8BEF: --item-ids \u4E0D\u80FD\u4E3A\u7A7A");
|
|
545
|
+
process.exit(1);
|
|
546
|
+
}
|
|
547
|
+
let cursor;
|
|
548
|
+
if (rawCursor !== void 0) {
|
|
549
|
+
cursor = parseStrictInteger(rawCursor, "--cursor");
|
|
550
|
+
if (cursor === void 0 || cursor < 0) {
|
|
551
|
+
console.error("\u9519\u8BEF: --cursor \u5FC5\u987B\u4E3A\u5927\u4E8E\u7B49\u4E8E 0 \u7684\u6574\u6570");
|
|
498
552
|
process.exit(1);
|
|
499
553
|
}
|
|
500
|
-
|
|
501
|
-
|
|
502
|
-
|
|
554
|
+
}
|
|
555
|
+
let maxCount;
|
|
556
|
+
if (rawMaxCount !== void 0) {
|
|
557
|
+
maxCount = parseStrictInteger(rawMaxCount, "--max-count");
|
|
558
|
+
if (maxCount === void 0 || maxCount < 10 || maxCount > 20) {
|
|
559
|
+
console.error("\u9519\u8BEF: --max-count \u5FC5\u987B\u4E3A 10 \u5230 20 \u4E4B\u95F4\u7684\u6574\u6570");
|
|
503
560
|
process.exit(1);
|
|
504
561
|
}
|
|
505
|
-
|
|
506
|
-
|
|
507
|
-
|
|
508
|
-
|
|
509
|
-
|
|
510
|
-
|
|
511
|
-
|
|
512
|
-
|
|
513
|
-
|
|
514
|
-
|
|
515
|
-
|
|
516
|
-
|
|
517
|
-
|
|
518
|
-
|
|
519
|
-
|
|
520
|
-
|
|
521
|
-
|
|
522
|
-
|
|
523
|
-
|
|
524
|
-
|
|
525
|
-
|
|
526
|
-
|
|
562
|
+
}
|
|
563
|
+
try {
|
|
564
|
+
console.log(
|
|
565
|
+
itemIds.length > 0 ? `\u67E5\u8BE2 ${itemIds.length} \u4E2A\u89C6\u9891\u7684\u6570\u636E...
|
|
566
|
+
` : "\u67E5\u8BE2\u89C6\u9891\u6570\u636E\u5217\u8868...\n"
|
|
567
|
+
);
|
|
568
|
+
const requestBody = {
|
|
569
|
+
businessId
|
|
570
|
+
};
|
|
571
|
+
if (itemIds.length > 0) requestBody.itemIds = itemIds;
|
|
572
|
+
if (cursor !== void 0) requestBody.cursor = cursor;
|
|
573
|
+
if (maxCount !== void 0) requestBody.maxCount = maxCount;
|
|
574
|
+
const data = await openApiPost("/api/v1/open/tiktok/video/query", requestBody);
|
|
575
|
+
const list = data.videoList ?? data.videos ?? [];
|
|
576
|
+
if (list.length === 0) {
|
|
577
|
+
console.log("\u672A\u67E5\u5230\u89C6\u9891\u6570\u636E");
|
|
578
|
+
process.exit(0);
|
|
579
|
+
}
|
|
580
|
+
const normalized = list.map((v) => ({
|
|
581
|
+
itemId: v.itemId ?? v.item_id,
|
|
582
|
+
videoViews: v.videoViews ?? v.video_views ?? 0,
|
|
583
|
+
likes: v.likes ?? 0,
|
|
584
|
+
comments: v.comments ?? 0,
|
|
585
|
+
shares: v.shares ?? 0,
|
|
586
|
+
thumbnailUrl: v.thumbnailUrl ?? v.thumbnail_url ?? "",
|
|
587
|
+
shareUrl: v.shareUrl ?? v.share_url ?? ""
|
|
588
|
+
}));
|
|
589
|
+
console.log(`\u67E5\u8BE2\u5230 ${normalized.length} \u4E2A\u89C6\u9891:
|
|
527
590
|
`);
|
|
528
|
-
|
|
529
|
-
|
|
530
|
-
|
|
531
|
-
|
|
532
|
-
|
|
533
|
-
|
|
534
|
-
|
|
535
|
-
}
|
|
536
|
-
printResult(data);
|
|
537
|
-
} catch (err) {
|
|
538
|
-
rethrowIfProcessExit(err);
|
|
539
|
-
console.error("\u67E5\u8BE2\u89C6\u9891\u6570\u636E\u5931\u8D25:", err.message);
|
|
540
|
-
process.exit(1);
|
|
591
|
+
for (const v of normalized) {
|
|
592
|
+
console.log(` \u89C6\u9891 ${v.itemId}`);
|
|
593
|
+
console.log(
|
|
594
|
+
` \u64AD\u653E: ${v.videoViews} \u70B9\u8D5E: ${v.likes} \u8BC4\u8BBA: ${v.comments} \u5206\u4EAB: ${v.shares}`
|
|
595
|
+
);
|
|
596
|
+
if (v.shareUrl) console.log(` \u94FE\u63A5: ${v.shareUrl}`);
|
|
597
|
+
console.log("");
|
|
541
598
|
}
|
|
599
|
+
printResult(data);
|
|
600
|
+
} catch (err) {
|
|
601
|
+
rethrowIfProcessExit(err);
|
|
602
|
+
console.error("\u67E5\u8BE2\u89C6\u9891\u6570\u636E\u5931\u8D25:", err.message);
|
|
603
|
+
process.exit(1);
|
|
542
604
|
}
|
|
543
|
-
);
|
|
605
|
+
});
|
|
544
606
|
}
|
|
545
607
|
|
|
546
608
|
// src/workflows/index.ts
|
|
547
609
|
import { createInterface } from "readline/promises";
|
|
548
610
|
import { stdin as input, stdout as output } from "process";
|
|
549
|
-
var MAX_PRODUCT_TITLE_LENGTH2 =
|
|
611
|
+
var MAX_PRODUCT_TITLE_LENGTH2 = 30;
|
|
550
612
|
function sleep2(ms) {
|
|
551
613
|
return new Promise((resolve2) => setTimeout(resolve2, ms));
|
|
552
614
|
}
|
|
553
|
-
async function publishNormalVideo(businessId, videoUrl,
|
|
554
|
-
|
|
615
|
+
async function publishNormalVideo(businessId, videoUrl, options = {}) {
|
|
616
|
+
const body = {
|
|
555
617
|
businessId,
|
|
556
618
|
videoUrl,
|
|
557
|
-
caption: caption ?? ""
|
|
558
|
-
}
|
|
619
|
+
caption: options.caption ?? ""
|
|
620
|
+
};
|
|
621
|
+
if (options.isBrandOrganic !== void 0) body.isBrandOrganic = options.isBrandOrganic;
|
|
622
|
+
if (options.isBrandedContent !== void 0) body.isBrandedContent = options.isBrandedContent;
|
|
623
|
+
if (options.disableComment !== void 0) body.disableComment = options.disableComment;
|
|
624
|
+
if (options.disableDuet !== void 0) body.disableDuet = options.disableDuet;
|
|
625
|
+
if (options.disableStitch !== void 0) body.disableStitch = options.disableStitch;
|
|
626
|
+
if (options.thumbnailOffset !== void 0) body.thumbnailOffset = options.thumbnailOffset;
|
|
627
|
+
return openApiPost("/api/v1/open/tiktok/video/publish", body);
|
|
559
628
|
}
|
|
560
629
|
async function publishTtsVideo(creatorId, fileId, productId, productTitle, caption) {
|
|
561
630
|
const normalizedTitle = productTitle.slice(0, MAX_PRODUCT_TITLE_LENGTH2);
|
|
@@ -650,6 +719,7 @@ function encodeCursor(cursor) {
|
|
|
650
719
|
return Buffer.from(JSON.stringify(cursor)).toString("base64");
|
|
651
720
|
}
|
|
652
721
|
async function queryProductsPage(creatorId, productType, pageSize, cursor) {
|
|
722
|
+
const normalizedPageSize = Math.min(Math.max(pageSize, 1), 20);
|
|
653
723
|
const allTypesToQuery = productType === "all" ? ["shop", "showcase"] : [productType];
|
|
654
724
|
const typesToQuery = allTypesToQuery.filter((type) => {
|
|
655
725
|
const token = type === "shop" ? cursor.shopToken : cursor.showcaseToken;
|
|
@@ -667,7 +737,7 @@ async function queryProductsPage(creatorId, productType, pageSize, cursor) {
|
|
|
667
737
|
const data = await openApiPost("/api/v1/open/tts/products/query", {
|
|
668
738
|
creatorUserOpenId: creatorId,
|
|
669
739
|
productType: type,
|
|
670
|
-
pageSize,
|
|
740
|
+
pageSize: normalizedPageSize,
|
|
671
741
|
pageToken: pageToken ?? ""
|
|
672
742
|
});
|
|
673
743
|
return { type, data };
|
|
@@ -719,12 +789,13 @@ async function queryProductsPage(creatorId, productType, pageSize, cursor) {
|
|
|
719
789
|
async function fetchProductPool(creatorId, productType, pageSize, maxPages) {
|
|
720
790
|
const allProducts = /* @__PURE__ */ new Map();
|
|
721
791
|
const rawGroups = [];
|
|
792
|
+
const normalizedPageSize = Math.min(Math.max(pageSize, 1), 20);
|
|
722
793
|
let cursor = { shopToken: "", showcaseToken: "" };
|
|
723
794
|
let nextCursor = null;
|
|
724
795
|
let pagesScanned = 0;
|
|
725
796
|
const failedSourcesSet = /* @__PURE__ */ new Set();
|
|
726
797
|
for (let page = 1; page <= maxPages; page++) {
|
|
727
|
-
const pageResult = await queryProductsPage(creatorId, productType,
|
|
798
|
+
const pageResult = await queryProductsPage(creatorId, productType, normalizedPageSize, cursor);
|
|
728
799
|
if (pageResult.successCount === 0) {
|
|
729
800
|
throw new Error("\u6240\u6709\u5546\u54C1\u6E90\u90FD\u8BF7\u6C42\u5931\u8D25");
|
|
730
801
|
}
|
|
@@ -749,7 +820,7 @@ async function fetchProductPool(creatorId, productType, pageSize, maxPages) {
|
|
|
749
820
|
rawGroups,
|
|
750
821
|
summary: {
|
|
751
822
|
productType,
|
|
752
|
-
pageSize,
|
|
823
|
+
pageSize: normalizedPageSize,
|
|
753
824
|
pagesScanned,
|
|
754
825
|
productCount: allProducts.size,
|
|
755
826
|
nextCursor,
|
|
@@ -810,14 +881,14 @@ function register7(cli2) {
|
|
|
810
881
|
process.exit(1);
|
|
811
882
|
}
|
|
812
883
|
const productType = (options.productType ?? "all").toLowerCase();
|
|
813
|
-
const pageSize =
|
|
884
|
+
const pageSize = parseStrictInteger(options.pageSize ?? "20", "--page-size");
|
|
814
885
|
const cursor = options.cursor ?? "";
|
|
815
886
|
if (!VALID_PRODUCT_TYPES.includes(productType)) {
|
|
816
887
|
console.error("\u9519\u8BEF: --product-type \u5FC5\u987B\u4E3A shop\u3001showcase \u6216 all");
|
|
817
888
|
process.exit(1);
|
|
818
889
|
}
|
|
819
|
-
if (
|
|
820
|
-
console.error("\u9519\u8BEF: --page-size \u5FC5\u987B\u4E3A\
|
|
890
|
+
if (pageSize === void 0 || pageSize <= 0 || pageSize > 20) {
|
|
891
|
+
console.error("\u9519\u8BEF: --page-size \u5FC5\u987B\u4E3A 1 \u5230 20 \u4E4B\u95F4\u7684\u6574\u6570");
|
|
821
892
|
process.exit(1);
|
|
822
893
|
}
|
|
823
894
|
try {
|
|
@@ -867,15 +938,24 @@ function register7(cli2) {
|
|
|
867
938
|
|
|
868
939
|
// src/commands/publish-tt-flow.ts
|
|
869
940
|
function parsePositiveInt(value, optionName, defaultValue) {
|
|
870
|
-
const parsed =
|
|
871
|
-
if (
|
|
941
|
+
const parsed = parseStrictInteger(value ?? `${defaultValue}`, optionName);
|
|
942
|
+
if (parsed === void 0 || parsed <= 0) {
|
|
872
943
|
console.error(`\u9519\u8BEF: ${optionName} \u5FC5\u987B\u4E3A\u5927\u4E8E 0 \u7684\u6574\u6570`);
|
|
873
944
|
process.exit(1);
|
|
874
945
|
}
|
|
875
946
|
return parsed;
|
|
876
947
|
}
|
|
948
|
+
function parseNonNegativeInt2(value, optionName) {
|
|
949
|
+
const parsed = parseStrictInteger(value, optionName);
|
|
950
|
+
if (parsed === void 0) return void 0;
|
|
951
|
+
if (parsed < 0) {
|
|
952
|
+
console.error(`\u9519\u8BEF: ${optionName} \u5FC5\u987B\u4E3A\u5927\u4E8E\u7B49\u4E8E 0 \u7684\u6574\u6570`);
|
|
953
|
+
process.exit(1);
|
|
954
|
+
}
|
|
955
|
+
return parsed;
|
|
956
|
+
}
|
|
877
957
|
function register8(cli2) {
|
|
878
|
-
cli2.command("publish-tt-flow", "\u6267\u884C TT \u5B8C\u6574\u53D1\u5E03\u6D41\u7A0B\uFF1A\u4E0A\u4F20\u3001\u53D1\u5E03\u3001\u8F6E\u8BE2\u3001\u67E5\u8BE2\u6570\u636E").option("--business-id <id>", "TT \u8D26\u53F7 businessId\uFF08\u5FC5\u586B\uFF09").option("--file <path>", "\u89C6\u9891\u6587\u4EF6\u8DEF\u5F84\u6216 URL\uFF08\u5FC5\u586B\uFF09").option("--caption <text>", "\u89C6\u9891\u63CF\u8FF0/\u6587\u6848\uFF08\u53EF\u9009\uFF09").option("--token <token>", "\u5DF2\u6709\u4E0A\u4F20\u51ED\u8BC1\uFF08\u53EF\u9009\uFF09").option("--interval <sec>", "\u8F6E\u8BE2\u95F4\u9694\u79D2\u6570\uFF08\u9ED8\u8BA4 5\uFF09").option("--max-polls <n>", "\u6700\u5927\u8F6E\u8BE2\u6B21\u6570\uFF08\u9ED8\u8BA4 60\uFF09").option("--query-interval <sec>", "\u89C6\u9891\u6570\u636E\u67E5\u8BE2\u91CD\u8BD5\u95F4\u9694\u79D2\u6570\uFF08\u9ED8\u8BA4 5\uFF09").option("--query-max-attempts <n>", "\u89C6\u9891\u6570\u636E\u67E5\u8BE2\u6700\u5927\u91CD\u8BD5\u6B21\u6570\uFF08\u9ED8\u8BA4 3\uFF09").action(
|
|
958
|
+
cli2.command("publish-tt-flow", "\u6267\u884C TT \u5B8C\u6574\u53D1\u5E03\u6D41\u7A0B\uFF1A\u4E0A\u4F20\u3001\u53D1\u5E03\u3001\u8F6E\u8BE2\u3001\u67E5\u8BE2\u6570\u636E").option("--business-id <id>", "TT \u8D26\u53F7 businessId\uFF08\u5FC5\u586B\uFF09").option("--file <path>", "\u89C6\u9891\u6587\u4EF6\u8DEF\u5F84\u6216 URL\uFF08\u5FC5\u586B\uFF09").option("--caption <text>", "\u89C6\u9891\u63CF\u8FF0/\u6587\u6848\uFF08\u53EF\u9009\uFF09").option("--token <token>", "\u5DF2\u6709\u4E0A\u4F20\u51ED\u8BC1\uFF08\u53EF\u9009\uFF09").option("--brand-organic", "\u6807\u8BB0\u4E3A\u54C1\u724C\u6709\u673A\u5185\u5BB9\uFF08\u53EF\u9009\uFF09").option("--branded-content", "\u6807\u8BB0\u4E3A\u54C1\u724C\u5185\u5BB9\uFF08\u53EF\u9009\uFF09").option("--disable-comment", "\u7981\u7528\u8BC4\u8BBA\uFF08\u53EF\u9009\uFF09").option("--disable-duet", "\u7981\u7528\u5408\u62CD\uFF08\u53EF\u9009\uFF09").option("--disable-stitch", "\u7981\u7528\u62FC\u63A5\uFF08\u53EF\u9009\uFF09").option("--thumbnail-offset <n>", "\u7F29\u7565\u56FE\u504F\u79FB\uFF08\u53EF\u9009\uFF0C>= 0\uFF09").option("--interval <sec>", "\u8F6E\u8BE2\u95F4\u9694\u79D2\u6570\uFF08\u9ED8\u8BA4 5\uFF09").option("--max-polls <n>", "\u6700\u5927\u8F6E\u8BE2\u6B21\u6570\uFF08\u9ED8\u8BA4 60\uFF09").option("--query-interval <sec>", "\u89C6\u9891\u6570\u636E\u67E5\u8BE2\u91CD\u8BD5\u95F4\u9694\u79D2\u6570\uFF08\u9ED8\u8BA4 5\uFF09").option("--query-max-attempts <n>", "\u89C6\u9891\u6570\u636E\u67E5\u8BE2\u6700\u5927\u91CD\u8BD5\u6B21\u6570\uFF08\u9ED8\u8BA4 3\uFF09").action(
|
|
879
959
|
async (options) => {
|
|
880
960
|
const businessId = getRawOptionValue(cli2.rawArgs, "--business-id");
|
|
881
961
|
if (!businessId || !options.file) {
|
|
@@ -898,12 +978,24 @@ function register8(cli2) {
|
|
|
898
978
|
"--query-max-attempts",
|
|
899
979
|
3
|
|
900
980
|
);
|
|
981
|
+
const publishOptions = {
|
|
982
|
+
caption: options.caption
|
|
983
|
+
};
|
|
984
|
+
if (options.brandOrganic) publishOptions.isBrandOrganic = true;
|
|
985
|
+
if (options.brandedContent) publishOptions.isBrandedContent = true;
|
|
986
|
+
if (options.disableComment) publishOptions.disableComment = true;
|
|
987
|
+
if (options.disableDuet) publishOptions.disableDuet = true;
|
|
988
|
+
if (options.disableStitch) publishOptions.disableStitch = true;
|
|
989
|
+
const thumbnailOffset = parseNonNegativeInt2(options.thumbnailOffset, "--thumbnail-offset");
|
|
990
|
+
if (thumbnailOffset !== void 0) {
|
|
991
|
+
publishOptions.thumbnailOffset = thumbnailOffset;
|
|
992
|
+
}
|
|
901
993
|
try {
|
|
902
994
|
console.log("\u5F00\u59CB\u6267\u884C TT \u5B8C\u6574\u53D1\u5E03\u6D41\u7A0B...");
|
|
903
995
|
console.log("1/4 \u6B63\u5728\u4E0A\u4F20\u89C6\u9891...");
|
|
904
996
|
const upload = await uploadNormalVideo(options.file, options.token);
|
|
905
997
|
console.log("2/4 \u6B63\u5728\u53D1\u5E03\u89C6\u9891...");
|
|
906
|
-
const publish = await publishNormalVideo(businessId, upload.fileUrl,
|
|
998
|
+
const publish = await publishNormalVideo(businessId, upload.fileUrl, publishOptions);
|
|
907
999
|
console.log("3/4 \u6B63\u5728\u8F6E\u8BE2\u53D1\u5E03\u72B6\u6001...");
|
|
908
1000
|
const status = await pollNormalVideoStatus(businessId, publish.shareId, intervalSec, maxPolls);
|
|
909
1001
|
const videoId = status.postIds[0] ?? null;
|
|
@@ -1072,7 +1164,7 @@ function register9(cli2) {
|
|
|
1072
1164
|
options.caption
|
|
1073
1165
|
);
|
|
1074
1166
|
if (publishResult.productTitle !== selectedProduct.title) {
|
|
1075
|
-
console.warn("\u5546\u54C1\u6807\u9898\u8D85\u8FC7
|
|
1167
|
+
console.warn("\u5546\u54C1\u6807\u9898\u8D85\u8FC7 30 \u5B57\u7B26\uFF0C\u53D1\u5E03\u65F6\u5DF2\u81EA\u52A8\u622A\u65AD");
|
|
1076
1168
|
}
|
|
1077
1169
|
printResult({
|
|
1078
1170
|
products: queriedProducts,
|
|
@@ -1130,7 +1222,7 @@ function register10(cli2) {
|
|
|
1130
1222
|
|
|
1131
1223
|
// src/cli.ts
|
|
1132
1224
|
var cli = cac("beervid");
|
|
1133
|
-
var cliVersion = true ? "0.2.
|
|
1225
|
+
var cliVersion = true ? "0.2.7" : pkg.version;
|
|
1134
1226
|
register10(cli);
|
|
1135
1227
|
register(cli);
|
|
1136
1228
|
register2(cli);
|