siluzan-tso-cli 1.1.33-beta.1 → 1.1.33-beta.2
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 +151 -59
- package/dist/skill/_meta.json +2 -2
- package/dist/skill/references/accounts/accounts.md +39 -5
- package/dist/skill/references/core/agent-conventions.md +1 -1
- package/dist/skill/references/core/workflows.md +2 -1
- package/dist/skill/references/report-templates/bing-period-report.md +1 -0
- package/dist/skill/report-templates/bing-period-report.md +1 -0
- package/dist/skill/scripts/install.ps1 +1 -1
- package/dist/skill/scripts/install.sh +1 -1
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -51,7 +51,7 @@ siluzan-tso init -d /path/to/skills # 写入自定义目录
|
|
|
51
51
|
siluzan-tso init --force # 强制覆盖已存在文件
|
|
52
52
|
```
|
|
53
53
|
|
|
54
|
-
> **注意**:当前为测试版(1.1.33-beta.
|
|
54
|
+
> **注意**:当前为测试版(1.1.33-beta.2),供内部测试使用。正式发布后安装命令将改为 `npm install -g siluzan-tso-cli`。
|
|
55
55
|
|
|
56
56
|
| 助手 | 建议 `--ai` |
|
|
57
57
|
| ----------------------- | ------------------------------------ |
|
package/dist/index.js
CHANGED
|
@@ -4329,6 +4329,44 @@ function groupAccountIdsByOverviewRoute(cliMedia, accountIds, accountMediaTypes)
|
|
|
4329
4329
|
}
|
|
4330
4330
|
return groups;
|
|
4331
4331
|
}
|
|
4332
|
+
function routeToBalanceMedia(route) {
|
|
4333
|
+
if (route === "FacebookAds") return "MetaAd";
|
|
4334
|
+
if (BALANCE_SUPPORTED_MEDIA.includes(route)) {
|
|
4335
|
+
return route;
|
|
4336
|
+
}
|
|
4337
|
+
return null;
|
|
4338
|
+
}
|
|
4339
|
+
function applyRealtimeBalanceIfNeeded(item, bal) {
|
|
4340
|
+
if (bal == null || typeof bal.remainingAccountBudget !== "number") return;
|
|
4341
|
+
if (bal.remainingAccountBudget > 0) {
|
|
4342
|
+
item.remainingAccountBudget = bal.remainingAccountBudget;
|
|
4343
|
+
}
|
|
4344
|
+
if (bal.currencyCode) item.currencyCode = bal.currencyCode;
|
|
4345
|
+
if (bal.status) item.status = bal.status;
|
|
4346
|
+
}
|
|
4347
|
+
async function overlayRealtimeBalanceOnOverviewMap(route, overviewMap, config, verbose) {
|
|
4348
|
+
const media = routeToBalanceMedia(route);
|
|
4349
|
+
if (!media || overviewMap.size === 0) return;
|
|
4350
|
+
const ids = [...overviewMap.keys()];
|
|
4351
|
+
const balanceMap = await fetchBalanceMap(media, ids, config, void 0, void 0, verbose);
|
|
4352
|
+
for (const [id, item] of overviewMap) {
|
|
4353
|
+
applyRealtimeBalanceIfNeeded(item, balanceMap.get(id));
|
|
4354
|
+
}
|
|
4355
|
+
}
|
|
4356
|
+
async function enrichOverviewRecordWithRealtimeBalance(media, accountId, config, record, verbose) {
|
|
4357
|
+
if (!BALANCE_SUPPORTED_MEDIA.includes(media)) {
|
|
4358
|
+
return record;
|
|
4359
|
+
}
|
|
4360
|
+
const balanceMap = await fetchBalanceMap(media, [accountId], config, void 0, void 0, verbose);
|
|
4361
|
+
const bal = balanceMap.get(accountId);
|
|
4362
|
+
if (bal == null) return record;
|
|
4363
|
+
const out = { ...record };
|
|
4364
|
+
applyRealtimeBalanceIfNeeded(out, bal);
|
|
4365
|
+
if (bal.name && out["accountName"] == null && out["mediaCustomerName"] == null) {
|
|
4366
|
+
out["mediaCustomerName"] = bal.name;
|
|
4367
|
+
}
|
|
4368
|
+
return out;
|
|
4369
|
+
}
|
|
4332
4370
|
async function fetchBalanceMap(media, accountIds, config, startDate, endDate, verbose) {
|
|
4333
4371
|
const result = /* @__PURE__ */ new Map();
|
|
4334
4372
|
if (accountIds.length === 0) return result;
|
|
@@ -4462,70 +4500,73 @@ async function fetchOverviewMap(route, accountIds, config, startDate, endDate, v
|
|
|
4462
4500
|
for (const row of rows) {
|
|
4463
4501
|
result.set(row.mediaAccountId, row);
|
|
4464
4502
|
}
|
|
4465
|
-
|
|
4466
|
-
|
|
4467
|
-
|
|
4468
|
-
|
|
4469
|
-
|
|
4470
|
-
|
|
4471
|
-
|
|
4472
|
-
|
|
4473
|
-
|
|
4474
|
-
|
|
4475
|
-
|
|
4476
|
-
|
|
4477
|
-
|
|
4478
|
-
|
|
4479
|
-
|
|
4480
|
-
|
|
4503
|
+
} else {
|
|
4504
|
+
const fetchLegacyBatch = async (ids) => {
|
|
4505
|
+
const batch = /* @__PURE__ */ new Map();
|
|
4506
|
+
const params = new URLSearchParams({
|
|
4507
|
+
period: "true",
|
|
4508
|
+
startDate: start,
|
|
4509
|
+
endDate: end,
|
|
4510
|
+
mediaCustomerIds: ids.join(",")
|
|
4511
|
+
});
|
|
4512
|
+
const url = `${config.apiBaseUrl}/report/media-account/${route}/accountsoverview?${params}`;
|
|
4513
|
+
const raw = await apiFetch2(url, config, {}, verbose);
|
|
4514
|
+
const items = Array.isArray(raw) ? raw : [];
|
|
4515
|
+
for (const item of items) {
|
|
4516
|
+
if (item.mediaAccountId != null) {
|
|
4517
|
+
batch.set(String(item.mediaAccountId), item);
|
|
4518
|
+
}
|
|
4481
4519
|
}
|
|
4482
|
-
|
|
4483
|
-
|
|
4484
|
-
|
|
4485
|
-
|
|
4486
|
-
|
|
4487
|
-
|
|
4488
|
-
|
|
4489
|
-
|
|
4490
|
-
|
|
4491
|
-
|
|
4492
|
-
|
|
4493
|
-
|
|
4494
|
-
|
|
4495
|
-
|
|
4496
|
-
|
|
4497
|
-
|
|
4498
|
-
|
|
4499
|
-
|
|
4500
|
-
|
|
4501
|
-
process.stderr.write(
|
|
4502
|
-
`[fetchOverviewMap] \u9010\u6237\u91CD\u8BD5\u5931\u8D25 ${id}\uFF1A${singleErr instanceof Error ? singleErr.message : String(singleErr)}
|
|
4520
|
+
return batch;
|
|
4521
|
+
};
|
|
4522
|
+
const mergeOverview = (batch) => {
|
|
4523
|
+
for (const [k, v] of batch) result.set(k, v);
|
|
4524
|
+
};
|
|
4525
|
+
if (accountIds.length === 1) {
|
|
4526
|
+
mergeOverview(await fetchLegacyBatch(accountIds));
|
|
4527
|
+
} else {
|
|
4528
|
+
try {
|
|
4529
|
+
const batch = await fetchLegacyBatch(accountIds);
|
|
4530
|
+
mergeOverview(batch);
|
|
4531
|
+
if (batch.size === 0) {
|
|
4532
|
+
for (const id of accountIds) {
|
|
4533
|
+
try {
|
|
4534
|
+
mergeOverview(await fetchLegacyBatch([id]));
|
|
4535
|
+
} catch (singleErr) {
|
|
4536
|
+
if (verbose) {
|
|
4537
|
+
process.stderr.write(
|
|
4538
|
+
`[fetchOverviewMap] \u9010\u6237\u91CD\u8BD5\u5931\u8D25 ${id}\uFF1A${singleErr instanceof Error ? singleErr.message : String(singleErr)}
|
|
4503
4539
|
`
|
|
4504
|
-
|
|
4540
|
+
);
|
|
4541
|
+
}
|
|
4542
|
+
}
|
|
4505
4543
|
}
|
|
4506
4544
|
}
|
|
4507
|
-
}
|
|
4508
|
-
}
|
|
4509
|
-
} catch (err) {
|
|
4510
|
-
if (verbose) {
|
|
4511
|
-
process.stderr.write(
|
|
4512
|
-
`[fetchOverviewMap] \u6279\u91CF\u5F02\u5E38\uFF0C\u9010\u6237\u91CD\u8BD5\uFF1A${err instanceof Error ? err.message : String(err)}
|
|
4513
|
-
`
|
|
4514
|
-
);
|
|
4515
|
-
}
|
|
4516
|
-
for (const id of accountIds) {
|
|
4517
|
-
try {
|
|
4518
|
-
mergeOverview(await fetchLegacyBatch([id]));
|
|
4519
|
-
} catch (singleErr) {
|
|
4545
|
+
} catch (err) {
|
|
4520
4546
|
if (verbose) {
|
|
4521
4547
|
process.stderr.write(
|
|
4522
|
-
`[fetchOverviewMap] \u9010\u6237\u91CD\u8BD5\
|
|
4548
|
+
`[fetchOverviewMap] \u6279\u91CF\u5F02\u5E38\uFF0C\u9010\u6237\u91CD\u8BD5\uFF1A${err instanceof Error ? err.message : String(err)}
|
|
4523
4549
|
`
|
|
4524
4550
|
);
|
|
4525
4551
|
}
|
|
4552
|
+
for (const id of accountIds) {
|
|
4553
|
+
try {
|
|
4554
|
+
mergeOverview(await fetchLegacyBatch([id]));
|
|
4555
|
+
} catch (singleErr) {
|
|
4556
|
+
if (verbose) {
|
|
4557
|
+
process.stderr.write(
|
|
4558
|
+
`[fetchOverviewMap] \u9010\u6237\u91CD\u8BD5\u5931\u8D25 ${id}\uFF1A${singleErr instanceof Error ? singleErr.message : String(singleErr)}
|
|
4559
|
+
`
|
|
4560
|
+
);
|
|
4561
|
+
}
|
|
4562
|
+
}
|
|
4563
|
+
}
|
|
4526
4564
|
}
|
|
4527
4565
|
}
|
|
4528
4566
|
}
|
|
4567
|
+
if (result.size > 0) {
|
|
4568
|
+
await overlayRealtimeBalanceOnOverviewMap(route, result, config, verbose);
|
|
4569
|
+
}
|
|
4529
4570
|
} catch (err) {
|
|
4530
4571
|
if (verbose) {
|
|
4531
4572
|
process.stderr.write(
|
|
@@ -106210,11 +106251,15 @@ async function runStats(opts) {
|
|
|
106210
106251
|
}
|
|
106211
106252
|
}
|
|
106212
106253
|
} else {
|
|
106213
|
-
const
|
|
106214
|
-
|
|
106215
|
-
|
|
106216
|
-
|
|
106217
|
-
|
|
106254
|
+
const map = await fetchOverviewMap(
|
|
106255
|
+
opts.media,
|
|
106256
|
+
ids,
|
|
106257
|
+
config,
|
|
106258
|
+
startDate,
|
|
106259
|
+
endDate,
|
|
106260
|
+
opts.verbose
|
|
106261
|
+
);
|
|
106262
|
+
items = [...map.values()];
|
|
106218
106263
|
}
|
|
106219
106264
|
} catch (err) {
|
|
106220
106265
|
const message = err instanceof Error ? err.message : String(err);
|
|
@@ -107748,6 +107793,7 @@ async function fetchBingJson(config, url, verbose) {
|
|
|
107748
107793
|
|
|
107749
107794
|
// src/commands/report-bing-analysis/run.ts
|
|
107750
107795
|
init_auth();
|
|
107796
|
+
init_balance();
|
|
107751
107797
|
async function runReportBingOverview(opts) {
|
|
107752
107798
|
const id = assertBingAccountId(opts.account);
|
|
107753
107799
|
const { startDate, endDate } = resolveBingDateRange(opts.start, opts.end);
|
|
@@ -107755,7 +107801,14 @@ async function runReportBingOverview(opts) {
|
|
|
107755
107801
|
const params = new URLSearchParams({ startDate, endDate });
|
|
107756
107802
|
const url = reportingUrl2(config, id, "OverviewSectionData", params.toString());
|
|
107757
107803
|
try {
|
|
107758
|
-
const
|
|
107804
|
+
const raw = await fetchBingJson(config, url, !!opts.verbose);
|
|
107805
|
+
const data = raw && typeof raw === "object" && !Array.isArray(raw) ? await enrichOverviewRecordWithRealtimeBalance(
|
|
107806
|
+
"BingV2",
|
|
107807
|
+
id,
|
|
107808
|
+
config,
|
|
107809
|
+
raw,
|
|
107810
|
+
opts.verbose
|
|
107811
|
+
) : raw;
|
|
107759
107812
|
if (opts.jsonOut) {
|
|
107760
107813
|
await emitBingSnapshot(opts, "bing-overview", id, startDate, endDate, data);
|
|
107761
107814
|
return;
|
|
@@ -121000,6 +121053,27 @@ async function runAccountAuth(opts) {
|
|
|
121000
121053
|
tryOpenBrowser: tryOpenHttpsUrlInBrowser
|
|
121001
121054
|
});
|
|
121002
121055
|
}
|
|
121056
|
+
async function runAccountReauth(opts) {
|
|
121057
|
+
if (!opts.id && (!opts.ids || opts.ids.length === 0)) {
|
|
121058
|
+
console.error(
|
|
121059
|
+
"\n\u274C \u91CD\u65B0\u6388\u6743\u987B\u6307\u5B9A\u8981\u89E3\u7ED1\u7684\u8D26\u6237 entityId\uFF1A--id <entityId> \u6216 --ids id1,id2\n entityId \u6765\u81EA list-accounts --json-out \u7684 ma.entityId\uFF08\u4E0D\u662F mediaCustomerId\uFF09\n"
|
|
121060
|
+
);
|
|
121061
|
+
process.exit(1);
|
|
121062
|
+
}
|
|
121063
|
+
console.log("\n\u6B65\u9AA4 1/2\uFF1A\u65AD\u5F00\u5173\u8054\uFF08\u91CD\u65B0\u6388\u6743\u524D\u5FC5\u987B\u5148\u89E3\u7ED1\uFF0C\u5BF9\u9F50\u7F51\u9875\u300C\u91CD\u65B0\u6388\u6743\u300D\uFF09\u2026\n");
|
|
121064
|
+
await runAccountDelink({
|
|
121065
|
+
token: opts.token,
|
|
121066
|
+
id: opts.id,
|
|
121067
|
+
ids: opts.ids,
|
|
121068
|
+
verbose: opts.verbose
|
|
121069
|
+
});
|
|
121070
|
+
console.log("\u6B65\u9AA4 2/2\uFF1A\u53D1\u8D77 OAuth \u6388\u6743\u2026\n");
|
|
121071
|
+
await runAccountAuth({
|
|
121072
|
+
token: opts.token,
|
|
121073
|
+
media: opts.media,
|
|
121074
|
+
verbose: opts.verbose
|
|
121075
|
+
});
|
|
121076
|
+
}
|
|
121003
121077
|
|
|
121004
121078
|
// src/commands/account-manage/google-mcc.ts
|
|
121005
121079
|
init_auth();
|
|
@@ -121959,12 +122033,30 @@ function register23(program2) {
|
|
|
121959
122033
|
});
|
|
121960
122034
|
}
|
|
121961
122035
|
);
|
|
121962
|
-
accountCmd.command("auth").description(
|
|
122036
|
+
accountCmd.command("auth").description(
|
|
122037
|
+
"\u6DFB\u52A0\u6388\u6743\uFF1A\u9996\u6B21\u7ED1\u5B9A\u5A92\u4F53\u8D26\u6237 OAuth\uFF08\u7F51\u9875 manageAccounts\u300C\u6DFB\u52A0\u6388\u6743\u300D\uFF09\uFF1BOAuth \u5931\u6548\u8BF7\u7528 reauth"
|
|
122038
|
+
).requiredOption(
|
|
121963
122039
|
"-m, --media <type>",
|
|
121964
122040
|
"\u5A92\u4F53\u7C7B\u578B\uFF1AGoogle | TikTok | Meta | Yandex | BingV2 | Kwai"
|
|
121965
122041
|
).option("-t, --token <token>", "Auth Token").option("--verbose", "\u8BE6\u7EC6\u9519\u8BEF\u4FE1\u606F", false).action(async (opts) => {
|
|
121966
122042
|
await runAccountAuth({ token: opts.token, media: opts.media, verbose: opts.verbose });
|
|
121967
122043
|
});
|
|
122044
|
+
accountCmd.command("reauth").description(
|
|
122045
|
+
"\u91CD\u65B0\u6388\u6743\uFF1A\u5148\u89E3\u7ED1\u518D OAuth\uFF08\u7F51\u9875 manageAccounts\u300C\u91CD\u65B0\u6388\u6743\u300D\uFF1BinvalidOAuthToken \u5931\u6548\u65F6\u5FC5\u8D70\u6B64\u547D\u4EE4\uFF09"
|
|
122046
|
+
).requiredOption(
|
|
122047
|
+
"-m, --media <type>",
|
|
122048
|
+
"\u5A92\u4F53\u7C7B\u578B\uFF1AGoogle | TikTok | Meta | Yandex | BingV2 | Kwai"
|
|
122049
|
+
).option("--id <entityId>", "\u5355\u4E2A\u8D26\u6237 entityId\uFF08\u6765\u81EA list-accounts \u7684 ma.entityId\uFF09").option("--ids <entityIds>", "\u6279\u91CF entityId\uFF0C\u9017\u53F7\u5206\u9694\uFF08\u4E0E --id \u4E8C\u9009\u4E00\uFF0C\u53EF\u540C\u65F6\u4F20\uFF09").option("-t, --token <token>", "Auth Token").option("--verbose", "\u8BE6\u7EC6\u9519\u8BEF\u4FE1\u606F", false).action(
|
|
122050
|
+
async (opts) => {
|
|
122051
|
+
await runAccountReauth({
|
|
122052
|
+
token: opts.token,
|
|
122053
|
+
media: opts.media,
|
|
122054
|
+
id: opts.id,
|
|
122055
|
+
ids: opts.ids ? opts.ids.split(",").map((s) => s.trim()).filter(Boolean) : void 0,
|
|
122056
|
+
verbose: opts.verbose
|
|
122057
|
+
});
|
|
122058
|
+
}
|
|
122059
|
+
);
|
|
121968
122060
|
accountCmd.command("mcc-bind").description("Google\uFF1A\u5C06\u5B50\u8D26\u6237\u7ED1\u5B9A\u5230\u7ECF\u7406\u8D26\u6237\uFF08MCC\uFF09\uFF0C\u9700\u5DF2\u914D\u7F6E googleApiUrl").requiredOption(
|
|
121969
122061
|
"--customers <ids>",
|
|
121970
122062
|
"\u5B50\u8D26\u6237 mediaCustomerId\uFF0C\u591A\u4E2A\u9017\u53F7\u5206\u9694\uFF08\u6765\u81EA list-accounts \u7684 ma.mediaCustomerId\uFF09"
|
package/dist/skill/_meta.json
CHANGED
|
@@ -307,9 +307,11 @@ siluzan-tso account me --check-phone 15130150466 --json-out ./snap-me
|
|
|
307
307
|
|
|
308
308
|
---
|
|
309
309
|
|
|
310
|
-
### auth — 添加媒体平台 OAuth
|
|
310
|
+
### auth — 添加媒体平台 OAuth 授权(首次绑定)
|
|
311
311
|
|
|
312
|
-
在浏览器中打开对应媒体的 OAuth
|
|
312
|
+
在浏览器中打开对应媒体的 OAuth 授权页面,授权后账户自动绑定到丝路赞。对应网页 **「添加授权」**。
|
|
313
|
+
|
|
314
|
+
> **OAuth 已失效**(`invalidOAuthToken=true`)时**不要**用本命令,须走下方 **`reauth`**(重新授权必须先解绑)。
|
|
313
315
|
|
|
314
316
|
```bash
|
|
315
317
|
siluzan-tso account auth -m <媒体类型>
|
|
@@ -322,13 +324,13 @@ siluzan-tso account auth -m <媒体类型>
|
|
|
322
324
|
**示例:**
|
|
323
325
|
|
|
324
326
|
```bash
|
|
325
|
-
#
|
|
327
|
+
# 首次授权 Google Ads 账户
|
|
326
328
|
siluzan-tso account auth -m Google
|
|
327
329
|
|
|
328
|
-
#
|
|
330
|
+
# 首次授权 TikTok Ads 账户
|
|
329
331
|
siluzan-tso account auth -m TikTok
|
|
330
332
|
|
|
331
|
-
#
|
|
333
|
+
# 首次授权 Meta(Facebook)Ads 账户
|
|
332
334
|
siluzan-tso account auth -m Meta
|
|
333
335
|
```
|
|
334
336
|
|
|
@@ -336,6 +338,38 @@ siluzan-tso account auth -m Meta
|
|
|
336
338
|
|
|
337
339
|
---
|
|
338
340
|
|
|
341
|
+
### reauth — 重新授权(先解绑再 OAuth)
|
|
342
|
+
|
|
343
|
+
OAuth 失效时恢复授权。对齐 TSO 网页 **「重新授权」**:程序会先 **delink** 断开关联,再跳转媒体 OAuth。**禁止**对失效账户跳过解绑直接用 `account auth`。
|
|
344
|
+
|
|
345
|
+
```bash
|
|
346
|
+
siluzan-tso account reauth -m <媒体类型> --id <entityId>
|
|
347
|
+
siluzan-tso account reauth -m Google --ids <id1,id2>
|
|
348
|
+
```
|
|
349
|
+
|
|
350
|
+
| 选项 | 说明 |
|
|
351
|
+
| -------------------- | ------------------------------------------------------------------------ |
|
|
352
|
+
| `-m, --media <type>` | 媒体类型(必填) |
|
|
353
|
+
| `--id <entityId>` | 单个账户 `entityId`(来自 `list-accounts` 的 `ma.entityId`) |
|
|
354
|
+
| `--ids <id1,id2>` | 批量 `entityId`,逗号分隔(与 `--id` 二选一) |
|
|
355
|
+
|
|
356
|
+
**示例:**
|
|
357
|
+
|
|
358
|
+
```bash
|
|
359
|
+
# 1. 查失效账户的 entityId
|
|
360
|
+
siluzan-tso list-accounts -m Google --json-out ./snap
|
|
361
|
+
|
|
362
|
+
# 2. 重新授权(内置 delink → OAuth)
|
|
363
|
+
siluzan-tso account reauth -m Google --id abc123def456
|
|
364
|
+
|
|
365
|
+
# 3. 验证
|
|
366
|
+
siluzan-tso list-accounts -m Google
|
|
367
|
+
```
|
|
368
|
+
|
|
369
|
+
> 手动两步等价于 `reauth`:`account delink --id …` → `account auth -m …`(须用户确认解绑风险)。
|
|
370
|
+
|
|
371
|
+
---
|
|
372
|
+
|
|
339
373
|
### delink — 解除授权 / 断开账户关联
|
|
340
374
|
|
|
341
375
|
从当前丝路赞账号下移除媒体账户绑定。
|
|
@@ -219,7 +219,7 @@
|
|
|
219
219
|
## 十一、常见 HTTP 状态码
|
|
220
220
|
|
|
221
221
|
- **400**:参数错误,查看对应 reference 或 `-h`
|
|
222
|
-
- **401
|
|
222
|
+
- **401**:媒体 OAuth 失效 → `account reauth -m <媒体> --id <entityId>`(须先 delink,见 W9);**丝路赞登录凭据失效** → `send-login-code` + `login --phone --code`,见 `references/core/setup.md`
|
|
223
223
|
- **500**:服务可能正在部署/升级,建议反馈 Siluzan 相关人员
|
|
224
224
|
|
|
225
225
|
---
|
|
@@ -152,7 +152,8 @@
|
|
|
152
152
|
- **步骤(按场景)**:
|
|
153
153
|
- **分享**:`list-accounts --json-out` 取 `entityId` → `account share --id <entityId> --phone <手机号>`;查 `account share-detail --customer-id <mediaCustomerId>`;取消 `account unshare --id <entityId> --account-id <userId>`。
|
|
154
154
|
- **解绑**:`account delink --id <entityId>` / `--ids id1,id2`。
|
|
155
|
-
- **OAuth 重授权**:`invalidOAuthToken=true` → `account
|
|
155
|
+
- **OAuth 重授权**:`invalidOAuthToken=true` → `list-accounts --json-out` 取 `ma.entityId` → **`account reauth -m <媒体> --id <entityId>`**(内置先 delink 再 OAuth,对齐网页「重新授权」)→ `list-accounts` 验证。**禁止**对失效账户直接用 `account auth`(首次「添加授权」专用)。
|
|
156
|
+
- **首次 OAuth 添加授权**:`account auth -m <媒体>`(无需先 delink)。
|
|
156
157
|
- **MCC**:`account mcc-bind --customers <mediaCustomerId,...> --mcc <MCC客户ID>` / `mcc-unbind`(走 `googleApiUrl`,先 `config show`)。
|
|
157
158
|
- **BC(TikTok)**:`account bc-bind --customers <id> --bc-ids <id>` / `bc-unbind --bc-id <id>`(解绑一次一个)。
|
|
158
159
|
- **BM(Meta)**:`account bm-bind --account-id <mediaCustomerId> --bm-id <bmId>`。
|
|
@@ -18,6 +18,7 @@
|
|
|
18
18
|
## 1. 执行摘要(总览)
|
|
19
19
|
|
|
20
20
|
- **CLI**:`siluzan-tso report bing-overview -a <mediaCustomerId> [--start … --end …] --json-out <dir>`
|
|
21
|
+
- **余额**:若 `OverviewSectionData` 误返 `remainingAccountBudget: 0`,CLI 会自动用 `GetMediaAccountInfo` 实时余额回填(与 Web 账户列表一致);**仍建议**单查余额用 `balance -m BingV2`。
|
|
21
22
|
|
|
22
23
|
## 2. 设备与地域
|
|
23
24
|
|
|
@@ -18,6 +18,7 @@
|
|
|
18
18
|
## 1. 执行摘要(总览)
|
|
19
19
|
|
|
20
20
|
- **CLI**:`siluzan-tso report bing-overview -a <mediaCustomerId> [--start … --end …] --json-out <dir>`
|
|
21
|
+
- **余额**:若 `OverviewSectionData` 误返 `remainingAccountBudget: 0`,CLI 会自动用 `GetMediaAccountInfo` 实时余额回填(与 Web 账户列表一致);**仍建议**单查余额用 `balance -m BingV2`。
|
|
21
22
|
|
|
22
23
|
## 2. 设备与地域
|
|
23
24
|
|
|
@@ -9,7 +9,7 @@ $ErrorActionPreference = 'Stop'
|
|
|
9
9
|
# -- Package info (injected at build time) ------------------------------------
|
|
10
10
|
$PKG_NAME = 'siluzan-tso-cli'
|
|
11
11
|
# PKG_VERSION 锁定到与本脚本同批构建产物一致的版本,避免与 dist/skill 错位
|
|
12
|
-
$PKG_VERSION = '1.1.33-beta.
|
|
12
|
+
$PKG_VERSION = '1.1.33-beta.2'
|
|
13
13
|
$CLI_BIN = 'siluzan-tso'
|
|
14
14
|
$SKILL_LABEL = 'Siluzan TSO'
|
|
15
15
|
$INSTALL_CMD = 'npm install -g siluzan-tso-cli@beta'
|
|
@@ -9,7 +9,7 @@ set -euo pipefail
|
|
|
9
9
|
# -- Package info (injected at build time) ------------------------------------
|
|
10
10
|
readonly PKG_NAME="siluzan-tso-cli"
|
|
11
11
|
# PKG_VERSION 锁定到与本脚本同批构建产物一致的版本,避免与 dist/skill 错位
|
|
12
|
-
readonly PKG_VERSION="1.1.33-beta.
|
|
12
|
+
readonly PKG_VERSION="1.1.33-beta.2"
|
|
13
13
|
readonly CLI_BIN="siluzan-tso"
|
|
14
14
|
readonly SKILL_LABEL="Siluzan TSO"
|
|
15
15
|
readonly INSTALL_CMD="npm install -g siluzan-tso-cli@beta"
|