siluzan-cso-cli 1.0.0-beta.29 → 1.0.0-beta.30
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 +1 -1
- package/dist/index.js +268 -71
- package/dist/skill/SKILL.md +7 -6
- package/dist/skill/_meta.json +2 -2
- package/dist/skill/assets/publish-config-image.example.json +4 -3
- package/dist/skill/assets/publish-config.example.json +9 -8
- package/dist/skill/references/analytics.md +41 -0
- package/dist/skill/references/publish.md +15 -0
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -20,7 +20,7 @@ siluzan-cso init -d /path/to/skills # 写入自定义目录
|
|
|
20
20
|
siluzan-cso init --force # 强制覆盖已存在文件
|
|
21
21
|
```
|
|
22
22
|
|
|
23
|
-
> **注意**:当前为测试版(1.0.0-beta.
|
|
23
|
+
> **注意**:当前为测试版(1.0.0-beta.30),供内部测试使用。正式发布后安装命令将改为 `npm install -g siluzan-cso-cli`。
|
|
24
24
|
|
|
25
25
|
| 助手 | 建议 `--ai` |
|
|
26
26
|
|------|-------------|
|
package/dist/index.js
CHANGED
|
@@ -2971,7 +2971,7 @@ async function runUpdate(options) {
|
|
|
2971
2971
|
console.log(`
|
|
2972
2972
|
\u5F53\u524D\u7248\u672C\uFF1A${current}`);
|
|
2973
2973
|
const npmTag = npmDistTagForBuildEnv(BUILD_ENV);
|
|
2974
|
-
console.log(
|
|
2974
|
+
console.log("\u6B63\u5728\u67E5\u8BE2 npm registry\u2026");
|
|
2975
2975
|
const latest = await fetchLatestVersion();
|
|
2976
2976
|
if (!latest) {
|
|
2977
2977
|
console.warn("\u26A0\uFE0F \u65E0\u6CD5\u8BBF\u95EE npm registry\uFF0C\u8BF7\u68C0\u67E5\u7F51\u7EDC\u540E\u91CD\u8BD5\u3002");
|
|
@@ -3137,9 +3137,30 @@ function printCliTable(rows, columns, options) {
|
|
|
3137
3137
|
}
|
|
3138
3138
|
|
|
3139
3139
|
// src/commands/list-accounts.ts
|
|
3140
|
-
|
|
3141
|
-
|
|
3142
|
-
|
|
3140
|
+
var MEDIA_TYPE_ALIAS = {
|
|
3141
|
+
tiktok: "TikTokBusinessAccount",
|
|
3142
|
+
tiktokbusinessaccount: "TikTokBusinessAccount",
|
|
3143
|
+
douyin: "Douyin",
|
|
3144
|
+
\u6296\u97F3: "Douyin",
|
|
3145
|
+
youtube: "YouTube",
|
|
3146
|
+
wechat: "WeChatChannel",
|
|
3147
|
+
wechatchannel: "WeChatChannel",
|
|
3148
|
+
\u89C6\u9891\u53F7: "WeChatChannel",
|
|
3149
|
+
\u5FAE\u4FE1\u89C6\u9891\u53F7: "WeChatChannel",
|
|
3150
|
+
instagram: "Instagram",
|
|
3151
|
+
ig: "Instagram",
|
|
3152
|
+
facebook: "Facebook",
|
|
3153
|
+
fb: "Facebook",
|
|
3154
|
+
twitter: "Twitter",
|
|
3155
|
+
x: "Twitter",
|
|
3156
|
+
kuaishou: "Kuaishou",
|
|
3157
|
+
\u5FEB\u624B: "Kuaishou",
|
|
3158
|
+
linkedin: "Linkedin",
|
|
3159
|
+
kwai: "Kuaishou"
|
|
3160
|
+
};
|
|
3161
|
+
function normalizeMediaType(input) {
|
|
3162
|
+
if (!input) return input;
|
|
3163
|
+
return MEDIA_TYPE_ALIAS[input.toLowerCase()] ?? MEDIA_TYPE_ALIAS[input] ?? input;
|
|
3143
3164
|
}
|
|
3144
3165
|
function formatOwners(ownerInfo) {
|
|
3145
3166
|
if (!ownerInfo || ownerInfo.length === 0) return "-";
|
|
@@ -3165,6 +3186,15 @@ function formatDate(iso) {
|
|
|
3165
3186
|
if (!iso) return "-";
|
|
3166
3187
|
return iso.slice(0, 10);
|
|
3167
3188
|
}
|
|
3189
|
+
function groupByPlatform(list) {
|
|
3190
|
+
const map = /* @__PURE__ */ new Map();
|
|
3191
|
+
for (const account of list) {
|
|
3192
|
+
const platform = account.mediaAccountType || "\u672A\u77E5\u5E73\u53F0";
|
|
3193
|
+
if (!map.has(platform)) map.set(platform, []);
|
|
3194
|
+
map.get(platform).push(account);
|
|
3195
|
+
}
|
|
3196
|
+
return Array.from(map.entries());
|
|
3197
|
+
}
|
|
3168
3198
|
async function runListAccounts(options) {
|
|
3169
3199
|
const config = loadConfig(options.token);
|
|
3170
3200
|
const isDomestic = options.domestic ?? false;
|
|
@@ -3189,7 +3219,7 @@ async function runListAccounts(options) {
|
|
|
3189
3219
|
pageNo: String(pageNo),
|
|
3190
3220
|
pageSize: String(pageSize),
|
|
3191
3221
|
...options.name ? { mediaCustomerName: options.name } : {},
|
|
3192
|
-
...options.mediaType ? { mediaType: options.mediaType } : {},
|
|
3222
|
+
...options.mediaType ? { mediaType: normalizeMediaType(options.mediaType) } : {},
|
|
3193
3223
|
...options.owner ? { owner: options.owner } : {},
|
|
3194
3224
|
...stateParams
|
|
3195
3225
|
});
|
|
@@ -3226,7 +3256,7 @@ async function runListAccounts(options) {
|
|
|
3226
3256
|
groupName: a.groupName ?? "",
|
|
3227
3257
|
imageUrl: a.imageUrl ?? null,
|
|
3228
3258
|
overview: a.mediaAccountOverviewDataDto ?? null,
|
|
3229
|
-
externalMediaAccountTokenId:
|
|
3259
|
+
externalMediaAccountTokenId: a.externalMediaAccountTokenId
|
|
3230
3260
|
}));
|
|
3231
3261
|
console.log(JSON.stringify(outputAccounts, null, 2));
|
|
3232
3262
|
return;
|
|
@@ -3239,12 +3269,12 @@ async function runListAccounts(options) {
|
|
|
3239
3269
|
const totalPages = Math.ceil(total / pageSize);
|
|
3240
3270
|
const pageInfo = `\u7B2C ${pageNo} \u9875 / \u5171 ${totalPages} \u9875\uFF0C\u603B\u8BA1 ${total} \u6761`;
|
|
3241
3271
|
const tableOpts2 = options.unicode ? { plain: false } : void 0;
|
|
3242
|
-
|
|
3272
|
+
const groups = groupByPlatform(list);
|
|
3273
|
+
const isOverview = options.overview ?? true;
|
|
3274
|
+
if (isOverview) {
|
|
3243
3275
|
console.log(`
|
|
3244
|
-
\u8D26\u53F7\u6570\u636E\u603B\u89C8\uFF08${tradeLabel}\uFF0C${pageInfo}\uFF09
|
|
3245
|
-
`);
|
|
3276
|
+
\u8D26\u53F7\u6570\u636E\u603B\u89C8\uFF08${tradeLabel}\uFF0C${pageInfo}\uFF09`);
|
|
3246
3277
|
const overviewColumns = [
|
|
3247
|
-
{ key: "mediaAccountType", header: "\u5E73\u53F0" },
|
|
3248
3278
|
{ key: "mediaCustomerName", header: "\u8D26\u53F7\u540D\u79F0" },
|
|
3249
3279
|
{ key: "state", header: "\u72B6\u6001" },
|
|
3250
3280
|
{ key: "fansCount", header: "\u7C89\u4E1D\u6570" },
|
|
@@ -3253,26 +3283,28 @@ async function runListAccounts(options) {
|
|
|
3253
3283
|
{ key: "commentCount", header: "\u8BC4\u8BBA\u6570" },
|
|
3254
3284
|
{ key: "diggCount", header: "\u83B7\u8D5E\u6570" }
|
|
3255
3285
|
];
|
|
3256
|
-
const
|
|
3257
|
-
|
|
3258
|
-
|
|
3259
|
-
|
|
3260
|
-
|
|
3261
|
-
|
|
3262
|
-
|
|
3263
|
-
|
|
3264
|
-
|
|
3265
|
-
|
|
3266
|
-
|
|
3267
|
-
|
|
3268
|
-
|
|
3269
|
-
|
|
3286
|
+
for (const [platform, accounts] of groups) {
|
|
3287
|
+
console.log(`
|
|
3288
|
+
\u25AA ${platform}\uFF08${accounts.length} \u4E2A\u8D26\u53F7\uFF09
|
|
3289
|
+
`);
|
|
3290
|
+
const rows = accounts.map((a) => {
|
|
3291
|
+
const ov = a.mediaAccountOverviewDataDto;
|
|
3292
|
+
return {
|
|
3293
|
+
mediaCustomerName: a.mediaCustomerName,
|
|
3294
|
+
state: formatState(a.mediaAccountState, a.invalidOAuthToken),
|
|
3295
|
+
fansCount: formatCount(ov?.fansCount),
|
|
3296
|
+
videoCount: formatCount(ov?.videoCount),
|
|
3297
|
+
playCount: formatCount(ov?.playCount),
|
|
3298
|
+
commentCount: formatCount(ov?.commentCount),
|
|
3299
|
+
diggCount: formatCount(ov?.diggCount)
|
|
3300
|
+
};
|
|
3301
|
+
});
|
|
3302
|
+
printCliTable(rows, overviewColumns, tableOpts2);
|
|
3303
|
+
}
|
|
3270
3304
|
} else {
|
|
3271
3305
|
console.log(`
|
|
3272
|
-
\u5A92\u4F53\u8D26\u53F7\u5217\u8868\uFF08${tradeLabel}\uFF0C${pageInfo}\uFF09
|
|
3273
|
-
`);
|
|
3306
|
+
\u5A92\u4F53\u8D26\u53F7\u5217\u8868\uFF08${tradeLabel}\uFF0C${pageInfo}\uFF09`);
|
|
3274
3307
|
const columns = [
|
|
3275
|
-
{ key: "mediaAccountType", header: "\u5E73\u53F0" },
|
|
3276
3308
|
{ key: "mediaCustomerName", header: "\u8D26\u53F7\u540D\u79F0" },
|
|
3277
3309
|
{ key: "mediaCustomerId", header: "\u8D26\u53F7ID" },
|
|
3278
3310
|
{ key: "state", header: "\u72B6\u6001" },
|
|
@@ -3280,28 +3312,27 @@ async function runListAccounts(options) {
|
|
|
3280
3312
|
{ key: "tokenExpiry", header: "Token\u5230\u671F" },
|
|
3281
3313
|
{ key: "owners", header: "\u8D1F\u8D23\u4EBA" }
|
|
3282
3314
|
];
|
|
3283
|
-
const
|
|
3284
|
-
|
|
3285
|
-
|
|
3286
|
-
|
|
3287
|
-
|
|
3288
|
-
|
|
3289
|
-
|
|
3290
|
-
|
|
3291
|
-
|
|
3292
|
-
|
|
3293
|
-
|
|
3315
|
+
for (const [platform, accounts] of groups) {
|
|
3316
|
+
console.log(`
|
|
3317
|
+
\u25AA ${platform}\uFF08${accounts.length} \u4E2A\u8D26\u53F7\uFF09
|
|
3318
|
+
`);
|
|
3319
|
+
const rows = accounts.map((a) => ({
|
|
3320
|
+
mediaCustomerName: a.mediaCustomerName,
|
|
3321
|
+
mediaCustomerId: a.mediaCustomerId,
|
|
3322
|
+
state: formatState(a.mediaAccountState, a.invalidOAuthToken),
|
|
3323
|
+
lastAuthTime: formatDate(a.lastAuthorizationTime),
|
|
3324
|
+
// expiresOn 比 tokenTime 更准确,优先使用
|
|
3325
|
+
tokenExpiry: formatDate(a.expiresOn ?? a.tokenTime),
|
|
3326
|
+
owners: formatOwners(a.ownerInfo)
|
|
3327
|
+
}));
|
|
3328
|
+
printCliTable(rows, columns, tableOpts2);
|
|
3329
|
+
}
|
|
3294
3330
|
}
|
|
3295
3331
|
if (total > pageNo * pageSize) {
|
|
3296
3332
|
console.log(`
|
|
3297
3333
|
\u63D0\u793A\uFF1A\u8FD8\u6709\u66F4\u591A\u8D26\u53F7\uFF0C\u4F7F\u7528 --page ${pageNo + 1} \u53EF\u67E5\u770B\u4E0B\u4E00\u9875\u3002`);
|
|
3298
3334
|
}
|
|
3299
|
-
|
|
3300
|
-
console.log("\u63D0\u793A\uFF1A\u4F7F\u7528 --json \u53EF\u83B7\u53D6\u5B8C\u6574 JSON \u6570\u636E\uFF08\u542B mediaCustomerId \u7B49\u5B57\u6BB5\uFF09\u3002");
|
|
3301
|
-
} else {
|
|
3302
|
-
console.log("\u63D0\u793A\uFF1A\u4F7F\u7528 --overview \u53EF\u67E5\u770B\u8D26\u53F7\u7684\u7C89\u4E1D\u6570/\u4F5C\u54C1\u6570/\u64AD\u653E\u6570\u7B49\u6570\u636E\u603B\u89C8\u3002");
|
|
3303
|
-
console.log("\u63D0\u793A\uFF1A\u4F7F\u7528 --json \u53EF\u83B7\u53D6\u5B8C\u6574 JSON \u6570\u636E\uFF0C\u7528\u4E8E\u53D1\u5E03\u914D\u7F6E\u7B49\u573A\u666F\u3002");
|
|
3304
|
-
}
|
|
3335
|
+
console.log("\u63D0\u793A\uFF1A\u4F7F\u7528 --json \u53EF\u83B7\u53D6\u5B8C\u6574 JSON \u6570\u636E\uFF08\u542B mediaCustomerId \u7B49\u5B57\u6BB5\uFF09\u3002");
|
|
3305
3336
|
}
|
|
3306
3337
|
|
|
3307
3338
|
// src/commands/list-members.ts
|
|
@@ -3545,6 +3576,9 @@ function nowUtc() {
|
|
|
3545
3576
|
return (/* @__PURE__ */ new Date()).toISOString().replace("T", " ").slice(0, 19);
|
|
3546
3577
|
}
|
|
3547
3578
|
var guid = randomUUID;
|
|
3579
|
+
function isGuidFormat(s) {
|
|
3580
|
+
return /^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$/i.test(s);
|
|
3581
|
+
}
|
|
3548
3582
|
function defaultTaskName() {
|
|
3549
3583
|
const d = /* @__PURE__ */ new Date();
|
|
3550
3584
|
const pad = (n) => String(n).padStart(2, "0");
|
|
@@ -3619,6 +3653,7 @@ function finalizeChannels(channels, sentKey) {
|
|
|
3619
3653
|
ch.publishAts = chSendType > 1 && chPublishAt ? [chPublishAt] : [];
|
|
3620
3654
|
}
|
|
3621
3655
|
}
|
|
3656
|
+
var UUID_HINT = "\uFF08\u8BF7\u5148\u8FD0\u884C `siluzan-cso list-accounts --json` \u83B7\u53D6\u6B63\u786E\u7684 UUID \u503C\uFF0C\u4E0D\u8981\u4F7F\u7528\u5360\u4F4D\u7B26\u6587\u672C\uFF09";
|
|
3622
3657
|
function buildVideoChannels(videos, currentUserId) {
|
|
3623
3658
|
const channels = {};
|
|
3624
3659
|
const contents = [];
|
|
@@ -3628,8 +3663,23 @@ function buildVideoChannels(videos, currentUserId) {
|
|
|
3628
3663
|
if (!item.accounts?.length) errorList.push(`\u89C6\u9891 "${item.videoName}" \u672A\u8BBE\u7F6E\u8D26\u53F7`);
|
|
3629
3664
|
if (!item.title) errorList.push(`\u89C6\u9891 "${item.videoName}" \u672A\u586B\u5199\u6807\u9898`);
|
|
3630
3665
|
if (!item.cover?.imageUrl) errorList.push(`\u89C6\u9891 "${item.videoName}" \u5C01\u9762\u53C2\u6570\u7F3A\u5931`);
|
|
3666
|
+
if (!isGuidFormat(item.videoId)) {
|
|
3667
|
+
errorList.push(
|
|
3668
|
+
`\u89C6\u9891 "${item.videoName}" \u7684 videoId "${item.videoId}" \u4E0D\u662F\u5408\u6CD5 UUID \u683C\u5F0F ${UUID_HINT}`
|
|
3669
|
+
);
|
|
3670
|
+
}
|
|
3631
3671
|
let itemSendType = 1;
|
|
3632
3672
|
for (const account of item.accounts ?? []) {
|
|
3673
|
+
if (!isGuidFormat(account.entityId)) {
|
|
3674
|
+
errorList.push(
|
|
3675
|
+
`\u8D26\u53F7 "${account.mediaCustomerName}" \u7684 entityId "${account.entityId}" \u4E0D\u662F\u5408\u6CD5 UUID \u683C\u5F0F ${UUID_HINT}`
|
|
3676
|
+
);
|
|
3677
|
+
}
|
|
3678
|
+
if (!isGuidFormat(account.externalMediaAccountTokenId)) {
|
|
3679
|
+
errorList.push(
|
|
3680
|
+
`\u8D26\u53F7 "${account.mediaCustomerName}" \u7684 externalMediaAccountTokenId "${account.externalMediaAccountTokenId}" \u4E0D\u662F\u5408\u6CD5 UUID \u683C\u5F0F ${UUID_HINT}`
|
|
3681
|
+
);
|
|
3682
|
+
}
|
|
3633
3683
|
const mediaType = account.mediaAccountType;
|
|
3634
3684
|
const sendType = toSendType(item.publishMode);
|
|
3635
3685
|
const publishAtUtc = item.publishAt ? new Date(item.publishAt).toISOString() : null;
|
|
@@ -3729,6 +3779,16 @@ function buildImageChannels(posts, currentUserId) {
|
|
|
3729
3779
|
if (!item.accounts?.length) errorList.push("\u56FE\u6587\u5E16\u5B50\u672A\u8BBE\u7F6E\u8D26\u53F7");
|
|
3730
3780
|
let itemSendType = 1;
|
|
3731
3781
|
for (const account of item.accounts ?? []) {
|
|
3782
|
+
if (!isGuidFormat(account.entityId)) {
|
|
3783
|
+
errorList.push(
|
|
3784
|
+
`\u8D26\u53F7 "${account.mediaCustomerName}" \u7684 entityId "${account.entityId}" \u4E0D\u662F\u5408\u6CD5 UUID \u683C\u5F0F ${UUID_HINT}`
|
|
3785
|
+
);
|
|
3786
|
+
}
|
|
3787
|
+
if (!isGuidFormat(account.externalMediaAccountTokenId)) {
|
|
3788
|
+
errorList.push(
|
|
3789
|
+
`\u8D26\u53F7 "${account.mediaCustomerName}" \u7684 externalMediaAccountTokenId "${account.externalMediaAccountTokenId}" \u4E0D\u662F\u5408\u6CD5 UUID \u683C\u5F0F ${UUID_HINT}`
|
|
3790
|
+
);
|
|
3791
|
+
}
|
|
3732
3792
|
const mediaType = account.mediaAccountType;
|
|
3733
3793
|
const sendType = toSendType(item.publishMode);
|
|
3734
3794
|
const publishAtUtc = item.publishAt ? new Date(item.publishAt).toISOString() : null;
|
|
@@ -3777,6 +3837,127 @@ function buildImageChannels(posts, currentUserId) {
|
|
|
3777
3837
|
finalizeChannels(channels, "imageTextToBeSent");
|
|
3778
3838
|
return { channels, videoType: globalSendType, contents, errorList };
|
|
3779
3839
|
}
|
|
3840
|
+
function formatTopics(topics) {
|
|
3841
|
+
if (!topics?.length) return "";
|
|
3842
|
+
return topics.map((t) => `#${t}`).join(" ");
|
|
3843
|
+
}
|
|
3844
|
+
function formatPublishMode(mode, publishAt) {
|
|
3845
|
+
if (mode === "scheduled") {
|
|
3846
|
+
return publishAt ? `\u5B9A\u65F6\u53D1\u5E03\uFF08${publishAt}\uFF09` : "\u5B9A\u65F6\u53D1\u5E03\uFF08\u26A0\uFE0F \u672A\u586B\u5199 publishAt\uFF09";
|
|
3847
|
+
}
|
|
3848
|
+
return "\u7ACB\u5373\u53D1\u5E03";
|
|
3849
|
+
}
|
|
3850
|
+
function printDryRun(input, taskName, isDomestic, body, verbose) {
|
|
3851
|
+
const SEP = "\u2500".repeat(54);
|
|
3852
|
+
console.log("\n\u2705 [dry-run] \u53D1\u5E03\u53C2\u6570\u9884\u89C8\uFF08\u672A\u5B9E\u9645\u63D0\u4EA4\uFF09\n");
|
|
3853
|
+
console.log(`\u4EFB\u52A1\u540D \uFF1A${taskName}`);
|
|
3854
|
+
console.log(`\u5185\u5BB9\u7C7B\u578B \uFF1A${input.contentType === 1 ? "\u89C6\u9891" : "\u56FE\u6587"}`);
|
|
3855
|
+
console.log(`\u5E73\u53F0\u6A21\u5F0F \uFF1A${isDomestic ? "\u5185\u8D38" : "\u5916\u8D38"}`);
|
|
3856
|
+
if (input.contentType === 1) {
|
|
3857
|
+
const items = input.videos;
|
|
3858
|
+
console.log(`\u89C6\u9891\u6570\u91CF \uFF1A${items.length} \u4E2A`);
|
|
3859
|
+
for (let i = 0; i < items.length; i++) {
|
|
3860
|
+
const item = items[i];
|
|
3861
|
+
console.log(`
|
|
3862
|
+
${SEP}`);
|
|
3863
|
+
console.log(` \u89C6\u9891 ${i + 1} / ${items.length}\uFF1A${item.videoName}`);
|
|
3864
|
+
console.log(SEP);
|
|
3865
|
+
console.log(` \u89C6\u9891 ID \uFF1A${item.videoId}`);
|
|
3866
|
+
console.log(` \u6807\u9898 \uFF1A${item.title || "\u26A0\uFE0F \u672A\u586B\u5199"}`);
|
|
3867
|
+
if (item.description) {
|
|
3868
|
+
console.log(` \u63CF\u8FF0 \uFF1A${item.description}`);
|
|
3869
|
+
}
|
|
3870
|
+
const topicsStr = formatTopics(item.topics);
|
|
3871
|
+
if (topicsStr) {
|
|
3872
|
+
console.log(` \u6807\u7B7E \uFF1A${topicsStr}`);
|
|
3873
|
+
}
|
|
3874
|
+
console.log(` \u53D1\u5E03\u6A21\u5F0F \uFF1A${formatPublishMode(item.publishMode, item.publishAt)}`);
|
|
3875
|
+
console.log(` \u5C01\u9762 URL \uFF1A${item.cover?.imageUrl || "\u26A0\uFE0F \u672A\u8BBE\u7F6E"}`);
|
|
3876
|
+
if (item.cover?.sourceImageId) {
|
|
3877
|
+
console.log(` \u5C01\u9762 ID \uFF1A${item.cover.sourceImageId}`);
|
|
3878
|
+
}
|
|
3879
|
+
const byPlatform = /* @__PURE__ */ new Map();
|
|
3880
|
+
for (const acc of item.accounts ?? []) {
|
|
3881
|
+
const list = byPlatform.get(acc.mediaAccountType) ?? [];
|
|
3882
|
+
list.push(acc);
|
|
3883
|
+
byPlatform.set(acc.mediaAccountType, list);
|
|
3884
|
+
}
|
|
3885
|
+
const totalAccounts = item.accounts?.length ?? 0;
|
|
3886
|
+
console.log(`
|
|
3887
|
+
\u8D26\u53F7\uFF08${totalAccounts} \u4E2A\uFF0C${byPlatform.size} \u4E2A\u5E73\u53F0\uFF09\uFF1A`);
|
|
3888
|
+
for (const [platform, accounts] of byPlatform) {
|
|
3889
|
+
const override = item.platformOverrides?.[platform];
|
|
3890
|
+
console.log(`
|
|
3891
|
+
\u25AA ${platform}`);
|
|
3892
|
+
if (override) {
|
|
3893
|
+
const pt = buildPublishTitle(item, platform, override);
|
|
3894
|
+
if (override.title) console.log(` \u6807\u9898\u8986\u76D6 \uFF1A${pt.title}`);
|
|
3895
|
+
if (override.description) console.log(` \u63CF\u8FF0\u8986\u76D6 \uFF1A${pt.description}`);
|
|
3896
|
+
const ovTopics = formatTopics(override.topics);
|
|
3897
|
+
if (ovTopics) console.log(` \u6807\u7B7E\u8986\u76D6 \uFF1A${ovTopics}`);
|
|
3898
|
+
}
|
|
3899
|
+
for (const acc of accounts) {
|
|
3900
|
+
console.log(` \xB7 ${acc.mediaCustomerName}\uFF08${acc.mediaCustomerId}\uFF09`);
|
|
3901
|
+
}
|
|
3902
|
+
}
|
|
3903
|
+
}
|
|
3904
|
+
console.log(`
|
|
3905
|
+
${SEP}`);
|
|
3906
|
+
} else {
|
|
3907
|
+
const items = input.posts;
|
|
3908
|
+
console.log(`\u56FE\u6587\u6570\u91CF \uFF1A${items.length} \u4E2A`);
|
|
3909
|
+
for (let i = 0; i < items.length; i++) {
|
|
3910
|
+
const item = items[i];
|
|
3911
|
+
console.log(`
|
|
3912
|
+
${SEP}`);
|
|
3913
|
+
console.log(` \u56FE\u6587 ${i + 1} / ${items.length}`);
|
|
3914
|
+
console.log(SEP);
|
|
3915
|
+
console.log(` \u6807\u9898 \uFF1A${item.title || "\u26A0\uFE0F \u672A\u586B\u5199"}`);
|
|
3916
|
+
if (item.description) {
|
|
3917
|
+
console.log(` \u63CF\u8FF0 \uFF1A${item.description}`);
|
|
3918
|
+
}
|
|
3919
|
+
const topicsStr = formatTopics(item.topics);
|
|
3920
|
+
if (topicsStr) {
|
|
3921
|
+
console.log(` \u6807\u7B7E \uFF1A${topicsStr}`);
|
|
3922
|
+
}
|
|
3923
|
+
console.log(` \u56FE\u7247\u6570\u91CF \uFF1A${item.images?.length ?? 0} \u5F20`);
|
|
3924
|
+
console.log(` \u53D1\u5E03\u6A21\u5F0F \uFF1A${formatPublishMode(item.publishMode, item.publishAt)}`);
|
|
3925
|
+
const byPlatform = /* @__PURE__ */ new Map();
|
|
3926
|
+
for (const acc of item.accounts ?? []) {
|
|
3927
|
+
const list = byPlatform.get(acc.mediaAccountType) ?? [];
|
|
3928
|
+
list.push(acc);
|
|
3929
|
+
byPlatform.set(acc.mediaAccountType, list);
|
|
3930
|
+
}
|
|
3931
|
+
const totalAccounts = item.accounts?.length ?? 0;
|
|
3932
|
+
console.log(`
|
|
3933
|
+
\u8D26\u53F7\uFF08${totalAccounts} \u4E2A\uFF0C${byPlatform.size} \u4E2A\u5E73\u53F0\uFF09\uFF1A`);
|
|
3934
|
+
for (const [platform, accounts] of byPlatform) {
|
|
3935
|
+
const override = item.platformOverrides?.[platform];
|
|
3936
|
+
console.log(`
|
|
3937
|
+
\u25AA ${platform}`);
|
|
3938
|
+
if (override) {
|
|
3939
|
+
const pt = buildPublishTitle(item, platform, override, true);
|
|
3940
|
+
if (override.title) console.log(` \u6807\u9898\u8986\u76D6 \uFF1A${pt.title}`);
|
|
3941
|
+
if (override.description) console.log(` \u63CF\u8FF0\u8986\u76D6 \uFF1A${pt.description}`);
|
|
3942
|
+
const ovTopics = formatTopics(override.topics);
|
|
3943
|
+
if (ovTopics) console.log(` \u6807\u7B7E\u8986\u76D6 \uFF1A${ovTopics}`);
|
|
3944
|
+
}
|
|
3945
|
+
for (const acc of accounts) {
|
|
3946
|
+
console.log(` \xB7 ${acc.mediaCustomerName}\uFF08${acc.mediaCustomerId}\uFF09`);
|
|
3947
|
+
}
|
|
3948
|
+
}
|
|
3949
|
+
}
|
|
3950
|
+
console.log(`
|
|
3951
|
+
${SEP}`);
|
|
3952
|
+
}
|
|
3953
|
+
if (verbose) {
|
|
3954
|
+
const verboseBody = { ...body, contents: JSON.parse(body.contents) };
|
|
3955
|
+
console.log("\n\u5B8C\u6574 JSON \u8BF7\u6C42\u4F53\uFF08--verbose\uFF0Ccontents \u5DF2\u5C55\u5F00\uFF09\uFF1A\n");
|
|
3956
|
+
console.log(JSON.stringify(verboseBody, null, 2));
|
|
3957
|
+
} else {
|
|
3958
|
+
console.log("\n\u2139\uFE0F \u52A0 --verbose \u53C2\u6570\u53EF\u67E5\u770B\u5B8C\u6574 JSON \u8BF7\u6C42\u4F53\u3002");
|
|
3959
|
+
}
|
|
3960
|
+
}
|
|
3780
3961
|
async function runPublish(options) {
|
|
3781
3962
|
const configPath = path6.resolve(options.config);
|
|
3782
3963
|
if (!fs6.existsSync(configPath)) {
|
|
@@ -3840,24 +4021,7 @@ async function runPublish(options) {
|
|
|
3840
4021
|
version: "v3"
|
|
3841
4022
|
};
|
|
3842
4023
|
if (options.dryRun) {
|
|
3843
|
-
|
|
3844
|
-
if (options.verbose) {
|
|
3845
|
-
console.log(JSON.stringify(body, null, 2));
|
|
3846
|
-
} else {
|
|
3847
|
-
const redacted = {
|
|
3848
|
-
...body,
|
|
3849
|
-
uniqueActionId: "[\u5DF2\u9690\u85CF\uFF0C\u52A0 --verbose \u67E5\u770B]",
|
|
3850
|
-
channels: body.channels.map((ch) => ({
|
|
3851
|
-
...ch,
|
|
3852
|
-
mediaAccountInfos: ch.mediaAccountInfos.map((acc) => ({
|
|
3853
|
-
...acc,
|
|
3854
|
-
externalMediaAccountTokenId: `${acc.externalMediaAccountTokenId.slice(0, 4)}****`
|
|
3855
|
-
}))
|
|
3856
|
-
}))
|
|
3857
|
-
};
|
|
3858
|
-
console.log(JSON.stringify(redacted, null, 2));
|
|
3859
|
-
console.log("\n\u26A0\uFE0F \u90E8\u5206\u5B57\u6BB5\u5DF2\u8131\u654F\uFF0C\u52A0 --verbose \u53C2\u6570\u67E5\u770B\u5B8C\u6574\u8BF7\u6C42\u4F53\u3002");
|
|
3860
|
-
}
|
|
4024
|
+
printDryRun(input, taskName, isDomestic, body, options.verbose);
|
|
3861
4025
|
return;
|
|
3862
4026
|
}
|
|
3863
4027
|
console.log(`
|
|
@@ -5633,27 +5797,29 @@ async function runTaskDetail(options) {
|
|
|
5633
5797
|
console.log(JSON.stringify({ publishId: options.publishId, page, size, ...data }, null, 2));
|
|
5634
5798
|
return;
|
|
5635
5799
|
}
|
|
5800
|
+
const groupSummary = Array.isArray(data.publishGroupCounts) && data.publishGroupCounts.length > 0 ? " " + data.publishGroupCounts.map((g) => `${g.mediaType}\xD7${g.publishCount}`).join(" ") : "";
|
|
5636
5801
|
console.log(`
|
|
5637
|
-
\u4EFB\u52A1\u8BE6\u60C5\uFF08publishId=${options.publishId}\uFF0C\u603B\u53D1\u5E03\u9879 ${data.totalPublishCount ?? 0}\uFF09
|
|
5802
|
+
\u4EFB\u52A1\u8BE6\u60C5\uFF08publishId=${options.publishId}\uFF0C\u603B\u53D1\u5E03\u9879 ${data.totalPublishCount ?? 0}\uFF09${groupSummary ? `
|
|
5803
|
+
\u5404\u5E73\u53F0\uFF1A${groupSummary}` : ""}\uFF1A`);
|
|
5638
5804
|
if (list.length === 0) {
|
|
5639
5805
|
console.log(" \u5F53\u524D\u9875\u6682\u65E0\u53D1\u5E03\u9879\u3002\n");
|
|
5640
5806
|
return;
|
|
5641
5807
|
}
|
|
5642
5808
|
const columns = [
|
|
5643
|
-
{ key: "id", header: "\u53D1\u5E03\u9879ID" },
|
|
5644
5809
|
{ key: "mediaType", header: "\u5A92\u4F53" },
|
|
5645
5810
|
{ key: "account", header: "\u8D26\u53F7" },
|
|
5811
|
+
{ key: "title", header: "\u6807\u9898" },
|
|
5646
5812
|
{ key: "status", header: "\u72B6\u6001" },
|
|
5647
|
-
{ key: "
|
|
5648
|
-
{ key: "
|
|
5813
|
+
{ key: "publishTime", header: "\u53D1\u5E03\u65F6\u95F4" },
|
|
5814
|
+
{ key: "remark", header: "\u5907\u6CE8/\u5931\u8D25\u539F\u56E0" }
|
|
5649
5815
|
];
|
|
5650
5816
|
const rows = list.map((item) => ({
|
|
5651
|
-
id: String(item.id ?? "-"),
|
|
5652
5817
|
mediaType: String(item.mediaType ?? "-"),
|
|
5653
5818
|
account: String(item.mediaCustomerName ?? item.mediaCustomerId ?? "-"),
|
|
5819
|
+
title: item.title ? item.title.length > 20 ? item.title.slice(0, 20) + "\u2026" : item.title : "-",
|
|
5654
5820
|
status: itemStatusLabel(typeof item.videoStatus === "number" ? item.videoStatus : void 0),
|
|
5655
|
-
|
|
5656
|
-
|
|
5821
|
+
publishTime: item.publishTime ? typeof item.publishTime === "number" ? new Date(item.publishTime * 1e3).toLocaleString("zh-CN") : String(item.publishTime) : "-",
|
|
5822
|
+
remark: item.remark ? item.remark.length > 30 ? item.remark.slice(0, 30) + "\u2026" : item.remark : "-"
|
|
5657
5823
|
}));
|
|
5658
5824
|
printCliTable(rows, columns, tableOpts(options.unicode));
|
|
5659
5825
|
console.log();
|
|
@@ -5783,6 +5949,35 @@ async function runTaskCommentList(options) {
|
|
|
5783
5949
|
console.log();
|
|
5784
5950
|
}
|
|
5785
5951
|
|
|
5952
|
+
// src/commands/authorize.ts
|
|
5953
|
+
import { exec } from "child_process";
|
|
5954
|
+
function openBrowser(url) {
|
|
5955
|
+
const platform = process.platform;
|
|
5956
|
+
let cmd;
|
|
5957
|
+
if (platform === "win32") cmd = `start "" "${url}"`;
|
|
5958
|
+
else if (platform === "darwin") cmd = `open "${url}"`;
|
|
5959
|
+
else cmd = `xdg-open "${url}"`;
|
|
5960
|
+
exec(cmd);
|
|
5961
|
+
}
|
|
5962
|
+
async function runAuthorize(opts) {
|
|
5963
|
+
const config = loadConfig(opts.token);
|
|
5964
|
+
const tradeSegment = opts.domestic ? "domestic_trade" : "foreign_trade";
|
|
5965
|
+
const returnUrl = `${DEFAULT_WEB_BASE}/v3/${tradeSegment}/cso/ManageAccounts`;
|
|
5966
|
+
const url = `${config.apiBaseUrl}/command/media-account/link/${encodeURIComponent(opts.mediaType)}?returnUrl=${encodeURIComponent(returnUrl)}`;
|
|
5967
|
+
let redirectUrl;
|
|
5968
|
+
try {
|
|
5969
|
+
const data = await apiFetch2(url, config, {}, opts.verbose);
|
|
5970
|
+
redirectUrl = data.redirectUrl;
|
|
5971
|
+
} catch {
|
|
5972
|
+
process.exit(1);
|
|
5973
|
+
}
|
|
5974
|
+
console.log(`\u6B63\u5728\u6253\u5F00 ${opts.mediaType} \u6388\u6743\u9875\u9762...`);
|
|
5975
|
+
console.log(`\u6388\u6743\u94FE\u63A5\uFF1A${redirectUrl}`);
|
|
5976
|
+
openBrowser(redirectUrl);
|
|
5977
|
+
console.log(`
|
|
5978
|
+
\u8BF7\u5728\u6D4F\u89C8\u5668\u4E2D\u5B8C\u6210\u6388\u6743\u3002\u6388\u6743\u6210\u529F\u540E\uFF0C\u9875\u9762\u5C06\u81EA\u52A8\u8DF3\u56DE\u4E1D\u8DEF\u8D5E\u8D26\u53F7\u7BA1\u7406\u9875\u9762\u3002`);
|
|
5979
|
+
}
|
|
5980
|
+
|
|
5786
5981
|
// src/commands/config.ts
|
|
5787
5982
|
import * as fs10 from "fs";
|
|
5788
5983
|
function cmdConfigShow() {
|
|
@@ -5797,7 +5992,6 @@ function cmdConfigShow() {
|
|
|
5797
5992
|
const csoBaseUrl = DEFAULT_CSO_BASE;
|
|
5798
5993
|
const apiKey = shared.apiKey ?? "";
|
|
5799
5994
|
console.log("\n\u5F53\u524D\u914D\u7F6E\uFF08~/.siluzan/config.json\uFF09\uFF1A");
|
|
5800
|
-
console.log(` \u6784\u5EFA\u73AF\u5883 : ${BUILD_ENV}`);
|
|
5801
5995
|
console.log(` apiBaseUrl : ${apiBaseUrl}`);
|
|
5802
5996
|
console.log(` csoBaseUrl : ${csoBaseUrl}`);
|
|
5803
5997
|
if (apiKey) {
|
|
@@ -5879,7 +6073,10 @@ program.command("init").description("\u5C06 Skill \u6587\u4EF6\u5199\u5165\u6307
|
|
|
5879
6073
|
apiBaseUrl: opts.apiBase ?? "https://api.siluzan.com"
|
|
5880
6074
|
});
|
|
5881
6075
|
});
|
|
5882
|
-
program.command("
|
|
6076
|
+
program.command("authorize").description("\u53D1\u8D77\u5916\u8D38\u5A92\u4F53\u5E73\u53F0 OAuth \u6388\u6743\uFF08YouTube/TikTok/Instagram/Facebook/LinkedIn \u7B49\uFF09\uFF0C\u5728\u6D4F\u89C8\u5668\u4E2D\u5B8C\u6210\u6388\u6743\u540E\u8DF3\u56DE\u4E1D\u8DEF\u8D5E\u8D26\u53F7\u7BA1\u7406\u9875").requiredOption("--media-type <type>", "\u5A92\u4F53\u5E73\u53F0\u7C7B\u578B\uFF0C\u5982 YouTube / TikTok / Instagram / Facebook / LinkedIn").option("--domestic", "\u5185\u8D38\u6A21\u5F0F\uFF0C\u6388\u6743\u5B8C\u6210\u540E\u8DF3\u56DE\u5185\u8D38\u8D26\u53F7\u7BA1\u7406\u9875\uFF08\u9ED8\u8BA4\u5916\u8D38\uFF09", false).option("-t, --token <token>", "Token\uFF08\u53EF\u9009\uFF1B\u4F18\u5148\u4E8E ~/.siluzan/config.json\uFF09").option("--verbose", "\u663E\u793A\u8BE6\u7EC6\u9519\u8BEF\u4FE1\u606F", false).action(async (opts) => {
|
|
6077
|
+
await runAuthorize(opts);
|
|
6078
|
+
});
|
|
6079
|
+
program.command("list-accounts").description("\u5217\u51FA\u5A92\u4F53\u8D26\u53F7\u5217\u8868\uFF0C\u9ED8\u8BA4\u5C55\u793A\u7C89\u4E1D\u6570/\u4F5C\u54C1\u6570/\u64AD\u653E\u6570\u7B49\u6570\u636E\u603B\u89C8\uFF1B\u652F\u6301\u5206\u9875\u3001\u5E73\u53F0/\u540D\u79F0/\u72B6\u6001/\u8D1F\u8D23\u4EBA\u8FC7\u6EE4").option("--domestic", "\u5185\u8D38\u6A21\u5F0F\uFF08mediaGroup=1\uFF09\uFF0C\u9ED8\u8BA4\u5916\u8D38", false).option("--name <name>", "\u6309\u8D26\u53F7\u540D\u79F0\u6A21\u7CCA\u641C\u7D22").option("--media-type <type>", "\u6309\u5E73\u53F0\u7C7B\u578B\u8FC7\u6EE4\uFF08\u5982 \u6296\u97F3\u3001YouTube\u3001TikTok \u7B49\uFF09").option("--state <state>", "\u6309\u72B6\u6001\u8FC7\u6EE4\uFF1Aall\uFF08\u5168\u90E8\uFF09| normal\uFF08\u6B63\u5E38\uFF09| abnormal\uFF08\u5F02\u5E38/\u8FC7\u671F\uFF09\uFF0C\u9ED8\u8BA4 all", "all").option("--owner <owner>", "\u6309\u8D1F\u8D23\u4EBA\u8FC7\u6EE4\uFF08\u4F20\u5165\u7528\u6237 ID\uFF0C\u53EF\u4ECE --json \u8FD4\u56DE\u7684 ownerInfo[].id \u5B57\u6BB5\u83B7\u53D6\uFF09").option("--page <n>", "\u9875\u7801\uFF08\u9ED8\u8BA4 1\uFF09", "1").option("--page-size <n>", "\u6BCF\u9875\u6761\u6570\uFF08\u9ED8\u8BA4 20\uFF09", "20").option("--no-overview", "\u5173\u95ED\u603B\u89C8\u6A21\u5F0F\uFF0C\u6539\u4E3A\u5C55\u793A\u57FA\u7840\u8D26\u53F7\u4FE1\u606F\uFF08\u8D26\u53F7ID/\u6388\u6743\u72B6\u6001/Token\u5230\u671F\u7B49\uFF09").option("--json", "\u4EE5 JSON \u8F93\u51FA\u8D26\u53F7\u5217\u8868\uFF08\u542B\u603B\u89C8\u6570\u636E\uFF0C\u7528\u4E8E\u811A\u672C\u6216\u914D\u7F6E\u6587\u4EF6\uFF09", false).option("--unicode", "\u4F7F\u7528 Unicode \u7EBF\u6846\u8868\u683C\uFF08\u9ED8\u8BA4 ASCII +-|\uFF09", false).option("--verbose", "\u663E\u793A\u5B8C\u6574\u4EE4\u724C\u6807\u8BC6\uFF08\u9ED8\u8BA4\u8131\u654F\uFF09", false).action(async (opts) => {
|
|
5883
6080
|
const state = opts.state;
|
|
5884
6081
|
await runListAccounts({
|
|
5885
6082
|
token: opts.token,
|
package/dist/skill/SKILL.md
CHANGED
|
@@ -14,9 +14,9 @@ description_en: >-
|
|
|
14
14
|
|------|------|
|
|
15
15
|
| `siluzan-cso login` | **首次使用:交互引导登录并保存 Token(推荐,Token 不进入 shell history)** |
|
|
16
16
|
| `siluzan-cso config show` | 查看当前保存的配置 |
|
|
17
|
-
| `siluzan-cso list-accounts` |
|
|
18
|
-
| `siluzan-cso list-accounts --
|
|
19
|
-
| `siluzan-cso list-accounts --media-type
|
|
17
|
+
| `siluzan-cso list-accounts` | 列出所有可用媒体账号(按平台分组,默认展示数据总览) |
|
|
18
|
+
| `siluzan-cso list-accounts --name <名称> --media-type <平台> --json` | **精准获取单个账号完整信息(entityId / mediaCustomerId / Token 等)** |
|
|
19
|
+
| `siluzan-cso list-accounts --media-type <平台>` | 按平台筛选账号 |
|
|
20
20
|
| `siluzan-cso report fetch --media <平台>` | 拉取指定平台的运营报表(核心指标 + 视频排行) |
|
|
21
21
|
| `siluzan-cso report fetch --media <平台> --maids <账号ID>` | 查指定账号的运营数据 |
|
|
22
22
|
| `siluzan-cso report fetch --media <平台> --days <N>` | 查近 N 天数据(默认 30 天) |
|
|
@@ -78,12 +78,13 @@ AI 需根据当前日期自动推算"明天"、"后天"等相对时间,转换
|
|
|
78
78
|
|
|
79
79
|
| 用户问 | 应使用命令 |
|
|
80
80
|
|--------|-----------|
|
|
81
|
-
|
|
|
82
|
-
|
|
|
81
|
+
| 帮我找一下 xxx 这个账号 / 获取账号 ID | `list-accounts --name <名称> --media-type <平台> --json` |
|
|
82
|
+
| 看所有账号对比/账号层面数据 | `list-accounts`(默认总览模式) |
|
|
83
|
+
| 只看某平台(如 TikTok)的账号 | `list-accounts --media-type TikTokBusinessAccount` |
|
|
83
84
|
| 某个账号最近表现 | `report fetch --media <平台> --maids <账号ID>` |
|
|
84
85
|
| 近 30 天 / 近 N 天 | `report fetch --media <平台> --days <N>` |
|
|
85
86
|
| 哪条视频/作品最好 | `report fetch --media <平台> --include works --order play` |
|
|
86
|
-
| 按账号和平台分别看 | 逐个调用 `report fetch --maids <id>`,或先用 `list-accounts
|
|
87
|
+
| 按账号和平台分别看 | 逐个调用 `report fetch --maids <id>`,或先用 `list-accounts` |
|
|
87
88
|
|
|
88
89
|
**平台名称速查(--media / --media-type 参数):**
|
|
89
90
|
`Douyin`(抖音)· `TikTokBusinessAccount`(TikTok)· `YouTube` · `Wechat`(视频号)· `Instagram` · `Facebook` · `Twitter`
|
package/dist/skill/_meta.json
CHANGED
|
@@ -15,6 +15,7 @@
|
|
|
15
15
|
"imageUrl": "https://cdn.example.com/img1.jpg",
|
|
16
16
|
"imageName": "img1.jpg",
|
|
17
17
|
"imageSourceType": 1,
|
|
18
|
+
"sourceImageId": "xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx",
|
|
18
19
|
"width": 1080,
|
|
19
20
|
"height": 1080
|
|
20
21
|
}
|
|
@@ -22,11 +23,11 @@
|
|
|
22
23
|
|
|
23
24
|
"accounts": [
|
|
24
25
|
{
|
|
25
|
-
"entityId": "
|
|
26
|
+
"entityId": "xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx",
|
|
26
27
|
"mediaAccountType": "Instagram",
|
|
27
|
-
"mediaCustomerId": "
|
|
28
|
+
"mediaCustomerId": "平台账号ID(非UUID)",
|
|
28
29
|
"mediaCustomerName": "我的 Instagram",
|
|
29
|
-
"externalMediaAccountTokenId": ""
|
|
30
|
+
"externalMediaAccountTokenId": "xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx"
|
|
30
31
|
}
|
|
31
32
|
],
|
|
32
33
|
|
|
@@ -6,7 +6,7 @@
|
|
|
6
6
|
|
|
7
7
|
"videos": [
|
|
8
8
|
{
|
|
9
|
-
"videoId": "
|
|
9
|
+
"videoId": "xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx",
|
|
10
10
|
"videoUrl": "https://cdn.example.com/video.mp4",
|
|
11
11
|
"videoName": "视频文件名.mp4",
|
|
12
12
|
"isMaterialCenter": true,
|
|
@@ -21,23 +21,24 @@
|
|
|
21
21
|
"cover": {
|
|
22
22
|
"imageUrl": "https://cdn.example.com/cover.jpg",
|
|
23
23
|
"imageName": "cover.jpg",
|
|
24
|
-
"imageSourceType": 1
|
|
24
|
+
"imageSourceType": 1,
|
|
25
|
+
"sourceImageId": "xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx"
|
|
25
26
|
},
|
|
26
27
|
|
|
27
28
|
"accounts": [
|
|
28
29
|
{
|
|
29
|
-
"entityId": "
|
|
30
|
+
"entityId": "xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx",
|
|
30
31
|
"mediaAccountType": "Douyin",
|
|
31
|
-
"mediaCustomerId": "
|
|
32
|
+
"mediaCustomerId": "抖音平台账号ID(非UUID,如数字字符串)",
|
|
32
33
|
"mediaCustomerName": "我的抖音账号",
|
|
33
|
-
"externalMediaAccountTokenId": ""
|
|
34
|
+
"externalMediaAccountTokenId": "xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx"
|
|
34
35
|
},
|
|
35
36
|
{
|
|
36
|
-
"entityId": "
|
|
37
|
+
"entityId": "xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx",
|
|
37
38
|
"mediaAccountType": "YouTube",
|
|
38
|
-
"mediaCustomerId": "
|
|
39
|
+
"mediaCustomerId": "YouTube频道ID(非UUID,如UCxxx)",
|
|
39
40
|
"mediaCustomerName": "我的 YouTube 频道",
|
|
40
|
-
"externalMediaAccountTokenId": ""
|
|
41
|
+
"externalMediaAccountTokenId": "xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx"
|
|
41
42
|
}
|
|
42
43
|
],
|
|
43
44
|
|
|
@@ -37,6 +37,47 @@
|
|
|
37
37
|
|
|
38
38
|
---
|
|
39
39
|
|
|
40
|
+
## 场景零:精准获取某一个账号的完整信息
|
|
41
|
+
|
|
42
|
+
**用户问**:"帮我查一下这个账号的信息"、"我想获取 xxx 账号的 ID"、"帮我找一下这个 YouTube 频道的账号信息"
|
|
43
|
+
|
|
44
|
+
### 推荐方式:名称 + 平台组合过滤
|
|
45
|
+
|
|
46
|
+
```bash
|
|
47
|
+
# 精确定位单个账号:同时传 --name(名称模糊搜索)和 --media-type(平台),加 --json 获取完整字段
|
|
48
|
+
siluzan-cso list-accounts --name "账号名" --media-type YouTube --json
|
|
49
|
+
|
|
50
|
+
# 只知道名称、不确定平台时,先不传 --media-type
|
|
51
|
+
siluzan-cso list-accounts --name "账号名" --json
|
|
52
|
+
|
|
53
|
+
# 只知道平台时,列出该平台所有账号
|
|
54
|
+
siluzan-cso list-accounts --media-type TikTokBusinessAccount --json
|
|
55
|
+
```
|
|
56
|
+
|
|
57
|
+
### JSON 输出中各字段的用途
|
|
58
|
+
|
|
59
|
+
| 字段 | 用途 |
|
|
60
|
+
|------|------|
|
|
61
|
+
| `entityId` | 发布配置 `accounts[].entityId` 的值 |
|
|
62
|
+
| `mediaCustomerId` | `report fetch --maids <id>` 的参数 |
|
|
63
|
+
| `mediaAccountType` | 发布配置 `accounts[].mediaAccountType`、`--media-type` 参数 |
|
|
64
|
+
| `mediaCustomerName` | 发布配置 `accounts[].mediaCustomerName` |
|
|
65
|
+
| `externalMediaAccountTokenId` | 发布配置 `accounts[].externalMediaAccountTokenId` |
|
|
66
|
+
| `invalidOAuthToken` | `true` 表示 Token 已失效,需要重新授权 |
|
|
67
|
+
| `expiresOn` | Token 到期时间 |
|
|
68
|
+
| `overview.fansCount` | 当前粉丝数 |
|
|
69
|
+
| `overview.videoCount` | 发布作品总数 |
|
|
70
|
+
| `overview.playCount` | 历史总播放数 |
|
|
71
|
+
|
|
72
|
+
### AI 行为规则
|
|
73
|
+
|
|
74
|
+
- 用户要找一个具体账号时,**优先用 `--name` + `--media-type` 双重过滤**,通常可直接得到唯一结果,无需让用户翻页。
|
|
75
|
+
- 如果用户只说了账号名称(没说平台),先不加 `--media-type`,看结果是否唯一;不唯一时再让用户确认平台。
|
|
76
|
+
- `--json` 返回的 `entityId` + `externalMediaAccountTokenId` + `mediaCustomerId` 是构造发布配置 `accounts[]` 所需的全部字段,**找到账号后可以直接填入发布配置,不必再多问用户**。
|
|
77
|
+
- 账号的 `overview` 字段就是概览数据(粉丝数/播放数等),找到账号后无需再单独调用 `report fetch` 就能回答粉丝数之类的基本问题。
|
|
78
|
+
|
|
79
|
+
---
|
|
80
|
+
|
|
40
81
|
## 场景一:查所有账号的数据对比
|
|
41
82
|
|
|
42
83
|
**用户问**:"能不能看所有账号的对比?"、"不同账号谁表现更好?"、"账号层面的数据在哪里看?"
|
|
@@ -185,6 +185,21 @@ AI 可以直接根据以下方向帮助润色:
|
|
|
185
185
|
- **视频配置文件结构:**
|
|
186
186
|
请阅读:`assets/publish-config.example.json`
|
|
187
187
|
|
|
188
|
+
**⚠️ UUID 字段必须用真实值,不能用占位符文本**
|
|
189
|
+
|
|
190
|
+
以下字段后端会做严格的 GUID 格式校验,填写错误将导致 HTTP 500 报错:
|
|
191
|
+
|
|
192
|
+
| 字段 | 来源 | 格式示例 |
|
|
193
|
+
|------|------|---------|
|
|
194
|
+
| `accounts[].entityId` | `list-accounts --json` 的 `entityId` 字段 | `xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx` |
|
|
195
|
+
| `accounts[].externalMediaAccountTokenId` | `list-accounts --json` 的 `externalMediaAccountTokenId` 字段 | `xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx` |
|
|
196
|
+
| `videos[].videoId` | `upload` 命令返回的 `videoId`,或素材库中的 UUID | `xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx` |
|
|
197
|
+
| `cover.sourceImageId` | `upload` 命令返回的 `sourceImageId` | `xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx` |
|
|
198
|
+
|
|
199
|
+
> **注意**:`mediaCustomerId` 不是 UUID,是各平台的账号 ID(如抖音的数字 ID、YouTube 的 UC 开头字符串),可以直接填写。
|
|
200
|
+
|
|
201
|
+
CLI 会在提交前校验所有 UUID 字段,如有非法值会给出明确错误提示,告知哪个账号的哪个字段需要修正。
|
|
202
|
+
|
|
188
203
|
根据用户确认的信息,生成 `publish-config.json`,然后先预览:
|
|
189
204
|
|
|
190
205
|
```bash
|
package/package.json
CHANGED